0
votes

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.

1
I've looked around a bit and I have reason to believe that nanoseconds since epoch aren't natively supported in Wireshark. I'll answer myself here...Anton

1 Answers

0
votes

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.