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

时间:2011-11-16 15:45:13

标签: 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_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。我们在这里有另一件事。此处的最后一个数据包可能是来自另一个会话的数据包。

我迷路了...

2 个答案:

答案 0 :(得分:0)

据我所知,在使用netfilter挂钩时,内核中的ip_local_deliver函数会在调用为LOCAL_IN注册的挂钩之前对ip数据包进行碎片整理。在ip_finished_output的挂钩运行后调用的POST_ROUTING函数中,本地生成的数据包被分段。

总而言之,查看内核代码告诉我,您只能抓取PRE_ROUTINGFORWARD(如果不是本地生成的)和POST_ROUTING(如果不是本地生成的)挂钩中的片段

希望它有所帮助。

答案 1 :(得分:0)

这是一个很好的拼图..你只是随机输出一堆数据包。除非你投入更多信息或PCAP,否则“我们”只能猜测。有很多场景, 您需要检查以下

1.如果偏移0

  

这可能是我支离破碎的,如果MF = 1,它是第一个数据包   要么   可能不容易碎片MF = 0

2.如果偏移是其他东西,那么你可以确定碎片

根据你提出的输出(是一些碎片包的最后一个包,将偏移乘以8) 首先是你的输出 好的,那之前 1.您是否尝试在LOCAL_IN或LOCAL_OUT或PRE_ROUTING上应用挂钩 2.我认为MTU设置为1500 好吧无论如何,显示的输出中的数据包大小是1514(我想tats是线路上数据包的大小)

如您所见,DF(不分段位)已设置且MF(更多片段)为零(可能是LAST数据包) 尝试这样做

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

结论那些是碎片包除了最后一个我认为:D:D欢呼