重新注射NetFilter模块中的修改后数据包

Reinjecting modified packets in netfilter module

本文关键字:修改 数据包 新注射 NetFilter 模块      更新时间:2023-10-16

我使用netfiler_queue为iptables创建一个处理所有传出UDP数据包的NFQUEUE模块。

我想修改所有匹配特定模式的UDP数据包,并将其重新注射到网络中。

这是一些示例代码:

...
static int Callback( nfq_q_handle *myQueue, struct nfgenmsg *msg, nfq_data *pkt, void *cbData) {
  uint32_t id = 0;
  nfqnl_msg_packet_hdr *header;
  if ((header = nfq_get_msg_packet_hdr(pkt))) {
    id = ntohl(header->packet_id);
  }
  // Get the packet payload
  unsigned char *pktData;
  int len = nfq_get_payload(pkt, &pktData);
  // The following is an example. 
  // In reality, it involves more parsing of the packet payload.
  if (len && pktData[40] == 'X') {
    // Modify byte 40
    pktData[40] = 'Y';
  }
  // Pass through the (modified) packet.
  return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL);
}
...
int main(){
  ...
  struct nfq_handle nfqHandle;
  nfq_create_queue(nfqHandle,  0, &Callback, NULL)
  ...
  return 0;
}

修改后的数据包不会被重新注射到流中。我将如何注入数据包的修改版本?

两件事。第一:

return nfq_set_verdict(myQueue, id, NF_ACCEPT, 0, NULL);

应该是:

return nfq_set_verdict(myQueue, id, NF_ACCEPT, len, pktData);

告诉它您要发送一个修改的数据包。(您可能需要某种类型的铸造)

第二,您只是修改了数据包。此时IP堆栈没有其他帮助,因此您需要重新计算该数据包的UDP校验和零,以便其他端都不会检查它。

UDP校验和将生活在您的数据包的Bytes 0x1A0x1B中,因此将它们归零:

pktData[0x1a] = 0;
pktData[0x1b] = 0;

然后您的数据包将通过。