2012-10-31 11 views
12

私はping時間に平均化できるscapyスクリプトを書こうとしているので、ICMPエコー/応答パケットと送信された応答パケットの間の経過時間を取得する必要があります。今のところ、私はこれを持っています:どのように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で取得する方法はありますか? 私は、未処理のパケット管理のためにscapyが必要なので、popen()関数または他のシステムコールを使用したくありません。

+0

'time.time()'の代わりに 'time.clock()'を使うのが良いかもしれません。 –

+0

'srp'ではなく' srp1'でうまくいくかもしれません。 –

+0

Nathan、あなたがscapyで行うことは、ひどく遅いです... scapyは、パケット全体を(ユーザ空間で)Pythonで解析します。 OSのシステムコールを使用するC実装と競合することはできません。 –

答えて

6

Scapyは、ユーザー空間でパケット全体を解析する純粋なPythonだから遅いです... it is not all that unusual to hack around scapy's thoughput limitations

リンゴをリンゴと比較しています...私はインターネットに直接のギガビットイーサネットパイプを備えたXeonサーバーを持っていますが、トラフィックは非常に軽いです。私はそれが添付ますCiscoルータに通常の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プロンプトからのベースラインping(245.469/0.062)...私はケーブルを自分で実行しました。シスコルータへのケーブルは10フィート未満です。

もっと良い結果を得るにはどうすればよいですか?コメントで述べたように、sent_timetime ... Packet.timeは解析前に入力されています...これはまだシェルの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 

サンプル実行...

[[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は印刷されません。

あなたはその後、tcpdumpからのpcapファイルを読むためにscapyのrdpcap()を使用して...あなたのCLIピングを実行する前に、tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> &を起動、後でscapy処理のために(シェルピングコールを通じて)あなたのpingパケットをキャプチャします。 pcapファイルでキャプチャするパケットの数を正しく計算してください。

+0

答え:私はこれを発見しました: "送信されたパケットはsent_time 'で、パケットはhavetime属性に応答しました。" http://comments.gmane.org/gmane.comp.security.scapy.general/4385 – user1789326

+0

@ user1789326:あなたは答えとしてコメントを投稿することができます – jfs

+1

なぜ0.29、0.23、0.22の平均が245ですか? – jfs

0

ところで、バッファリングされていないpython(python -uを起動すると)を使うと、バッファがダンプするのをPythonが待っていないためタイミング精度が向上します。上記のスクリプトを使用すると、私の結果は0.4ミリ秒オフから0.1ミリ秒オフに変わりました。

0

マイク、平均時間を得るために、ほんの少しの修正、変更:

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

へ:

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

(match.group(1))分の時間を取得しますので、言及された平均ではありません。

関連する問題