Wireshark dissect information but not display in the dissect

asked 2021-04-05 15:17:59 +0000

gary.barnes.az gravatar image

updated 2021-04-05 22:39:53 +0000

This may have been explained elsewhere, but not finding it. I have to work within the confines of wireshark 2.4.x. So I defined some values for data as so.

    { &hf_td_timestamp,
        { "Timestamp", "td.timestamp",
            FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL
        } },
    { &hf_td_timestamp_sec,
        { "Timestamp Seconds", "td.timestamp.sec",
            FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL
        } },
    { &hf_td_timestamp_nsec,
        { "Timestamp nSeconds", "td.timestamp.nsec",
            FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
        } },

and the data for one of them gets stored and added to the dissect tree as so

    proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC);

I only want to display the one line item and not all three. The information for the other two are of course derived from the same bytes. Ultimately I would like to have the other fields available for adding to the columns and not the detail dissect. The timestamp within my payload is 12 bytes, 4 bytes padding then the 8 bytes timestamp as understood by wireshark 2.4.x.
That is part 1. Once I can establish the storing of the information I will of course add the other two as a single line into the detail as seconds.nanoseconds. The values just need to be stored separately so that the data can be parsed in an Excel csv file. Excel cannot handle the precision of the nanoseconds in decimal format, that is why they must be separate.
Part 2: store some metadata that is calculated from known fields. Specifically the delta between these timestamps. Wireshark can give the delta of the recorded timestamp but not the timestamp within the payload. So basically store the delta between the payload timestamp with the same port information as the last packet from the same port. Once I can get past part 1 then I should be able to accomplish part 2.

So, is there a function that will parse the tvb and only store the value as opposed to store to be displayed?

edit retag flag offensive close merge delete

Comments

Are the three time fields always present in your protocol as actual bytes or is one or more of them inferred from the other fields?

grahamb gravatar imagegrahamb ( 2021-04-05 15:59:43 +0000 )edit

Within the payload of the udp packet there is a single stream of 8 bytes that make up the timestamp. The bytes I would presume would be read 3 times once for the complete timestamp, once to get just the seconds and then once more for the nanoseconds. Timestamp as defined by wireshark is 4 bytes and 4 bytes, seconds and nanoseconds respectively.

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-05 16:22:55 +0000 )edit

The second part of my work is to calculate some values from the timestamps as deltas from specific types of data and then store those values as new fields that can be used in the same fashion as the built in timestamp delta. So, what was the delta between this packet and the last according to its timestamp (not the timestamp wireshark recorded). What was the delta between this type 1 package and the last type 1 packet and so on.

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-05 16:27:26 +0000 )edit

Can you first clarify the time format? You wrote this:

proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC);

... but if secs is 64 bits and nsecs is 32 bits, then shouldn't this be:

proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 12, ENC_TIME_TIMESPEC);

(Also, maybe use ENC_TIME_SECS_NSECS instead since ENC_TIME_TIMESPEC is no longer even mentioned in the README.dissector file documentation.)


Well, assuming that's the case, then the first 8 bytes is seconds and the next 4 bytes is nanoseconds, so you'd grab the values using the appropriate tvb_get_*() functions (Ref: . For example:

Big-Endian:

secs = tvb_get_ntoh64(tvb, offset);
nsecs = tvb_get_ntohl(tvb, offset + 8);

Little-Endian:

secs = tvb_get_letoh64(tvb, offset);
nsecs = tvb_get_letohl(tvb, offset + 8);
cmaynard gravatar imagecmaynard ( 2021-04-05 17:07:19 +0000 )edit

Wireshark 2.4.x ENC_TIME_TIMESPEC is only 8 bytes and will generate an error if larger than 8 bytes. Even though the value stored from the 8 bytes is then internally stored as 12 bytes (guessing future enhancement). My payload is padded with 4 bytes for if/when wireshark allows 12 byte timestamp to deal with 2038 issues with time.
I understand the how to extract the data from the stream. My question is how do I then store the data into the hf_td_timestamp_sec and hf_td_timestamp_nsec without having it displayed as part of the detail dissect? When proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC); is called with the bytes 5fabb4843102fe07 the result is the timestamp is recorded in td.timestamp and then in the dissect detail this is displayed
Timestamp: Nov 11, 2020 02:53:08.822279687 US Mountain Standard Time.

If I do proto_tree_add_item(tu_tree, hf_tu_timestamp_sec, tvb, offset, 8 ...(more)

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-05 17:57:18 +0000 )edit

If you don't want the values shown in the tree, you can use PROTO_ITEM_SET_HIDDEN() after you add them. That way they won't be shown (by default), but you can still filter on them.

