Scapy comment obtenir le temps de ping?

j'essaie d'écrire un script scapy qui peut faire une moyenne sur le temps de ping, donc j'ai besoin de récupérer le temps écoulé entre le paquet ICMP echo/reply envoyé et le paquet reply reçu. Pour l'instant, j'ai ceci:

#! /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

le problème est que l'utilisation de la fonction time() ne fait pas monter un bon résultat. Par exemple, je trouve 134 ms sur un domaine, et avec la fonction de système de ping sur le même domaine, j'ai trouvé 30 ms (en moyenne bien sûr).

ma question Est: y a-t-il un moyen d'obtenir l'heure exacte à laquelle beeteween a envoyé le paquet et reçu le paquet par scapy? Je ne veux pas utiliser la fonction popen () ou un autre appel système car j'ai besoin de scapy pour la gestion de paquets future.

12
demandé sur Mike Pennington 2012-10-31 21:27:47

3 réponses

Scapy est lent parce que c'est python pur parsing le paquet entier dans l'espace utilisateur... il n'est pas si inhabituel de contourner les limites de thoughput de scapy.

faire une comparaison de pommes à pommes... J'ai un serveur Xeon avec un tuyau ethernet direct gig sur internet, mais mon trafic est très léger. Quand j'exécute un ping normal sur le routeur Cisco auquel il est attaché, je suis en moyenne 60 microsecondes chacune...

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

sur Le même destination à scapy... également mesuré en millisecondes...

[mpenning@Bucksnort ~]$ sudo python new_ping_ip.py
Ping: 0.285587072372
Ping: 0.230889797211
Ping: 0.219928979874
AVERAGE 245.468616486
[mpenning@Bucksnort ~]$

les résultats de Scapy sont presque 4000 fois plus grand qu'un ping de base de l'invite de bash (245.469 / 0.062)... J'ai passé le câble moi-même, c'est moins qu'un câble de 10 pieds vers le routeur Cisco.

Que pouvez-vous faire pour obtenir de meilleurs résultats? Comme mentionné dans les commentaires, regardez sent_time et time... Packet.time est peuplé avant l'analyse... c'est encore plus lent qu'un ping depuis le shell, mais peut aider avec votre désir de capturer des paquets dans 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

Echantillonnage...

[mpenning@Bucksnort ~]$ sudo python ping_ip.py
Ping: 0.000389099121094
Ping: 0.000531911849976
Ping: 0.000631093978882
TOTAL 0.51736831665
[mpenning@Bucksnort ~]$

même en utilisant Packet.time et Packet.sent_time est cependant lent par rapport à un appel 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
>>>

ping -q -c 3 fournit la sortie sommaire de 3 pings sans les pings individuels imprimés.

si vous voulez capturer vos paquets de ping (via un appel de ping shell) pour plus tard scapy traitement de, frayer tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> & avant de lancer votre CLIP... puis utilisation scapy rdpcap() pour lire le fichier pcap de tcpdump. Assurez-vous de bien calculer le nombre de paquets que vous allez capturer dans votre fichier pcap.

6
répondu Mike Pennington 2017-05-23 12:16:56

BTW, l'utilisation de Python (python-u pour le démarrer) augmente la précision du timing car python n'attend pas que les buffers décident de décharger. En utilisant le script ci-dessus, il a changé mes résultats de 0.4 ms à 0.1-ish.

0
répondu fantadisco 2014-06-19 20:28:49

Mike, juste une petite correction pour obtenir le temps moyen, changer:

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

à:

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

depuis (match.group (1)) obtiendra le temps minimum et non le Moy tel que mentionné.

0
répondu Naor Kalbo 2016-12-29 09:03:56