libnet创建带有无效校验和的UDP数据包
我使用pylibnet来构造和发送UDP数据包。我用这种方式构造的UDP数据包似乎都有无效的校验和。例如:libnet创建带有无效校验和的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
我错了在这里做什么?
这无关tcpdump的错误或校验和卸载。 Libnet也在用户模式下计算校验和(FYI)。这个问题与你没有为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()
计算校验和的工作通常不在用户空间库中执行,而是在设备驱动程序或硬件中执行。我相信你会看到“校验和卸载”的结果,物理设备会计算出站数据包的校验和,从而节省主机上的CPU周期。许多(如果不是全部的话)现代以太网适配器都这样做,并且驱动程序不计算校验和。由于tcpdump正在捕获驱动程序中的数据包,因此在它们到达物理设备之前,它只会在校验和字段(可能是缓冲区中剩下的内容)中发生垃圾并抱怨。
在2005年至2008年的时间段内,Wireshark报告了几个“bug”,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
我已经更新到pylibnet包括自动大小确定为最头的长度字段。这样,如果您忘记指定任何需要它的标题头的长度,它将尝试自动确定它。保存你头痛的搞清楚为什么你的校验不好;)
太好了。谢谢您的帮助! – Mox 2010-01-22 13:33:59
谢谢。我刚刚通过在接收主机上捕获这些数据包进行了调查。校验和在接收主机上也是不好的(并且在发送主机上的捕获中观察到相同的值)。所以它看起来不像校验和卸载是这里的答案。 – Mox 2009-12-15 19:28:14
如果接收主机实现了标准协议栈,或者两台主机之间至少有一台路由器,则数据包永远不会在接收主机上可见。其他事情正在发生。 – 2009-12-15 22:40:53