Как использовать метку времени из заголовка оперативного захвата в dpkt Writer? - PullRequest
0 голосов
/ 19 апреля 2019

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

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

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

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

Я также пытался использовать библиотеку 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)

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 writer ts.Надеюсь, скоро выложу рабочий пример

1 Ответ

0 голосов
/ 20 апреля 2019

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