But I still don't understand your time format. If it's only 8 bytes, then according to the 2.4 documentation for ENC_TIME_TIMESPEC, the first 4 bytes are seconds since the UN*X epoch and the next 4 bytes are nanoseconds since that second. Why do you then declare hf_td_timestamp_sec as a FT_UINT64?

And I don't understand this, "If I doproto_tree_add_item(tu_tree, hf_tu_timestamp_sec, tvb, offset, 8, ENC_BIG_ENDIAN);backing up 4 bytes for the padding ..." What do you mean by backing up 4 bytes? Why wouldn't you just use the following?

The 4 bytes representing seconds:
PROTO_ITEM_SET_HIDDEN(proto_tree_add_item(tu_tree, hf_tu_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN));

And the 4 bytes representing nanoseconds:
PROTO_ITEM_SET_HIDDEN(proto_tree_add_item ...(more)

cmaynard gravatar imagecmaynard ( 2021-04-05 19:06:04 +0000 )edit

Another thing that's unclear to me is why you don't want to display the seconds and nanoseconds in the first place. As the documentation for PROTO_ITEM_SET_HIDDEN() indicates:

NOTE that creating hidden fields is actually quite a bad idea from a UI design
perspective because the user (someone who did not write nor has ever seen the
code) has no way of knowing that hidden fields are there to be filtered on
thus defeating the whole purpose of putting them there.  A Better Way might
be to add the fields (that might otherwise be hidden) to a subtree where they
won't be seen unless the user opens the subtree--but they can be found if the
user wants.

So why not do something like this instead?

ti = proto_tree_add_item(td_tree, hf_td_timestamp, tvb, offset, 8, ENC_TIME_TIMESPEC);
ts_tree = proto_item_add_subtree(ti, ett_timestamp);

proto_tree_add_item(ts_tree, hf_td_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(ts_tree, hf_td_timestamp_nsec, tvb ...
(more)
cmaynard gravatar imagecmaynard ( 2021-04-05 19:21:23 +0000 )edit

And I don't understand this, "If I do proto_tree_add_item(tu_tree, hf_tu_timestamp_sec, tvb, offset, 8, ENC_BIG_ENDIAN); backing up 4 bytes for the padding ..." What do you mean by backing up 4 bytes? Why wouldn't you just use the following?

The 4 bytes representing seconds:

PROTO_ITEM_SET_HIDDEN(proto_tree_add_item(tu_tree, hf_tu_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN));

And the 4 bytes representing nanoseconds:

PROTO_ITEM_SET_HIDDEN(proto_tree_add_item(tu_tree, hf_tu_timestamp_nsec, tvb, offset + 4, 4, ENC_BIG_ENDIAN));

Wireshark only deals with an 8 byte timestamp 4 seconds, 4 nanoseconds. The software that wireshark is capturing is a 12 byte timestamp, 8 bytes seconds, 4 bytes nanoseconds. As far as wireshark is concerned there is 4 bytes of 00 (or padding).

Now the reason for not displaying is the data is useless in the context of the detail, it adds nothing to the display. The data is NEEDED for post processing and only useful as a column to be exported.

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-06 14:45:14 +0000 )edit

PROTO_ITEM_SET_HIDDEN() displayed the lines 3 times each. Not very hidden.

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-07 15:45:47 +0000 )edit

The issue is likely to be in your code, it's used extensively in the codebase, e.g. packet-tcp.c where among other things it's used to add a field tcp.port twice, once for the source port and again for the destination so that a filter of tcp.port == xxxx can be used to search both tcp.srcport and tcp.dstport fields. The tcp.port items are set to hidden as the tree is already displaying the individual source and destination ports.

grahamb gravatar imagegrahamb ( 2021-04-07 16:33:26 +0000 )edit

Edit -> Preferences -> Protocols -> Display hidden protocol items

This is also why I prefer the subtree since it groups the fields more logically and also doesn't show them if the subtree isn't expanded.

cmaynard gravatar imagecmaynard ( 2021-04-07 17:07:58 +0000 )edit

unchecked for Display hidden protocol items

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-07 22:14:14 +0000 )edit

PROTO_ITEM_SET_HIDDEN(proto_tree_add_item(tu_tree, hf_tu_timestamp_nsec, tvb, offset + 4, 4, ENC_BIG_ENDIAN));
Displays the line 3 times, yet
proto_tree_add_item(tu_tree, hf_tu_timestamp_nsec, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
displays only once.

gary.barnes.az gravatar imagegary.barnes.az ( 2021-04-07 22:15:25 +0000 )edit