3

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.

user3124171
  • 401
  • 2
  • 7
  • 19

2 Answers2

1

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)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • Here im not using the [0] though.. and the same thing is happening http://www.picpaste.com/pics/icmp_problem-g3q981FT.1429788898.png – user3124171 Apr 23 '15 at 11:35
  • add a `print(pkts.summary())` before the loop, then tell me what does not match up – Padraic Cunningham Apr 23 '15 at 11:40
  • LOL. thats quite interesting... There is a problem here obviously... Is this a bug in scapy?? http://www.picpaste.com/pics/scapy_hmmm_-IKNMgx5i.1429789818.png http://www.picpaste.com/pics/ICMP_LOL-VC2psSk5.1429789532.png It looks like it duplicates the entries somehow... You can see from my tcpdump (which definitely doesnt lie) that I send 3 requests and 3 responses came back... Where scapy shows them 2 times... What do you think?? – user3124171 Apr 23 '15 at 11:52
  • If you `ping -c 3 localhost` and set count to 3 what do you get? – Padraic Cunningham Apr 23 '15 at 11:55
  • This is the first screenshot from my previous message.. the -c 3 sends 3 echo requests as we know... But scapy for a reason sees this process 2 times ( 6 requests - 6 responses)... – user3124171 Apr 23 '15 at 11:58
  • Yes but what happens when you lower the count to 3? – Padraic Cunningham Apr 23 '15 at 11:59
  • you can also remove the haslayer when filtering – Padraic Cunningham Apr 23 '15 at 12:05
  • Thats something interesting... So the count is for all the packets and not for the packets in filter I guess. When I set it to 3 and I ping usually it grabs the 2 requests + 1 more random packet... I tried the count=7 and the random results started happening... ping 3 times see 4 times the IP.src.. I think count doesnt work as intended.. – user3124171 Apr 23 '15 at 12:07
  • I removed count completely... Still duplicated results.. I also removed the haslayer.. I think there is something else here related to sniff() itself maybe. – user3124171 Apr 23 '15 at 12:17
1

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.

wookie919
  • 3,054
  • 24
  • 32
  • Thanks for your reply. That was helpful actually.. But why the for packet in pkts: if packet.haslayer(ICMP) and str(packet.getlayer(ICMP).type)=="8": print (packet[IP].src) produces duplicate results?? Thanks – user3124171 Apr 23 '15 at 11:19
  • Because when you `ping localhost` both your source and destination IP addresses are `127.0.0.1`. So both the echo request and echo reply has the source IP address of `127.0.0.1`. – wookie919 Apr 23 '15 at 20:59
  • but I have also an if statement for picking only the echo requests – user3124171 Apr 30 '15 at 10:55