как использовать метку времени из заголовка живого захвата в dpkt записывающем устройстве?

У меня возникли проблемы с утилитой захвата пакетов, которую я пишу. В настоящее время я использую pcapy для открытия живого потока байтов и dpkt для декодирования пакетов. Я также хочу записывать пакеты в файл .pcap, который работает с объектом dpkt.Writer, однако метки времени, записанные в файле pcap, относятся к моменту, когда писатель записывает пакет в файл pcap, а не когда сетевой интерфейс или ядро ​​получило сообщение.

Я понимаю из документации, что при записи вы можете предоставить ts для использования писателем, однако я не понимаю, как его извлечь из заголовка полученного пакета. Из примеров, которые я могу найти, которые показывают, как распечатать метку времени при чтении файла, может показаться, что я могу просто напечатать первое значение кортежа, которое я получаю из потока байтов, однако, когда я это делаю, я получаю следующую ошибку:

TypeError: аргумент int() должен быть строкой, байтовым объектом или числом, а не 'Pkthdr'

Ошибка достаточно ясна: я, без сомнения, должен найти атрибут timestamp в объекте Pkthdr, но я не могу найти документацию/примеры ни в проекте pcapy, ни в dpkt, которые объясняют, как анализировать «заголовок»

Я также пытался использовать библиотеку pypcap для захвата в реальном времени, но результат тот же. Я также попытался использовать тот же код на python 2.7.5, поскольку я читал, что dpkt может еще не полностью поддерживать python3, но тот же результат в любой версии.

#!/usr/bin/env python3.6
import pcapy
import dpkt

cap = pcapy.open_live("eth0", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
    (header,packet) = cap.next()
    writer.writepkt(packet, header)
    print('packet printed')

Чтобы доказать, что временные метки в pcap относятся к моменту записи, я добавил период ожидания перед повторной записью того же пакета. Вы увидите, что они показывают разницу в ~ 1 секунду в отметке времени заголовка:

#!/usr/bin/env python3.6
import pcapy
import dpkt
import time

cap = pcapy.open_live("em2", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
    (header,packet) = cap.next()
    writer.writepkt(packet, )
    time.sleep(1)
    writer.writepkt(packet, )
    print('packet printed')

Я не сильно завишу ни от pcapy, ни от dpkt, поэтому я готов отключить любую из этих библиотек, если есть лучший метод, однако у меня есть ощущение, что кто-то с немного большим опытом может показать мне, как копаться в объекта Pkthdr, извлеките метку времени как строку, а затем вставьте ее в качестве аргумента 'ts' при записи в pcap:

ts = %unpack from header%
writer.writepkt(packet, ts)

edit: поэтому я просмотрел исходный код объекта pkthdr в модуле pcapy и нашел кое-что полезное: похоже, есть функция getts для получения метки времени от объекта:

static PyMethodDef p_methods[] = {
  {"getts", (PyCFunction) p_getts, METH_VARARGS, "get timestamp tuple 
(seconds, microseconds) since the Epoch"},
  {"getcaplen", (PyCFunction) p_getcaplen, METH_VARARGS, "returns the length 
of portion present"},
  {"getlen", (PyCFunction) p_getlen, METH_VARARGS, "returns the length of 
the packet (off wire)"},
  {NULL, NULL}  /* sentinel */
};

в моем коде Python я назвал функцию следующим образом:

timestamp = header.getts()

И он вернул кортеж, содержащий секунды и микросекунды заголовка, например. (1555710256, 942645). Следующим шагом является объединение этого числа в одно число и ввод его в dpkt записывающее устройство ts. Я опубликую рабочий пример, надеюсь, очень скоро


person psi    schedule 19.04.2019    source источник


Ответы (1)


Хорошо, я адекватно решил свою проблему. Точность метки времени указана в микросекундах и одинакова для обеих копий в .pcap.

#!/usr/bin/env python3.6
import pcapy
import dpkt
import time

cap = pcapy.open_live("em2", 65435, True, 100)
(header,packet) = cap.next()
timestamp = header.getts()
print (timestamp)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
    (header,packet) = cap.next()
    ts = header.getts()
    now = time.time()
    print (ts)
    timestamp = ts[0] + (float(ts[1])/1000000))
    writer.writepkt(packet, timestamp)
    time.sleep(1)
    writer.writepkt(packet, timestamp)
    print('packet printed')
person psi    schedule 19.04.2019