Scapy如何获得ping时间?

use*_*326 12 python time networking ping scapy

我正在尝试编写一个scapy脚本,它可以在ping时间上取平均值,因此我需要在发送的ICMP echo/reply数据包和收到的回复数据包之间得到时间.现在,我有这个:

#! /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
Run Code Online (Sandbox Code Playgroud)

问题是使用time()函数不会产生好的结果.例如,我在一个域上发现134毫秒,并且在同一个域上使用ping系统功能,我发现30毫秒(当然是平均值).

我的问题是:有没有办法通过scapy获得发送的数据包和收到的数据包之间的确切时间?我不想使用popen()函数或其他系统调用,因为我需要scapy来进行未来数据包管理.

Mik*_*ton 6

Scapy很慢,因为它是纯粹的python解析用户空间中的整个数据包...... 围绕scapy的输出限制并不是那么不寻常.

进行苹果对苹果比较...我有一个Xeon服务器,带有直接的gig以太网管道到互联网,但我的流量很轻.当我对连接到的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 ~]$
Run Code Online (Sandbox Code Playgroud)

scapy中的同一目的地...也以毫秒为单位测量......

[mpenning@Bucksnort ~]$ sudo python new_ping_ip.py
Ping: 0.285587072372
Ping: 0.230889797211
Ping: 0.219928979874
AVERAGE 245.468616486
[mpenning@Bucksnort ~]$
Run Code Online (Sandbox Code Playgroud)

Scapy的结果比bash提示符(245.469/0.062)的基线ping大近4000倍......我自己运行了电缆,它距离Cisco路由器的电缆不到10英尺.

你能做些什么来获得更好的结果?正如在注释中所提到的那样,在解析之前看看sent_timetime... 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
Run Code Online (Sandbox Code Playgroud)

样品运行......

[mpenning@Bucksnort ~]$ sudo python ping_ip.py
Ping: 0.000389099121094
Ping: 0.000531911849976
Ping: 0.000631093978882
TOTAL 0.51736831665
[mpenning@Bucksnort ~]$
Run Code Online (Sandbox Code Playgroud)

虽然使用Packet.timePacket.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
>>>
Run Code Online (Sandbox Code Playgroud)

ping -q -c 3 提供3个ping的摘要输出,不打印单个ping.

如果你想捕获ping数据包(通过shell ping调用)以便以后scapy处理,tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> &在运行CLI ping之前生成...然后使用scapy rdpcap()来读取pcap文件tcpdump.请务必正确计算您将在pcap文件中捕获的数据包数量.