在netfilter模块中重新注入已修改的数据包

时间:2015-05-09 10:28:34

标签: c++ linux udp iptables netfilter

我使用netfiler_queueNFQUEUE创建iptables模块,处理所有传出的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;
}

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

1 个答案:

答案 0 :(得分:3)

两件事。第一:

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

应该是:

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

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

其次,您刚刚修改了数据包。此时IP堆栈不再帮助您,因此您需要重新计算该数据包的UDP校验和,将其归零,以便另一端获胜&# 39;甚至检查它。

UDP校验和将以数据包的0x1A0x1B个字节为单位,因此将其清零:

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

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