ICMP 数据包嗅探未收到任何数据(Black Hat Python Book)

ICMP packet sniffing not receiving any data (Black Hat Python Book)

我从书中看到这段代码片段,黑帽 Python,第 3 章网络:原始套接字和嗅探:

import socket
import os

host = "x.x.x.x"        # Host to listen on

# Create a raw socket and bind it to the public interface
if os.name == "nt":
    socket_protocol = socket.IPPROTO_IP
else:
    socket_protocol = socket.IPPROTO_ICMP
    
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)     # We want the IP headers included in the capture
# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print(sniffer.recvfrom(65565))      # Read in a single packet

# If we're using Windows, turn off promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

当我执行 ping google.com 时,上面的代码应该捕获第一个 ping 数据包,但是 在行 print(sniffer.recvfrom(65565)) 中无限期地等待数据包 ].

我尝试使用 host 作为我机器的本地 ip 和 localhost,并尝试更改缓冲区大小,如 中所示。但是效果并不好

我在设置 host = "" 并执行 ping 127.0.0.1 时工作,但在我 ping 其他 url 时不工作。

谁能告诉我哪里出了问题?

我正在使用 Python 3.8.2 和 Ubuntu 18.04。

实际上问题不在于代码,而是兼容性问题,ping 更现代的服务器由 IPv6 完成,而代码仅选择 IPv4 ICMP 数据包。一个简单的解决方案是通过 :

将 ping 限制为 IPv4
ping -4 google.com

IPv6 的嗅探器只需要对 IPv4 版本进行小的改动,如下所示:

import socket
import os

host = ""       # Host to listen on

# Create a raw socket and bind it to the public interface
if os.name == "nt":
    socket_protocol = socket.IPPROTO_IPV6
else:
    socket_protocol = socket.IPPROTO_ICMPV6
    
sniffer = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IPV6, socket.IP_HDRINCL, 1)       # We want the IP headers included in the capture
# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print(sniffer.recvfrom(65565))      # Read in a single packet

# If we're using Windows, turn off promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)