user3124171
user3124171

Reputation: 401

Python scapy show ip of the ping (echo) requests

I want to grab and print the source address of the ping requests. I have the following script:

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

When a packet arrives script crashes with

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

However on the scapy console I can see clearly that this exist!

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

Any thoughts??

I changed for testing purposes (!) my script to the following:

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)

The above after doing a ping:

ping localhost -c 3

produces the following awkward result:

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

We can ignore the "packet arrived" multiple times because other packets are reaching my host as well. But why I see 6 times the 127.0.0.1 when I sent 3 echo requests ? Even if I remove the for loop the same results are happening.

Upvotes: 3

Views: 13115

Answers (2)

wookie919
wookie919

Reputation: 3134

What sniff() returns is not a list of packets, even though you can iterate over it as if it was a list. See below example:

>>> 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>
>>>

If sniff() simply returned a list of packets, pkt[ICMP] in your example would never work. What pkt[ICMP] does is that it retrieves a list of all ICMP packets in pkt.

Upvotes: 1

Padraic Cunningham
Padraic Cunningham

Reputation: 180411

You have multiple packets so you can either index or iterate over:

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)

Or using indexing to get the forst packet:

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)

Upvotes: 1

Related Questions