为什么这段Python代码在Linux下能够运行但在Windows下不行?
我正在检查一个捕获的数据包文件的位置。在Ubuntu系统上运行时,一切都很顺利,但如果我切换到Windows系统,每当遇到一个IPv6数据包时,它就会停止。我希望它能像在Ubuntu上一样跳过这个数据包,继续处理下一个,但它并没有这样做。每次遇到IPv6地址时,它都会停止这个循环。
有没有什么办法可以解决这个问题呢?
def printPcap(pcap):
for (ts, buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
src = socket.inet_ntoa(ip.src)
dst = socket.inet_ntoa(ip.dst)
print '[+] Src: ' + src + ' --> Dst: ' + dst
print '[+] Src: ' + retGeoStr(src) + ' --> Dst: ' + retGeoStr(dst) + '\n'
except:
pass
如果我打印出错误信息,捕获到的异常会显示:
数据包的IP长度不正确,无法用于inet_ntoa
我很确定这是因为它是IPv6数据包,所以我希望它能继续处理下一个数据包,但它还会打印出这个错误:
'str'对象没有'src'属性
我觉得这可能是导致我问题的原因。
就像我说的,它在遇到那个IPv6地址之前都能正常工作,在Ubuntu上也没问题。我感到很困惑。
2 个回答
请注意,Windows系统的socket库里没有inet_ntop这个函数,只有Linux系统有。你可以在Windows上使用IPy这个Python库来处理IPv6地址,方法如下:
ip = eth.data
src = IPy.IP(ip.src.encode('hex'))
数据包 IP 长度错误,无法使用 inet_ntoa
inet_ntoa 这个函数只适用于 IPv4 地址。你在一个系统上能用,而在另一个系统上不能用,可能是因为你在其中一个系统上只收到了 IPv6 的数据包。
根据文档说明,https://docs.python.org/2/library/socket.html
socket.inet_ntoa(packed_ip) 这个函数可以把一个32位的打包 IPv4 地址(长度为四个字符的字符串)转换成标准的点分十进制字符串表示(比如,‘123.45.67.89’)。这在和使用标准 C 库的程序交流时很有用,因为这些程序需要类型为 struct in_addr 的对象,而这个类型正是这个函数所接受的32位打包二进制数据。
如果传给这个函数的字符串长度不是正好4个字节,就会抛出 socket.error 错误。inet_ntoa() 不支持 IPv6,如果需要同时支持 IPv4 和 IPv6,应该使用 inet_ntop()。