Хранение меток времени в виде двух 32-битных слов (формат pcapng)
Я генерирую файлы PCAPNG пакетов, которые я перехватываю. Кажется, все работает нормально, за исключением того, что временная метка каждого пакета является недействительной.
Проще говоря, я храню метку времени в байтовом буфере вместе со всеми остальными данными и записываю ее в файл. Когда я затем проверяю файл с помощью шестнадцатеричного редактора, я получаю следующее значение для поля отметки времени:
ByteBuffer data = ByteBuffer.allocate(epbLength).order(ByteOrder.BIG_ENDIAN);
data.putlong(timestamp);
00 00 01 49 D3 7F B4 D9 => 1416592602329 (According to Hex Fiend)
Это похоже на правильную метку времени. Однако, открыв файл в Wireshark я получаю 12 января 46860
Глядя на спецификацию PCAPNG, касающуюся метки времени, говорится следующее:
Timestamp (High) и Timestamp (Low): старшие и младшие 32 бита из 64-битной величины, представляющей метку времени. Отметка времени представляет собой одно 64-разрядное целое число без знака, представляющее количество единиц с 01.01.1970 по 00:00:00 UTC. Способ интерпретации этого поля определяется параметром 'if_tsresol' (см. Рисунок 9) блока описания интерфейса, на который ссылается этот пакет. Обратите внимание, что в отличие от формата файла libpcap временные метки не сохраняются как два 32-битных значения, учитывающих секунды и микросекунды с 1 января 1970 года. Они сохраняются как одно 64-битное количество, сохраняемое как два 32-битных слова.
Таким образом, я предполагаю, что для меня неправильно просто хранить значение как long в байтовом буфере, а затем сохранять его в файл. Но как мне сохранить метку времени в виде двух 32-битных слов? Я пробовал разные вещи, такие как просто сохранение значения в виде двух целых, но, похоже, ничто не дает мне правильный формат.
Обратите внимание, что я также указываю if_tsresol в пакете, но независимо от того, какое значение я ему даю (3 для 10^-3 => миллис), это не влияет на то, как Wireshark интерпретирует файл.
Еще одна вещь, которую стоит отметить: если я сохраню метку времени в секундах, я получу действительную метку времени в wireshark. Как видно здесь, однако, миллисекунды отбрасываются, что означает, что упорядочение всех пакетов, полученных в течение одной и той же секунды, не может быть разрешено с учетом временной отметки.
Для справки, вот поле метки времени, взятое из перехвата TCP Wireshark ранее:
86 07 05 00 5A A5 4C F8
Каким-то образом мне нужно хранить свою метку времени, как они.
Последний вариант спецификации PCAP можно найти здесь
1 ответ
Я нашел решение проблемы.
Временная метка действительно была правильно сохранена в миллисекундах, однако я неправильно сохранил параметр ts_resol в блоке заголовка интерфейса. Я просто сохранил 32-битное выровненное значение (целое число) в качестве значения параметра. Что неверно, поскольку в спецификации указано, что старший значащий бит определяет значение разрешения отметки времени.
Таким образом, решение состояло в том, чтобы сохранить значение ts_resol в виде одного байта, а затем добавить 3 дополнительных байта в качестве заполнения, чтобы выровнять значение по 32 битам.
ts_resol перед:
00 09 00 01 00 00 00 03
ts_resol после (решение):
00 09 00 01 03 00 00 00