【问题标题】:Reinjecting modified packets in netfilter module在 netfilter 模块中重新注入修改过的数据包
【发布时间】:2015-05-12 04:35:38
【问题描述】:

我使用netfiler_queueiptables 创建了一个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;
}

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

【问题讨论】:

  • 示例代码纯属示例,视为伪代码。

标签: c++ linux udp iptables netfilter


【解决方案1】:

两件事。第一:

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;

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

【讨论】:

  • 在这种情况下如何重新计算校验和?
  • 更具体地说,如何使用通用校验和计算函数并将其插入到这两个字节中?
  • 你不能使用通用的,你必须使用UDP校验和功能。它在 RFC768,tools.ietf.org/html/rfc768 和 Wikipedia,en.wikipedia.org/wiki/… 中有描述
  • 如果数据包没有这样做,那么首先计算校验和有什么意义?
  • 最初包含它是为了确保数据到达时不会从中间链接损坏。但是现在基本上每个链路层都执行自己的校验和,即使通过 Internet 发送数据包也极不可能出现损坏,更不用说本地链路了。如果您只是为了本地流量和/或教学目的而进行此操作,则无需为校验和而烦恼。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 2018-03-12
  • 1970-01-01
  • 2020-06-26
相关资源
最近更新 更多