I'm writing a Wireshark dissector (the C variety, not Lua).
I have time fields which are uint64
, representing the nanoseconds since the unix epoch.
I'd like to print the time in a human-readable format in wireshark.
I looked around for documentation to show how to do this, and only found this time-related function proto_tree_add_time
, at https://anonsvn.wireshark.org/wireshark/trunk-1.6/doc/README.developer.
I end up writing a helper function like this:
static void add_pretty_time(tvbuff_t* tvb, proto_tree* body, unsigned field_offset, int field_id)
{
uint64_t raw_time = tvb_get_letoh64(tvb, field_offset);
nstime_t time;
time.secs = raw_time / 1000000000;
time.nsecs = raw_time % 1000000000;
proto_tree_add_time(body, field_id, tvb, field_offset, 8, &time);
}
Is there any more-elegant way provided by Wireshark to do this? For example FT_UINT64, BASE_DEC in the hf_register_info
array can specify that this field should be parsed as a uint64 and displayed in decimal format. It would be ideal if there was something like FT_EPOCH64, ISO_FORMAT at the hf_register_info
array.
For FT_ABSOLUTE_TIME fields, the encoding specifies the form in which the time stamp is specified, as well as its byte order. The time stamp encodings that are currently supported are found at: https://github.com/wireshark/wireshark/blob/master/doc/README.dissector#L1648
ENC_TIME_SECS_NSECS - 8, 12, or 16 bytes. For 8 bytes, the first 4
bytes are seconds and the next 4 bytes are nanoseconds; for 12
bytes, the first 8 bytes are seconds and the next 4 bytes are
nanoseconds; for 16 bytes, the first 8 bytes are seconds and
the next 8 bytes are nanoseconds. The seconds are seconds
since the UN*X epoch (1970-01-01 00:00:00 UTC). (I.e., a UN*X
struct timespec with a 4-byte or 8-byte time_t or a structure
with an 8-byte time_t and an 8-byte nanoseconds field.)
ENC_TIME_NTP - 8 bytes; the first 4 bytes are seconds since the NTP
epoch (1900-01-01 00:00:00 GMT) and the next 4 bytes are 1/2^32's of
a second since that second. (I.e., a 64-bit count of 1/2^32's of a
second since the NTP epoch, with the upper 32 bits first and the
lower 32 bits second, even when little-endian.)
ENC_TIME_TOD - 8 bytes, as a count of microseconds since the System/3x0
and z/Architecture epoch (1900-01-01 00:00:00 GMT).
ENC_TIME_RTPS - 8 bytes; the first 4 bytes are seconds since the UN*X
epoch and the next 4 bytes are are 1/2^32's of a second since that
second. (I.e., it's the offspring of a mating between UN*X time and
NTP time.) It's used by the Object Management Group's Real-Time
Publish-Subscribe Wire Protocol for the Data Distribution Service.
ENC_TIME_SECS_USECS - 8 bytes; the first 4 bytes are seconds since the
UN*X epoch and the next 4 bytes are microseconds since that
second. (I.e., a UN*X struct timeval with a 4-byte time_t.)
ENC_TIME_SECS - 4 to 8 bytes, representing a value in seconds since
the UN*X epoch.
ENC_TIME_MSECS - 6 to 8 bytes, representing a value in milliseconds
since the UN*X epoch.
ENC_TIME_SECS_NTP - 4 bytes, representing a count of seconds since
the NTP epoch. (I.e., seconds since the NTP epoch.)
ENC_TIME_RFC_3971 - 8 bytes, representing a count of 1/64ths of a
second since the UN*X epoch; see section 5.3.1 "Timestamp Option"
in RFC 3971.
ENC_TIME_MSEC_NTP - 4-8 bytes, representing a count of milliseconds since
the NTP epoch. (I.e., milliseconds since the NTP epoch.)
None of them correspond to uint64 nanoseconds past epoch.
The add_pretty_time
helper written in the question is the right approach, since we are forced to use proto_tree_add_time
instead of using the standard proto_tree_add_item
with the help of built-in encodings.
This still requires that the hf_register_info
array has the correct values: i.e. we must use a time-based field type, and a time-based display format. Example of the former: FT_ABSOLUTE_TIME. Example of the latter: ABSOLUTE_TIME_UTC. Where to find a list of each: https://github.com/boundary/wireshark/blob/master/epan/proto.c#L4742 and https://github.com/wireshark/wireshark/blob/master/doc/README.dissector#L147 respectively.