Wireshark-dev: Re: [Wireshark-dev] Time Zone Setting in a PCAP-NG file

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Sun, 5 Feb 2017 11:47:40 -0800
On Feb 5, 2017, at 10:21 AM, Paul Offord <Paul.Offord@xxxxxxxxxxxx> wrote:
 
> I need some guidance on the time zone settings in a PCAP-NG file.

Are you referring to the if_tzone option in the Interface Description block, which:

	1) is specified so vaguely as to make it not actually *usable* - to quote the current pcapng spec:

		The if_tzone option identifies the time zone for GMT support (TODO: specify better).

and

	2) is, in fact, not actually read by any software I know of whatsoever?

> I have a pcapng file captured in the UK on 12th October 2016.  That means that the time zone at the time of capture was GMT +1.

...which is not recorded anywhere in the file.

> There is a trace entry in this trace that shows in Wireshark today as 15:40:31.541142.

That entry has, in the file, a time stamp that does not give local time, but gives UTC; to quote the pcapng spec entry for the EPB:

	Timestamp (High) and Timestamp (Low): upper 32 bits and lower 32 bits of a 64-bit timestamp. The timestamp is a single 64-bit unsigned integer that represents the number of units of time that have elapsed since 1/1/1970 00:00:00 UTC.

All other time stamps are given in the same or a similar format.  1/1/1970 00:00:00 UTC is "the Epoch" in UN*X/POSIX terminology, i.e. the time origin for time stamps on UN*X systems.  (There is an issue with leap seconds here; don't get me started on POSIX and leap seconds....)

> A screenshot taken at the time of the trace entry shows a clock time of 15:40.
>  
> <image003.jpg>
>  
> If I look inside the pcapng file with a hex editor, there is no if_tzone option set in the IDB.

That's right - I know of no software that *sets* it, either, because it's currently so vaguely defined that it's not interpretable.

That was deliberate - those working on the spec had no idea yet how the time zone should be specified.

My personal preference is to have it use IANA tzdb zone IDs:

	https://www.iana.org/time-zones

although, currently:

	most of the UN*Xes on which Wireshark runs use the IANA tzdb, but

		1) there's no convenient API to take a tzdb ID and convert a *particular* "seconds since the Epoch" time stamp to a displayable representation of local time in any of those systems, as far as I know;

		2) new IANA zones are created over time as necessary - and nations/regions make it necessary all the time - a given system might have an older version of the tzdb that lacks the ID for the region in which a capture is done;

	Windows, and, I think, even some UN*Xes (HP-UX and AIX, perhaps?) don't use the tzdb, and don't even have the raw data available;

so supporting that in programs such as tcpdump, Wireshark, etc. might not be simple.

>  The EPB for the trace entry I’ve referred to above has:
>  
> ·        Timezone High – 0xAB3E0500
> ·        Timezone Low – 0xC0B1FE22
>  
> If there is no time reference setting in the trace file, how does Wireshark know that the file was recorded in GMT +1 timezone.

It doesn't.

It takes that time, converts it (in libwiretap) to seconds since the Epoch and nanoseconds since the beginning of that second, and then converts that, using localtime(), to local time on the machine on which you're running, and displays that.

If it shows it as GMT+1 rather than the UTC in which it's recorded, that's because your system is set to use GMT+1.

> This isn’t just idle curiosity.  I’ve written a trace format converter that converts IIS Logs into pcapng files.  IIS logs are recorded with GMT times by default.

So, if the origin of those time stamps isn't 1970-01-01 00:00:00 UTC, then just add to those time stamps an amount in seconds equal to (1970-01-01 00:00:00 UTC - the origin of those time stamps) and record that in the EPB.

> I’ve tried coding for the if_tzone IDB option and setting it to zero (GMT) but it makes no difference.

	1) there's nothing in the pcapng spec that says that if_tzone is a number (or that it is anything in particular);

	2) as a result, neither Wireshark nor any other tool looks at it, so you could set it to the string "Roland the headless Thompson gunner" and it would *still* make no difference.
 
> How do I get Wireshark to convert the time of a GMT trace entry to local time?

Time stamps in pcap and pcapng files are all UTC, so in that sense they're all "GMT", so "[converting] the time of a GMT trace entry to local time" is what Wireshark *always* does.  The only issue here is "*whose* local time?  The local time for the machine in which the trace was done, or the local time for the machine reading the file?"

To get Wireshark to convert them to local time in the time zone your machine is set to, you get Wireshark to convert the times to local time by running Wireshark normally.

To get Wireshark to convert them to local time in some other timezone, you either

	1) set the time zone for your machine to that other time zone and run Wireshark;

	2) run Wireshark with *its* time zone set differently, if that's possible (it's possible in UN*Xes by setting the TZ environment variable for that particular instance of Wireshark to the appropriate value for that zone; I'm not sure how it'd be done on Windows).