libnet 创建带有无效校验和的 UDP 数据包

发布于 2024-08-15 15:27:36 字数 1245 浏览 5 评论 0原文

我正在使用 pylibnet 构建和发送 UDP 数据包。我用这种方式构建的 UDP 数据包似乎都有无效的校验和。示例:

# python
Python 2.4.3 (#1, Sep  3 2009, 15:37:12)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import libnet
>>> from libnet.constants import *
>>> 
>>> net = libnet.context(RAW4, 'venet0:0')
>>> ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
>>> data = 'This is my payload.'
>>> udptag = net.build_udp(sp=54321, dp=54321, payload=data)
>>> packetlen = IPV4_H + UDP_H + len(data)
>>> iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)
>>> 
>>> net.write() 

在发送主机上捕获上述数据包会显示无效的校验和:

# tcpdump -i venet0:0 -n -v -v port 54321
tcpdump: WARNING: arptype 65535 not supported by libpcap - falling back to cooked socket
tcpdump: listening on venet0:0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
08:16:10.303719 IP (tos 0x0, ttl  64, id 1, offset 0, flags [none], proto: UDP (17), length: 47) 192.168.55.10.54321 > 69.59.196.211.54321: [bad udp cksum 50c3!] UDP, length 0

我在这里做错了什么吗?

I'm using pylibnet to construct and send UDP packets. The UDP packets I construct in this way all seem to have invalid checksums. Example:

# python
Python 2.4.3 (#1, Sep  3 2009, 15:37:12)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import libnet
>>> from libnet.constants import *
>>> 
>>> net = libnet.context(RAW4, 'venet0:0')
>>> ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
>>> data = 'This is my payload.'
>>> udptag = net.build_udp(sp=54321, dp=54321, payload=data)
>>> packetlen = IPV4_H + UDP_H + len(data)
>>> iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)
>>> 
>>> net.write() 

Capturing the above packet on the sending host reveals an invalid checksum:

# tcpdump -i venet0:0 -n -v -v port 54321
tcpdump: WARNING: arptype 65535 not supported by libpcap - falling back to cooked socket
tcpdump: listening on venet0:0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
08:16:10.303719 IP (tos 0x0, ttl  64, id 1, offset 0, flags [none], proto: UDP (17), length: 47) 192.168.55.10.54321 > 69.59.196.211.54321: [bad udp cksum 50c3!] UDP, length 0

Am I doing something wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

赠佳期 2024-08-22 15:27:36

这与 tcpdump 错误或校验和卸载无关。 Libnet 也在用户模式下计算校验和(仅供参考)。该问题与您没有指定 UDP 标头的长度有关。这不是在 pylibnet 或 libnet 中自动计算的,因此您必须暂时指定它。以下是您的代码的更正版本。我将向 pylibnet 应用补丁以自动检测 rc6 中的标头长度。请继续关注 http://sourceforge.net/projects/pylibnet 获取更新。我将推出解决此问题的新版本。顺便说一句,如果您有错误或功能请求,请随时通过 sourceforge 的 pylibnet 页面与我联系。我喜欢听到使用我的软件的开发人员的来信:)


import libnet
from libnet.constants import *

net = libnet.context(RAW4, 'venet0:0')
ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
data = 'This is my payload.'
udptag = net.build_udp(len=UDP_H+len(data), sp=54321, dp=54321, payload=data)
packetlen = IPV4_H + UDP_H + len(data)
iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)

net.write()

It's nothing to do with tcpdump bugs or checksum offloading. Libnet calculates the checksum in user mode as well (FYI). The problem has to do with the fact that you did not specify a length for the UDP header. This is not automagically calculated in pylibnet or libnet so you have to specify it for the time being. Below is the corrected version of your code. I will apply a patch to pylibnet to automagically detect the header length in rc6. Stay tuned to http://sourceforge.net/projects/pylibnet for updates. I will be pushing a new release fixing this issue. By the way, please feel free to contact me via sourceforge's pylibnet page if you have bug or feature requests. I love to hear from developers using my software :)


import libnet
from libnet.constants import *

net = libnet.context(RAW4, 'venet0:0')
ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
data = 'This is my payload.'
udptag = net.build_udp(len=UDP_H+len(data), sp=54321, dp=54321, payload=data)
packetlen = IPV4_H + UDP_H + len(data)
iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)

net.write()
单挑你×的.吻 2024-08-22 15:27:36

计算校验和的工作通常不在用户空间库中执行,而是在设备驱动程序或硬件中执行。我相信您看到的是“校验和卸载”的结果,其中物理设备计算传出数据包的校验和,从而节省主机上的 CPU 周期。许多(如果不是全部)现代以太网适配器都这样做,并且驱动程序不计算校验和。由于 tcpdump 正在捕获驱动程序中的数据包,因此在它们到达物理设备之前,它只会在校验和字段中获取垃圾(可能是缓冲区中剩余的内容)并抱怨。

在 2005-2008 年期间,针对 Wireshark 报告了几个涉及此问题的“错误”,并且 Wireshark(只是 tcpdump 或其 Windoze 等效项上的 GUI 包装器)现在可以选择禁用卸载情况下的校验和验证。

http://wiki.wireshark.org/TCP_Checksum_Verification

无论如何,我不希望 pylibnet (或libnet) 负责校验和。

另请参阅http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums。 html#id4744523

The job of calculating checksums is usually not performed in the user-space library but at the device driver or in hardware. I believe you are seeing the result of "checksum offloading", where the physical device calculates the checksums on outgoing packets, saving CPU cycles on the host. Many (if not all) modern Ethernet adapters do this, and the drivers do not calculate the checksum. Since tcpdump is capturing the packets in the driver, before they get to the physical device, it just gets garbage in the checksum field (probably what's left over in the buffer) and complains.

There were several "bugs" reported against Wireshark in the 2005-2008 timeframe covering this, and Wireshark (which is just a GUI wrapper on tcpdump or its Windoze equivalent) now has an option to disable checksum validation for the offload case.

http://wiki.wireshark.org/TCP_Checksum_Verification

In any event, I would not expect pylibnet (or libnet) to be responsible for the checksums.

See also http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html#id4744523

盛装女皇 2024-08-22 15:27:36

我已经更新了 pylibnet 以包含大多数标头中长度字段的自动大小确定。这样,如果您忘记为任何需要它的标头指定标头的长度,它将尝试自动确定它。省去了您找出校验和错误原因的麻烦;)

I have updated pylibnet to include an auto size determination for the length fields in most headers. This way if you forget to specify the length of the header for any of the headers that require it, it will attempt to automagically determine it. Saves you the headache of figuring out why your checksum is bad;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文