This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Bytes Accessors in wireshark in c

1

I've to access 4 bytes of data from tvb (tvbuff_t *) passed in dissect-protocolname() function. I used 2 functions:
1. data = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN); 2. proto_tree_add_item(foo_tree, hf_foo_data, tvb, offset, 4, ENC_BIG_ENDIAN); the returned value from the first function i'm displaying it using

proto_tree_add_uint(foo_tree, hf_foo_data1, tvb, offset, 4, data);

Both shows the different result in second display pane of wireshark. I'm not changing the offset too.
since offset does not change in both and both are accessing 4 bytes of data . Then Why do both show different result ?
I need 4 bytes of data in a variable to manipulate which first function is doing but returned value is not correct why ??
second function shows the correct decimal value of 4 bytes in display pane of wireshark whereas first does not, why ?
Is there any other function to access 4 bytes of data from tvb buffer ?

Thanks.

asked 09 Jun '15, 01:42

Sammee%20Sharma's gravatar image

Sammee Sharma
314610
accept rate: 100%

edited 09 Jun '15, 01:49


One Answer:

2

data = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN);

Note that, in that statement, offset is the offset, in bits, not bytes, from the beginning of the tvbuff.

proto_tree_add_item(foo_tree, hf_foo_data, tvb, offset, 4, ENC_BIG_ENDIAN);

However, in that statement, offset is the offset in bytes from the beginning of the tvbuff.

proto_tree_add_uint(foo_tree, hf_foo_data1, tvb, offset, 4, data);

And it's the offset in bytes from the beginning of the tvbuff in that call as well.

So, if you want to use tvb_get_bits32(), you'll have to convert offset to an offset in bits, i.e.

data = tvb_get_bits32(tvb, offset*8, 32, ENC_BIG_ENDIAN);

However:

Is there any other function to access 4 bytes of data from tvb buffer ?

Yes - tvb_get_ntohl(), i.e.

data = tvb_get_ntohl(tvb, offset);

(No, the name doesn't have "be", for "big-endian", or "32" in it, but, well, BSD, UN*X history, ntohl(), blah blah blah.)

Unless you're dealing with values not aligned on byte boundaries, i.e. bit-packed values, you don't need to use the tvb_get_bits routines, you can just use routines such as tvb_get_ntohs(), tvb_get_ntohl(), tvb_get_letohs(), tvb_get_letohl(), etc.. Most protocols have byte-aligned values, so the tvb_get_bits routines are less often used than the routines I mentioned.

answered 09 Jun '15, 02:17

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

edited 09 Jun '15, 09:58

Thanks, @GuyHarris , it worked. The offset in first function is in bits. so it should be converted to bytes in order to access the same value. just one correction i want to make in your answer is that the offset should be multiplied by 8 not 32. Thanks for the quick answer.

(09 Jun '15, 02:36) Sammee Sharma

And one more thing, i didn't get the function
data = tvb_get_ntohl(tvb, offset);
Can you explain a bit about this function like how it will be used to access the 4 bytes.
Thanks.

(09 Jun '15, 02:40) Sammee Sharma
1

The ntohl is an abbreviation for "network to host long", i.e. convert a long from the network representation (which is always big-endian) to host representation. There are similar functions for converting from host to network representations and for many different data types. See epan/tvbuff.h for the full list.

(09 Jun '15, 02:50) grahamb ♦
1

...which means that tvb_get_ntohl() is all you need to fetch a 32-bit big-endian quantity that's aligned on a byte boundary; there's no advantage to using tvb_get_bits32() unless you're dealing with data that's not aligned on byte boundaries.

(09 Jun '15, 09:55) Guy Harris ♦♦
1

Example fixed.

(09 Jun '15, 09:55) Guy Harris ♦♦