У меня возникли проблемы с утилитой захвата пакетов, которую я пишу. В настоящее время я использую 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. Я опубликую рабочий пример, надеюсь, очень скоро