将时间戳存储为两个 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 中打开文件我得到 1 月 12 日 46860

查看有关时间戳的PCAPNG规范,它声明如下:

时间戳(高

)和时间戳(低):高和低 32 位 表示时间戳的 64 位数量。时间戳是单个 64 位无符号整数,表示自 1/1/1970 00:00:00 UTC。指定解释此字段的方式 通过接口的"if_tsresol"选项(请参阅图 9) 此数据包引用的说明块。请注意, 与 libpcap 文件格式不同,时间戳不会另存为 两个 32 位值,说明自那时以来的秒和微秒 1970/1/1。它们保存为单个 64 位数量,另存为两个 32 位字。

所以我假设我简单地将值存储为字节缓冲区中的长值,然后将其保存到文件中是错误的。但是我应该如何将时间戳保存为两个 32 位字呢?我尝试了不同的事情,例如简单地将值存储为两个整数,但似乎没有什么能给我正确的格式。

请注意,我还在数据包中指定了if_tsresol,但无论我给它什么值(3 表示 10^-3 => 毫秒),它都不会影响 Wireshark 解释文件的方式。

另一件需要注意的事情是,如果我将时间戳存储为秒,我确实会在 wireshark 中获得一个有效的时间戳。如此处所示 但是,毫秒被丢弃,这意味着无法根据时间戳解析同一秒内收到的所有数据包的顺序。

作为参考,下面是从之前从wireshark TCP捕获中获取的时间戳字段:

86 07 05 00 5A A5 4C F8

不知何故,我需要像他们一样存储我的时间戳。

最新的PCAP规范草案可以在这里找到

我找到了问题的解决方案。

时间戳确实正确存储为毫秒,但是,我没有将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

最新更新