Python scapy 显示 ping (echo) 请求的 ip

Python scapy show ip of the ping (echo) requests

我想抓取并打印 ping 请求的源地址。 我有以下脚本:

pkt = sniff(filter="icmp", timeout =15, count = 15)
if pkt[ICMP].type == '8':
    print pkt[IP].src

当数据包到达时脚本崩溃

 AttributeError:'list' object has no attribute 'type'

但是在scapy控制台上我可以清楚地看到这个存在!

>>>packet=IP()/ICMP()/"AAAAAA"
>>>packet[ICMP].type
8
>>>

有什么想法吗??

出于测试目的,我将脚本更改为 (!) 以下内容:

pkts=sniff(filter="icmp", timeout=120,count=15)

for packet in pkts:
    if packet.haslayer(IP) and str(packet.getlayer(IP).src)=="127.0.0.1"
       print "packet arrived"
           if packet.haslayer(ICMP) and str(packet.getlayer(ICMP).type)=="8":
                print(packet[IP].src)

ping 之后的上面:

ping localhost -c 3

产生以下尴尬的结果:

packet arrived
127.0.0.1
packet arrived
127.0.0.1
packet arrived
packet arrived
packet arrived
127.0.0.1
packet arrived
127.0.0.1
packet arrived
packet arrived
packet arrived
127.0.0.1
packet arrived
127.0.0.1
packet arrived

我们可以多次忽略 "packet arrived",因为其他数据包也到达了我的主机。但是为什么当我发送 3 个回显请求时我看到 127.0.0.1 的 6 倍?即使我删除 for 循环,也会出现相同的结果。

您有多个数据包,因此您可以索引或迭代:

from scapy.all import *
pkts = sniff(filter="icmp", timeout =15,count=15)

for packet in pkts:
     if  str(packet.getlayer(ICMP).type) == "8": 
        print(packet[IP].src)

或使用索引获取第一个数据包:

from scapy.all import *
pkts = sniff(filter="icmp", timeout =15,count=15)

if pkts  and str(pkts[0].getlayer(ICMP).type) == "8": 
        print(pkts[0][IP].src)

What sniff() returns 不是数据包列表,即使您可以像列表一样对其进行迭代。请参阅以下示例:

>>> from scapy.all import *
>>> pkts = sniff(count = 15)
>>> pkts
<Sniffed: TCP:4 UDP:4 ICMP:0 Other:7>
>>> pkts[TCP]
<TCP from Sniffed: TCP:4 UDP:0 ICMP:0 Other:0>
>>>

如果 sniff() 只是返回一个数据包列表,那么您示例中的 pkt[ICMP] 将永远无法工作。 pkt[ICMP] 的作用是检索 pkt.

中所有 ICMP 数据包的列表