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

#python #writer #dpkt #pcapy

#питон #писатель #дпкт #пкэпи

Вопрос:

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

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

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, извлекать временную метку в виде str и затем вставьте его в качестве аргумента ‘ts’ при записи в pcap:

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

редактировать: итак, я просмотрел исходный код объекта 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). Следующий шаг — объединить это в одно число и ввести его в ts записи dpkt. Я опубликую рабочий пример, надеюсь, очень скоро

Ответ №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')