C 检测内核模块netfilter挂钩中的数据包碎片

C 检测内核模块netfilter挂钩中的数据包碎片,c,network-programming,linux-kernel,C,Network Programming,Linux Kernel,我无法检测数据包是否碎片化以及数据包偏移量 我转储头数据 printk("frt_offset=%d ", ((ip_header->frag_off)));//print all, not 13 bytes of it printk("fr_cf=%d ", (ntohs(ip_header->frag_off) & IP_CE) > 0); printk("frt_df=%d ", (ntohs(ip_header->frag_off) & IP

我无法检测数据包是否碎片化以及数据包偏移量

我转储头数据

 printk("frt_offset=%d ", ((ip_header->frag_off)));//print all, not 13 bytes of it
 printk("fr_cf=%d ", (ntohs(ip_header->frag_off) & IP_CE) > 0);
 printk("frt_df=%d ", (ntohs(ip_header->frag_off) & IP_DF) > 0);
 printk("fr_mf=%d ", (ntohs(ip_header->frag_off) & IP_MF) > 0);
但当我下载启用模块的文件时,我得到了以下输出:

[40432.831134] packet size=1514 timestamp=-790555865  frt_id=60370 frt_offset=64 fr_xf=0    frt_df=1 fr_mf=0
[40432.831318] packet size=1514 timestamp=-790371858  frt_id=60626 frt_offset=64 fr_xf=0 frt_df=1 fr_mf=0 
[40432.831496] packet size=1514 timestamp=-790193971 frt_id=60882 frt_offset=64 fr_xf=0   frt_df=1 fr_mf=0 
[40432.831905] packet size=1514 timestamp=-789785167 frt_id=61138 frt_offset=64 fr_xf=0 frt_df=1 fr_mf=0 
[40432.832098] packet size=1514 timestamp=-789592131 frt_id=61394 frt_offset=64 fr_xf=0 frt_df=1 fr_mf=0 
[40432.832504] packet size=1514 timestamp=-789186978 frt_id=61650 frt_offset=64 fr_xf=0 frt_df=1 fr_mf=0 
[40436.131049] packet size=45 timestamp=-1785619342 frt_id=4464 frt_offset=0 fr_xf=0 frt_df=0 fr_mf=0 
但据我所知,对于碎片数据包,我必须获得相同的id,不同的偏移量,标志mf=1。我们这里还有别的东西。这里的最后一个数据包可能是来自另一个会话的数据包


我迷路了…

据我所知,在使用netfilter挂钩时,内核中的
ip\u local\u deliver
函数将在调用为
local\u注册的挂钩之前对ip数据包进行碎片整理。本地生成的数据包在运行
POST\u路由
的挂钩后调用的
ip\u finished\u输出
函数中被分割

总之,查看内核代码告诉我,您只能在
PRE_ROUTING
FORWARD
(如果不是本地生成的)和
POST_ROUTING
(如果不是本地生成的)钩子中获取片段


希望有帮助。

这是一个像拼图一样好的游戏。你只需输入一组数据包的随机输出。“我们”只能猜测,除非你输入更多信息或PCAP。有很多场景, 您需要检查以下内容

1.如果偏移量为0

如果MF=1,这可能是第一个数据包 或 MF=0时,可能不容易碎片化

2.如果偏移量是其他值,则可以确定碎片

根据您提供的输出(某些碎片数据包的最后一个数据包是否将偏移量乘以8) 首先是你的输出 好的,在那之前 1.您是否尝试在本地\u-IN、本地\u-OUT或预\u路由上应用钩子 2.我假设的MTU设置是多少 不管怎样,输出中显示的数据包大小是1514(我想是有线数据包的大小)

如您所见,DF(不分段位)已设置,MF(更多分段)为零(可能是最后一个数据包) 试着这样做

ping-s 2000 www.google.com并检查输出关闭所有其他打开的连接(浏览器下载等)


好的结论除了最后一个我想是:D:D干杯

你确定这些数据包真的是碎片吗?哦,现在我真的不确定这一点。感谢您在哪些钩子点检查片段(本地输入、后路由等)?