Scapy如何获取ping时间?
Posted
技术标签:
【中文标题】Scapy如何获取ping时间?【英文标题】:Scapy how get ping time? 【发布时间】:2012-10-21 05:45:39 【问题描述】:我正在尝试编写一个可以平均 ping 时间的 scapy 脚本,因此我需要获取发送 ICMP 回显/回复数据包和收到回复数据包之间经过的时间。现在,我有这个:
#! /usr/bin/env python
from scapy.all import *
from time import *
def QoS_ping(host, count=3):
packet = Ether()/IP(dst=host)/ICMP()
t=0.0
for x in range(count):
t1=time()
ans=srp(packet,iface="eth0", verbose=0)
t2=time()
t+=t2-t1
return (t/count)*1000
问题是使用 time() 函数并不能获得好的结果。例如,我在一个域上找到 134 ms,在同一个域上使用 ping 系统功能,我找到了 30 ms(当然是平均值)。
我的问题是:有没有办法获得 scapy 发送数据包和接收数据包之间的确切时间? 我不想使用 popen() 函数或其他系统调用,因为我需要 scapy 来管理未来的数据包。
【问题讨论】:
使用time.clock()
代替time.time()
可能会更好。
使用srp1
代替srp
可能效果更好。
Nathan,你在 scapy 中做的任何事情都非常慢...... scapy 在 python 中解析整个数据包(在用户空间中)。它无法与使用 OS 系统调用的 C 实现竞争。
添加那个作为答案,不要在问题中回答你的问题
无关:ping in pure python
【参考方案1】:
Scapy 很慢,因为它是纯 python 解析用户空间中的整个数据包...it is not all that unusual to hack around scapy's thoughput limitations.
进行苹果对苹果的比较...我有一台 Xeon 服务器,它有一个直接连接到互联网的千兆以太网管道,但我的流量非常少。当我对它所连接的 Cisco 路由器运行正常 ping 时,我平均每个大约 60 微秒...
[mpenning@Bucksnort ~]$ ping -W 1 -c 3 192.0.2.1
PING 192.0.2.1 (192.0.2.6) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_req=1 ttl=64 time=0.078 ms
64 bytes from 192.0.2.1: icmp_req=2 ttl=64 time=0.062 ms
64 bytes from 192.0.2.1: icmp_req=3 ttl=64 time=0.062 ms
--- 192.0.2.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.062/0.067/0.078/0.010 ms
[mpenning@Bucksnort ~]$
scapy 中的相同目的地...也以毫秒为单位...
[mpenning@Bucksnort ~]$ sudo python new_ping_ip.py
Ping: 0.285587072372
Ping: 0.230889797211
Ping: 0.219928979874
AVERAGE 245.468616486
[mpenning@Bucksnort ~]$
Scapy 的结果几乎是 bash 提示 (245.469 / 0.062) 的基线 ping 的 4000 倍...我自己运行电缆,它不到 10 英尺的电缆到 Cisco路由器。
你能做些什么来获得更好的结果?如 cmets 中所述,请查看 sent_time
和 time
...Packet.time
在解析之前填充...这仍然比来自 shell 的 ping 慢,但可能有助于您在 scapy 中捕获数据包。
#! /usr/bin/env python
from scapy.all import *
def QoS_ping(host, count=3):
packet = Ether()/IP(dst=host)/ICMP()
t=0.0
for x in range(count):
ans,unans=srp(packet,iface="eth0", filter='icmp', verbose=0)
rx = ans[0][1]
tx = ans[0][0]
delta = rx.time-tx.sent_time
print "Ping:", delta
t+=delta
return (t/count)*1000
if __name__=="__main__":
total = QoS_ping('192.0.2.1')
print "TOTAL", total
样品运行...
[mpenning@Bucksnort ~]$ sudo python ping_ip.py
Ping: 0.000389099121094
Ping: 0.000531911849976
Ping: 0.000631093978882
TOTAL 0.51736831665
[mpenning@Bucksnort ~]$
即使使用 Packet.time
和 Packet.sent_time
与 shell 调用相比也很慢......
>>> from subprocess import Popen, PIPE
>>> import re
>>> cmd = Popen('ping -q -c 3 192.0.2.1'.split(' '), stdout=PIPE)
>>> output = cmd.communicate()[0]
>>> match = re.search('(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+)\/(\d+\.\d+)\s+ms', output)
>>> if not (match is None):
... print "Average %0.3f" % float(match.group(1))
... else:
... print "Failure"
...
Average 0.073
>>>
ping -q -c 3
提供 3 次 ping 的摘要输出,但未打印单独的 ping。
如果您想捕获您的 ping 数据包(通过 shell ping 调用)以供以后处理 scapy
,请在运行 CLI ping 之前生成 tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> &
...然后使用 scapy 的 rdpcap()
从 @ 读取 pcap 文件987654339@。请务必正确计算您将在 pcap 文件中捕获的数据包数量。
【讨论】:
ANSWER:我发现了这个:“发送的数据包有 send_time',应答的数据包有时间'属性。”在comments.gmane.org/gmane.comp.security.scapy.general/4385 @user1789326:您可以发表评论作为答案 为什么0.29、0.23、0.22的平均值是245? 285.5ms + 230.9ms + 219.9ms 的平均值是245ms;单个数据包的响应时间以秒为单位打印,在return
期间,平均值转换为毫秒
对未来读者的警告:使用rx.time-tx.sent_time
可能会导致负时间测量(scapy 2.4.0-2.4.3rc1)。我为对此感兴趣的人创建了一个问题 (#1952)。【参考方案2】:
顺便说一句,使用无缓冲的 python(python -u 启动它)提高了计时精度,因为 python 不等待缓冲区决定转储。使用您上面的脚本,它将我的结果从 0.4 毫秒关闭到 0.1-ish 关闭。
【讨论】:
【参考方案3】:迈克,为了得到平均时间,只是一个小修正,改变:
print "Average %0.3f" % float(match.group(1))
到:
print "Average %0.3f" % float(match.group(2))
因为 (match.group(1)) 将获得最短时间,而不是前面提到的平均时间。
【讨论】:
以上是关于Scapy如何获取ping时间?的主要内容,如果未能解决你的问题,请参考以下文章