C++ 在netfilter模块中重新注入修改后的数据包

C++ 在netfilter模块中重新注入修改后的数据包,c++,linux,udp,iptables,netfilter,C++,Linux,Udp,Iptables,Netfilter,我曾经为iptables创建一个NFQUEUE模块,用于处理所有传出的UDP数据包 我想修改所有符合特定模式的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 ((heade

我曾经为
iptables
创建一个
NFQUEUE
模块,用于处理所有传出的
UDP
数据包

我想修改所有符合特定模式的
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校验和将以数据包的字节
0x1A
0x1B
为单位,因此这将使它们归零:

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

然后您的数据包将通过。

在这种情况下,我将如何重新计算校验和?更具体地说,我如何使用通用校验和计算函数并将其插入到这两个“是”中?您不能使用通用校验和,您必须使用UDP校验和函数。RFC768和Wikipedia中都有描述,如果数据包没有经过校验和,那么首先计算校验和又有什么意义呢?它最初是为了确保数据到达时中间链路不会损坏。但如今,基本上每个链路层都执行自己的校验和运算,即使通过互联网发送数据包,也不太可能出现损坏,更不用说本地链路了。如果您只是为了本地流量和/或教学目的而进行此项工作,那么使用校验和并没有多大意义。示例代码纯粹是一个示例,请将其视为psuedo代码。