Подтвердить что ты не робот

Скапи, как получить пинг время?

Я пытаюсь написать scapy script, который может сделать среднее время 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

Проблема заключается в том, что использование функции time() не приводит к хорошему результату. Например, я нахожу 134 мс на одном домене и с помощью функции системы ping в том же домене, я нашел 30 мс (в среднем, конечно).

Мой вопрос: есть ли способ получить точное время, отправленное между отправленным пакетом и принятым пакетом scapy? Я не хочу использовать функцию popen() или другой системный вызов, потому что мне нужно scapy для управления пакетами futur.

4b9b3361

Ответ 1

Scapy медленный, потому что чистый python анализирует весь пакет в пользовательском пространстве... не так уж и необычно взломать ограничения scatchy.

Сочетание яблок с яблоками... У меня есть сервер Xeon с прямой трубкой ethernet в Интернете, но мой трафик очень легкий. Когда я запускаю обычный пинг на маршрутизатор Cisco, к которому он подключен, я усредняю ​​около 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 почти 4000 раз больше, чем исходный пинг из приглашения bash (245.469/0.062)... Я сам запустил кабель, он меньше, чем 10 футовый кабель для маршрутизатор Cisco.

Что вы можете сделать, чтобы получить лучшие результаты? Как уже упоминалось в комментариях, посмотрите на sent_time и time... Packet.time заполняется до разбора... это все еще медленнее, чем пинг из оболочки, но может помочь с вашим желанием захватить пакеты в 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.time и 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 предоставляет итоговый вывод из 3-х пинов без распечатки отдельных писем.

Если вы хотите захватить ваши пакеты ping (через вызов ping оболочки) для последующей обработки scapy, spawn tcpdump -c <num-packets> -w <filename> icmp and host <host-addr> & перед запуском вашего ping ping... затем используйте scapy rdpcap(), чтобы прочитать файл pcap с tcpdump. Не забудьте правильно рассчитать количество пакетов, которые вы будете записывать в свой файл pcap.

Ответ 2

BTW, используя небуферизованный питон (python -u для его запуска) увеличивает точность синхронизации, поскольку python не ждет, пока буферы решат сбросить. Используя вышеприведенный script, он изменил мои результаты на то, чтобы быть выключенным на 0,4 мс, чтобы отключить его на 0,1-иш.

Ответ 3

Майк, просто небольшое исправление, чтобы получить среднее время, измените:

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

в

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

поскольку (match.group(1)) получит минимальное время, а не avg, как указано.