Hi, I am writing a dissector in C and have a question in regards to what the differences are between proto_tree_add_item and proto_tree_add_uint. I have experiences Expert Info Warnings of "Trying to fetch an unsigned integer with length --" when using proto_tree_add_item with sizes above a certain amount. Switching this to proto_tree_add_uint results in these warnings disappearing. Under the hood, what is the difference between these two functions? This is the only conversation I've seen on the topic: https://www.wireshark.org/lists/wireshark-dev/201408/msg00296.html [As reference I've including the functions as seen in proto.c]
asked 21 Mar ‘17, 07:50 brownfox edited 21 Mar ‘17, 07:59 |
2 Answers:
Wireshark version? Are you correctly matching the answered 21 Mar '17, 08:15 grahamb ♦ |
The proto_tree_add functions perform the essential function of populating the tree with fields from the data packet at hand. The function which supports the most common operations in one is proto_tree_add_item(). It helps to do the following:
So basically all common functions are wrapped into one. The header field is important here, it defines much of the retrieval and representation of the value. It provides a lot of flexibility for most common situations. But sometimes this is not enough. Sometimes you want more control over the actual value used for this field, which somehow cannot be provided by the functionality of the header field. Then you can resort to proto_tree_add_uint(). This does the same, but for value retrieval, that value is now passed via the function interface. You say you run into trouble when using certain lengths, but not when using proto_tree_add_uint(). This for sure comes from the fact that the header field is no longer used for value retrieval, just highlighting. answered 21 Mar '17, 08:06 Jaap ♦ |
I'm using version 2.3.0.
For example, one of my packets in the capture file contains a 32-byte SHA256 hash.
Here's the corresponding code:
proto_tree_add_uint(proto_tree, hf_proto_config_sha256_hash_frame, tvb, offset, CONFIG_SHA256_HASH_FRAME_LEN, ENC_LITTLE_ENDIAN); offset += CONFIG_SHA256_HASH_FRAME_LEN;
{&hf_proto_config_sha256_hash_frame, {"Config SHA256 Hash This Frame", "proto.config_sha256_hash_frame", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
As a side note, there's an issue with the display in Wireshark using BASE_DEC but I believe that is due to a mistake in the generated capture file not being little endian.
And what's the
hfproto_config_sha256_hash_frame
declaration?Note that it doesn't make sense (to me at least) to show a SHA256 hash as a
FT_UINTXX
value, especially as a uint is limited to 8 bytes. You could use aFT_NONE
type as is done for hashes in SSL, e.g. packet-ssl-utils.c functionssl_dissect_hnd_finished()
withssl_hfs.hs_sha_hash
(declared in packet-ssl.c), passing in 32 for the length.I would actually argue that hashes should be using
FT_BYTES
rather thanFT_NONE
as that's what they are, a sequence of bytes with arbitrary values.My hf_proto_config_sha256_hash_frame is now
{"Config SHA256 Hash This Frame", "proto.config_sha256_hash_frame", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
as you suggested. It works without error so thank you for that. I had initially chosen to display the hash as FT_UINT16 just as a placeholder before seeing how it was done in other protocols - thanks for the reference to SSL.
I think this is the solution though I'll try to fix the other fields first.