为什么这段Python代码在Linux下能够运行但在Windows下不行?

2 投票
2 回答
809 浏览
提问于 2025-04-18 11:31

我正在检查一个捕获的数据包文件的位置。在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 个回答

1

请注意,Windows系统的socket库里没有inet_ntop这个函数,只有Linux系统有。你可以在Windows上使用IPy这个Python库来处理IPv6地址,方法如下:

ip = eth.data
src = IPy.IP(ip.src.encode('hex'))
2

数据包 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()。

撰写回答