我使用libnetfilter_queue在C捕获数据包。 我设置的iptable的规则来排队,后来由用户空间实现这样的处理传入的数据包: iptables -A INPUT -j NFQUEUE --queue-num 0
。 我用nfqnl_test例如作为一个框架来实现捕获。 一切正常。 不过,我注意到,这是不可能去检查IP碎片的级别队列。 也就是说,如果一个数据包的片段来它被放入队列之前首先重新组装。 但我想用碎片的工作。 那么,有没有办法强制执行这种行为? 我想有一个队列在那里我可以看到原始的传入数据包(包括零散和不分段),这样我就可以相应地采取行动。
我读的重组确实之前发生。 在另一方面,使用iptables有-f
标志可用,因此应该有一个“破碎粒度”这是我所期待的。 我还试图调节iptable的规则(例如iptables -t raw -D PREROUTING -i eth0 -j NFQUEUE --queue-num 0
),但结果仍是相同的。 我只能观察已经重组后的包,我肯定知道,到达片段。
任何帮助非常感谢。
所以,我已经找到了解决问题的方法,我在这里分享它的情况下,一些人有兴趣。 信贷从谁提出的可能的解决方法的netfilter邮件列表去阿德尔。 基本上,解决方案是使用nftables并设置一个链与优先级比一个用于碎片整理低。 我已经测试此设置与C语言代码,它似乎工作得很好(我没有发现任何副作用)。 但是,我不得不提到我用它只是观察IP碎片,我没有随意更改。
下面有两个功能进行设定nftables,然后删除它们。
void set_nftable() {
int status = 0;
// Create a nftable
status = system("nft add table ip filter");
// Add a chain to the nftable called "predefrag" which has lower priority than the defragmentation -450 < -400
status = system("nft add chain ip filter predefrag { type filter hook prerouting priority -- -450 \\; }");
// Set the nftable rule (queue packets to be accessed by a user-space application)
status = system("nft add filter predefrag meta iif eth0 counter queue num 0 bypass");
}
void remove_nftable() {
int status = 0;
// Flush the rules that are stored in the chains that belong to the nftable
status = system("nft flush table ip filter");
// Delete the chain from the nftable
status = system("nft delete chain ip filter predefrag");
// Delete the nftable
status = system("nft delete table ip filter");
}
随着这些功能的nfqnl_test代码可以被用来捕捉IP片段。 下面有设立nftables和低估他们的工作有用的链接(在功能评论是不言自明,一旦获得与nftables手动熟悉)。
http://wiki.nftables.org/wiki-nftables/index.php/Building_and_installing_nftables_from_sources
http://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables
http://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
http://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management
http://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace
别的之前,请确保您的网络卡是不是一个做重组。
现代网卡等进行了各种卸载技术LRO , UFO ,别人也可以重新组装IP层分片。 我建议使用ethtool -k
检查哪些卸载是活性相关的接口上,然后使用由一个关断它们一个ethtool -K
。