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.
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.
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.
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é.