我有一个数据包内有一个数据包,也就是隧道。因此,它本质上具有以下形式:[IP HEADER 1][IP HEADER 2][PAYLOAD]
读取第一个标头(由库完成)后,我将获得数据包:[IP HEADER 2][PAYLOAD]
在 iptables 的 INPUT 链中。我想将数据包重新注入 iptables 的开头,即 PREROUTING 链中。最终目标是将数据包转发到远程主机(这就是我希望数据包位于 PREROUTING 链中的原因)。我读过一些关于 libipq 的内容,但我不确定这是否是最好的方法。任何大胆的建议也会有所帮助。
我已经在“stackoverflow”中发布了这个问题,但由于没有回复,所以我认为它更适合“serverfault”。
答案1
我同意 MrShunz 的回答。使用libnetfilter_queue。要使用它,您需要一个包含 nfnetlink_queue 支持的 Linux 内核版本 2.6.14 或更高版本。需要设置两个部分:
- /netfilter规则
iptables
用于将数据包发送到用户空间,以及 - 您的用户空间程序,它将根据需要处理数据包,然后将其返回给 netfilter。
该iptables
规则可能看起来像这样:
IN_INTERFACE=eth0
SOURCE_NETWORK=192.168.66.0/24
QUEUE_NUM=1
iptables -t raw -A PREROUTING -i $IN_INTERFACE -s $SOURCE_NETWORK -j NFQUEUE --queue-num $QUEUE_NUM
这会将通过特定接口从特定网络传入的所有数据包发送到正在监听队列号 1 的用户空间进程。
你的程序很可能必须用 C 或 C++ 编写,将使用libnetfilter_queue API抱歉,我不会在这里写任何代码(我链接到的 API 文档中有示例代码),但基本思想是您的程序将:
- 读取发送到队列的每个数据包,
- 对数据包进行所需的修改,
- 最后,为 netfilter 指定一个“判定”,表示是接受还是丢弃该数据包。假设您大多数情况下都会选择接受。
我个人没有使用过这个 API,但我读到的文档是,接受数据包实际上意味着将其重新注入 netfilter(已修改),以继续遍历iptables
规则集。在这一点上我可能错了,所以在开始这一开发过程之前,您可能需要进一步调查。
答案2
如果我没记错的话,重新注入(但是注入到链的开头!),NF_REPEAT
作为判决。