Python原始套接字无法接收ICMP消息;出现在Wireshark



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

我在网上的例子中尝试过各种不同版本的设置套接字,也尝试过使用bind()和不使用它,但似乎没有任何配置可以产生读取套接字。等待读取ICMP消息会超时。

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

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)

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

最新更新