2012-10-31 105 views
12

我想写一个scapy脚本,它可以在ping时间上做出平均值,所以我需要获得ICMP回送/回复数据包发送和接收到回复数据包之间的时间间隔。现在,我有这个:Scapy如何获得ping时间?

#! /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毫秒,并且在同一个域上使用ping系统功能,我发现了30毫秒(平均值)。

我的问题是:有没有办法让elpased beetween发送的数据包,并通过Scapy的接收数据包的准确时间? 我不想使用popen()函数或其他系统调用,因为我需要scapy来处理未来的数据包管理。

+0

使用'time.clock()'而不是'time.time()'可能会有更好的运气。 –

+0

它可能更好地用'srp1'而不是'srp'。 –

+0

Nathan,你在scapy中做的任何事情都非常慢...... scapy在python中解析整个数据包(在用户空间中)。它不能与使用OS系统调用的C实现竞争。 –

回答

6

Scapy的是缓慢的,因为它是纯Python解析在用户空间... it is not all that unusual to hack around scapy's thoughput limitations整个数据包。

制作一个苹果,苹果的比较......我有一个直接的演出以太网管道到互联网的至强服务器,但我的流量是它很轻。当我运行一个正常的ping到它的附着,我平均每个约60微秒的思科路由器...

[[email protected] ~]$ 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 
[[email protected] ~]$ 

在Scapy的...也以毫秒为单位的相同的目的地...

[[email protected] ~]$ sudo python new_ping_ip.py 
Ping: 0.285587072372 
Ping: 0.230889797211 
Ping: 0.219928979874 
AVERAGE 245.468616486 
[[email protected] ~]$ 

Scapy的的结果比从bash提示符(245.469/0.062)......我跑了电缆自己的基线平大几乎时代,这是不到十英尺电缆连接到Cisco路由器的。

什么可以做,以取得更好的成绩?正如评论所说,看sent_timetime ... Packet.time在解析之前填充......这仍然比从壳平慢,但可能会与你的愿望,捕获数据包在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 

采样运行...

[[email protected] ~]$ sudo python ping_ip.py 
Ping: 0.000389099121094 
Ping: 0.000531911849976 
Ping: 0.000631093978882 
TOTAL 0.51736831665 
[[email protected] ~]$ 

即使使用Packet.timePacket.sent_time相比,外壳调用,虽然是慢...

>>> 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呼叫)供以后scapy处理,运行您的CLI平之前产卵tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> & ...然后使用Scapy的的rdpcap()tcpdump读取PCAP文件。请务必正确计算您将在您的pcap文件中捕获的数据包数量。

+0

答案:我发现这一点:“发送的数据包有sent_time',应答的数据包有'time'属性。”在http://comments.gmane.org/gmane.comp.security.scapy.general/4385 – user1789326

+0

@ user1789326:你可以发表评论作为回答 – jfs

+1

为什么0.29,0.23,0.22的平均值是245? – jfs

0

顺便说一句,使用无缓冲蟒(蟒-u来启动它)增加的定时精度蟒不等待缓冲器来决定倾倒。使用上面的脚本,它将我的结果从0.4 ms改为0.1 ish。

0

迈克,只是为了获得平均时间,变化的小修正:

print "Average %0.3f" % float(match.group(1)) 

到:

print "Average %0.3f" % float(match.group(2)) 

因为(match.group(1)),将获得分钟时间而不是如前所述的平均值。