Python Raw Socket 无法接收 ICMP 消息;出现在 Wireshark 中

Posted

技术标签:

【中文标题】Python Raw Socket 无法接收 ICMP 消息;出现在 Wireshark 中【英文标题】:Python Raw Socket cannot recieve ICMP messages; show up in Wireshark 【发布时间】:2012-11-29 20:18:32 【问题描述】:

我正在尝试实现一个 python traceroute,它发送 UDP 消息并通过原始套接字接收 ICMP 响应。我遇到了一个问题,ICMP 数据包似乎不惜一切代价避免捕获。 ICMP 响应正如我所期望的那样在wireshark 中显示,但套接字从不接收任何要读取的数据。另一个复杂之处是我在运行 Ubuntu 的 VirtualBox 上运行代码,因为 sendto() 不会在 Windows 7 中获取数据包。(我在 Windows 中运行 wireshark 来捕获数据包)。奇怪的是,当我从虚拟机运行 python 脚本时,wireshark 会捕获 ICMP 消息。但是,当我尝试在 Windows 上运行脚本时,ICMP 消息不会显示在wireshark 中。 (UDP数据包神奇地开始在windows上工作)

我已经从在线示例中尝试了各种不同版本的设置套接字,并尝试使用 bind() 而不使用它,但似乎没有配置产生读取的套接字。等待读取 ICMP 消息将超时。

还应注意,如果我尝试读取我的 udp 发送套接字,它会成功读取 udp 数据包。一旦我设置 IPPROTO_ICMP 读取超时。

receive_response 方法:

def receive_response(rec_socket, packetid, tsend, timeout):
remain = timeout
print packetid
while remain > 0:
    ready = select.select([rec_socket], [], [], remain)
    if ready[0] == []:
        return
    print 'got something'

设置套接字:

rec_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
rec_socket.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
rec_socket.bind(("",0))      #played with using this statement and skipping it

调用接收很简单:

reached = receive_response(rec_socket, packetid, time.time(), timeout)

【问题讨论】:

Wireshark 是如此专业的工具,有时对于简单的任务它甚至可能使事情复杂化。您能否尝试 SmartSniff (nirsoft.net/utils/smsniff.html) 并在使用和不使用 WinpCap 的情况下再试一次?这适用于 Windows... 使用 smartsniff,默认情况下会发生相同的行为:从主机/windows 尝试它不会看到 icmp 数据包并从 vm 运行导致嗅探器看到 icmp 数据包,但然后打开 winpcap icmp 数据包是在这两种情况下都没有看到。 运行程序时你应该是管理员。 【参考方案1】:

看起来问题是 VirtualBox 将默认使用 NAT 连接到网络。这意味着虚拟机不会接收到 ICMP 消息,因为它们是 ICMP 消息。似乎解决方案是将 VirtualBox 网络配置为使用“桥接网络”模式。不幸的是,我无法确认这一点,因为我无法在桥接模式下在我的大学网络上设置虚拟机。至于在windows下不工作的原因,肯定是windows不支持raw socket有关。

【讨论】:

以上是关于Python Raw Socket 无法接收 ICMP 消息;出现在 Wireshark 中的主要内容,如果未能解决你的问题,请参考以下文章

Raw Socket Linux 发送/接收数据包

python socket.io客户端无法接收广播消息

使用数据包套接字在同一网络接口上发送和接收时无法接收包

python raw socket 介绍

Python 原始套接字 (Windows):嗅探以太网帧

python用socket 接收数据问题?