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

10 投票
3 回答
39986 浏览
提问于 2025-04-17 03:00

我正在尝试写一个Python脚本,使用Scapy这个模块来对一个内部IP范围进行ping测试,以确定哪些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对一个IP范围进行ping测试,以确定哪些主机是在线的?

3 个回答

2

顺便说一下,Scapy支持隐式生成器。

这个是可以用的:

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

然后可以遍历这些答案。

2

如果变量的返回值是空的,你就不能显示reply.src这个字段。换句话说,你需要先检查一下这个变量是不是有值(也就是ping操作是否成功)。你可以用一个IF条件,只有在变量有值的时候才去获取.src这个字段。

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

撰写回答