Storing Timestamps as two 32 bit words (pcapng format)

1.8k views Asked by At

I am generating PCAPNG files of packets that I capture. Everything seems to work fine, except for the timestamp of each packet being invalid.

Simply put, I store the timestamp in a bytebuffer along with all the other data and write it to a file. When I then inspect the file using a hex editor I get the following value for the timestamp field:

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)

This seems like a valid timestamp. However, opening the file in Wireshark I get January 12, 46860

Looking at the PCAPNG specification regarding timestamp it states the following:

Timestamp (High) and Timestamp (Low): high and low 32-bits of a 64-bit quantity representing the timestamp. The timestamp is a single 64-bit unsigned integer representing the number of units since 1/1/1970 00:00:00 UTC. The way to interpret this field is specified by the ’if_tsresol’ option (see Figure 9) of the Interface Description block referenced by this packet. Please note that differently from the libpcap file format, timestamps are not saved as two 32-bit values accounting for the seconds and microseconds since 1/1/1970. They are saved as a single 64-bit quantity saved as two 32-bit words.

So I am assuming that it is wrong for me to simply store the value as a long in the bytebuffer and then save it to a file. But how am I supposed to save a timestamp as two 32 bit words? I have tried different things like simply storing the value as two ints but nothing seems to give me the right format.

Note that I also specify if_tsresol, in the packet, but no matter what value I give it (3 for 10^-3 => millis) it does not affect the way Wireshark interprets the file.

Another thing to note, is that if I store the timestamp as seconds, I do get a valid timestamp in wireshark. As seen here However, the milliseconds are discarded, meaning that the ordering of all packets received within the same second cannot be resolved given the timestamp.

As a reference, here is a timestamp field taken from a wireshark TCP capture earlier:

86 07 05 00 5A A5 4C F8

Somehow I need to store my timestamp like they do.

The latest PCAP specification draft can be found here

1

There are 1 answers

0
Simon Langhoff On BEST ANSWER

I found the solution to the problem.

The timestamp was indeed correctly stored as milliseconds, however, I did not store the ts_resol option correctly in the interface header block. I simply stored a 32 bit aligned value (integer) as the option value. Which is wrong, as the specification states that the most significant bit determines the value of the timestamp resolution.

The solution was thus to store the ts_resol value as a single byte and then add 3 extra bytes as padding to align the value to 32 bits.

ts_resol before:

00 09 00 01 00 00 00 03

ts_resol after (solution):

00 09 00 01 03 00 00 00