使用Scapy对IP范围进行ping测试

10
我将尝试编写一个使用Scapy模块的Python脚本,以ping内部IP范围来确定哪些IP地址在线。目前我已经有了以下代码:
#!/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"

这个程序有时会长时间不做任何操作,如果我使用CTRL+C中止它,会出现一个错误信息:

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'

然而,如果我尝试使用单个IP地址而不是范围,则可以正常工作。像这样:

#!/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"

有人知道如何解决这个问题吗?或者你们有没有其他方法可以使用Scapy来ping一个IP范围,以确定哪些主机在线?


你的问题与将sr1(packet)的返回值分配给reply有关。我不熟悉scapy,所以除此之外无法提供更多帮助,但是从这里开始。 - brc
3个回答

7
您只需要确保下面所示的reply不是NoneType即可... 如果您在等待响应时超时,sr1()将返回None。 您还应该向sr1()添加一个timeout,默认的超时时间对您来说相当荒谬。
#!/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

packet[IP].src不会打印源IP吗?例如,如果您从10.1.1.1 ping到10.1.1.7并且失败了,回复将是“等待10.1.1.1超时”而不是“等待10.1.1.7超时”? - Saurabh Hirani

2

顺便说一下,Scapy支持隐式生成器。以下是示例:

ans, unans = sr(IP(dst="192.169.0.1-255")/ICMP(), timeout=2) 

然后遍历答案。
这样可能会更好 :)

2

如果变量的返回值为null,就无法显示reply.src字段。换句话说,您需要验证变量是否有返回某些值(如果ping成功)。您可以使用IF条件来仅在变量不为null时获取.src字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接