libpcap无法捕获IP分片。

10
我想捕获发送到本地端口的UDP数据包,过滤表达式类似于udp port 20000。我注意到如果UDP数据包在IP层被分片,libpcap只能捕获第一个IP分片。我猜测原因是第二个IP分片没有UDP头(我认为TCP也是一样),所以libpcap不能使用过滤表达式udp port 20000来捕获它们。
有没有解决这个问题的方法?或者有其他的库可以捕获发送到特定本地端口的数据包吗?
谢谢!

1
如果一个UDP数据包被分段并且这些片段没有标识它们的源/目的地,那么它们如何被路由到正确的主机和应用程序呢? - Iron Savior
第二个片段具有IP头但没有UDP头。 IP / TCP堆栈将在将整个UDP数据包交付给应用程序之前组装第一个和第二个IP片段。但是我觉得libpcap无法识别第二个IP片段。 - misteryes
我对 TCP/IP 的底层机制并不是很熟悉,无法确定 UDP 分片在数据包级别上的实际工作方式。 我一直认为数据报不会被分片。 您能否在 Wireshark 中收集显示 UDP 数据包分段的捕获信息? - Iron Savior
看看这个,似乎是一个有关重构片段的Java演示。 - Iron Savior
@IronSavior IP堆栈根据IP头中的信息重新组装片段。重新组装后,您将得到一个带有UDP头的数据包,该头将标识本地应用程序/套接字。libpcap在重新组装之前接收帧。因此,在使用包括UDP头中内容的过滤器时,只能捕获第1个片段,而无法捕获其他内容。 - nos
显示剩余4条评论
1个回答

11
我猜原因是第二个IP片段没有UDP头(我认为TCP也一样),所以libpcap不能使用过滤表达式udp port 20000捕获它们。 是的,没错。 你可以尝试udp port 20000 或者 (ip[6:2] & 0x1fff) != 0,这将捕获端口20000的数据包和第一个片段外的IP片段。这不是理想的情况,但在使用libpcap过滤器时,这是你可以做的全部。因为它使用的过滤机制(是操作系统内核的一部分)在数据包之间不维护任何历史记录,因此无法知道具有相同IP ID的数据包恰好是与另一个具有相同IP ID、片段偏移为0和带有端口20000的UDP头的数据包属于同一片段。
(还要注意,至少一些Linux版本会以相反的顺序传输IP数据报的片段 - 为了让接收方先看到最后一个片段,从而更能正确地估计重新组装的数据包的大小。这将使使用检查TCP或UDP头中字段的过滤器捕获所有IP数据包片段变得更加困难。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接