c++ - 在 netfilter 模块中重新注入(inject)修改后的数据包

标签 c++ linux udp iptables netfilter

我用过netfiler_queueiptables 创建一个 NFQUEUE 模块来处理所有传出的 UDP 数据包。

我想修改所有匹配特定模式的 UDP 数据包,然后将它们重新注入(inject)网络。

下面是一些示例代码:

...

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;
}

修改后的数据包不会重新注入(inject)流中。我将如何注入(inject)数据包的修改版本?

最佳答案

两件事。第一:

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

应该是:

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

这告诉它你想发送一个修改过的数据包。 (你可能需要一些类型转换)

其次,您刚刚修改了数据包。 IP 堆栈此时不再帮助您,因此您需要重新计算该数据包的 UDP 校验和,将其清零,这样另一端甚至不会检查它.

UDP 校验和将存在于数据包的字节 0x1A0x1B 中,因此这会将它们清零:

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

然后你的数据包就会通过。

关于c++ - 在 netfilter 模块中重新注入(inject)修改后的数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30138818/

相关文章:

python - 在 Windows 8 中编译 mod_wsgi 不适用于 django

c++ - 使用 Hook Engine 时的 ACCESS_VIOLATION

linux - 如何使用 rm -rf 从目录中删除文件?

linux - linux如何重命名当前目录下的所有文件

tcp - 哪些 header 字段将数据包描述为唯一的?

c++ - 不能用通告包含转发声明

c++ - 为什么 const 左值引用可以引用可变右值引用?

linux - 在 shell 脚本中设置环境变量以在远程服务器上运行

c - 为什么 UDP 套接字不接收来自 nc -u 主机端口的 udp 流量?

Java UDP服务器-客户端通信-发送分片(分片发送失败)