Pinging an IP range with Scapy

user961124 picture user961124 · Sep 24, 2011 · Viewed 27.3k times · Source

I'm attempting to write a Python script which uses the Scapy module to ping an internal IP range to determine which IP's are online. I've got this so far:

#!/usr/bin/python
from scapy.all import *
conf.verb = 0
for ip in range(0, 256):
    packet = IP(dst="192.168.0." + str(ip), ttl=20)/ICMP()
    reply = sr1(packet)
    if "192.168." in reply.src:
         print reply.src, "is online"

And the program will sit for a while doing nothing, and then if I kill it with CTRL+C I get an error message:

Traceback (most recent call last):
File "sweep.py", line 7, in <module>
if "192.168." in reply.src:
AttributeError: 'NoneType' object has no attribute 'src'

However if I try it with a single IP address, instead of a range, it works. Like this:

#!/usr/bin/python
from scapy.all import *
conf.verb = 0
packet = IP(dst="192.168.0.195", ttl=20)/ICMP()
reply = sr1(packet)
if "192.168." in reply.src:
    print reply.src, "is online"

Anyone know how I can fix this problem? Or do you have any other ideas on how I can ping an IP range with Scapy, to determine which hosts are online?

Answer

Mike Pennington picture Mike Pennington · Oct 19, 2011

You just need to ensure that reply is not NoneType as illustrated below... sr1() returns None if you get a timeout waiting for the response. You should also add a timeout to sr1(), the default timeout is quite absurd for your purposes.

#!/usr/bin/python
from scapy.all import *

TIMEOUT = 2
conf.verb = 0
for ip in range(0, 256):
    packet = IP(dst="192.168.0." + str(ip), ttl=20)/ICMP()
    reply = sr1(packet, timeout=TIMEOUT)
    if not (reply is None):
         print reply.dst, "is online"
    else:
         print "Timeout waiting for %s" % packet[IP].dst