2012-10-31 102 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)),將獲得分鐘時間而不是如前所述的平均值。