12

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() 関数を使用しても良い結果が得られないことです。たとえば、1 つのドメインで 134 ミリ秒が検出され、同じドメインで ping システム機能を使用すると、30 ミリ秒が検出されました (もちろん平均)。

私の質問は次のとおりです:送信パケットと受信パケットの間の経過時間を正確に取得する方法はありますか? 将来のパケット管理のために scapy が必要なので、popen() 関数やその他のシステム コールを使用したくありません。

4

3 に答える 3

7

ユーザー空間でパケット全体を解析する純粋な python であるため、Scapy は低速で​​す... scapy のスループット制限を回避することはそれほど珍しいことではありません

リンゴとリンゴの比較を行います...インターネットへの直接ギグイーサネットパイプを備えた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 プロンプトからのベースライン ping のほぼ4000倍です (245.469 / 0.062)... 私は自分でケーブルを配線しました。Cisco ルーターへのケーブルは 10 フィート未満です。

より良い結果を得るために何ができますか? コメントで述べたように、解析前にsent_timeand time... Packet.timeis populated を見てください... これはシェルからの 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.timeandを使用してもPacket.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個々の ping を出力せずに、3 つの ping の要約出力を提供します。

scapy後で処理するために (シェルの ping 呼び出しを介して) ping パケットをキャプチャする場合はtcpdump -c <num-packets> -w <filename> icmp and host <host-addr> &、CLI の ping を実行する前に spawn を実行してから、scapy を使用rdpcap()して から pcap ファイルを読み取りますtcpdump。pcap ファイルでキャプチャするパケット数を正しく計算してください。

于 2012-11-01T09:40:17.863 に答える
0

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

于 2014-06-19T20:28:49.427 に答える