How to save in a variable a specific value from masked bytes?

The variable YEAR, has got an offset of 2000. This means, that I need to add 2000 to the taken value. Here I create my "ProtoField":

local Year_proto = ProtoField.uint16("Variable_Year", "This is the transmitted year", base.DEC, nil)


Before adding it to the shown values of my Wireshark-Parser, I need to save the LITTLE-ENDIAN 7 bits long number. The bit mask should be 0x07f0 = 0000 0111 1111 0000 - so the only intersting bits here are the "1". The start byte is the 77 and the information is found in two bytes (buffer(77,2).

Can you please tell me how can I save the mentioned LITTLE-ENDIAN 7 bits number? Let's say that the name of the saved number is saved in "year_test" and the variable "year" is the corrected value:

offset=2000.0
year=year_test+offset //for example year_test=0x15=21 --> 2021


Afterwards I would list the corrected year value as follows:

subtree:add(Year_proto, year)


edit retag close merge delete

What do you mean by LITTLE-ENDIAN 7 bits number? You mentioned that, "The bit mask should be 0x07f0 = 0000 0111 1111 0000", so assuming bits are numbered from left-to-right as bits 15-0, does that mean that only bits 11-4 are relevant but that bit 11 is the least-significant bit and bit 4 is the most significant bit?

( 2021-08-23 14:39:52 +0000 )edit

Let's say that the two bytes are 0x50 and 0x41. 0x50 is byte #77 and 0x41 is byte #78. As is LITTLE-ENDIAN, the bites more to the left from #78 are the MSB. So that: 0x4150=0100 0001 0101 000, with the mask 0x7F0 I just care the following 7 bits: 001 0101 = 0x15 = 21 (to that 21 decimal I need to add 2000). I hope it answers your question, many thanks again for your help! :)

( 2021-08-24 08:14:49 +0000 )edit

OK, so the bitfield is split across a multi-byte field, which is transmitted in Little-Endian format but the 7 bits that comprise the field itself are specified in the "normal" order with the most-significant bit on the left and the least-significant bit on the right.

( 2021-08-24 15:37:29 +0000 )edit

Sort by » oldest newest most voted

Ideally you could accomplish this as follows:

local Year_proto = ProtoField.uint16("Variable_Year", "This is the transmitted year", base.DEC, nil, 0x07f0)

subtree:add_le(Year_proto, buffer(77, 2), 2000 + bit.band(bit.rshift(buffer(77, 2):le_uint(), 4), 0x7f))


That would highlight the 7 bits of the multi-byte field while still being able to specify the exact value to display, but unfortunately Wireshark is applying the 0x07f0 mask to the specified value, which I believe is a bug, after all the user is explicitly indicating the value to be displayed. In any case, because of this problem, you have to declare Year_proto as follows:

local Year_proto = ProtoField.uint16("Variable_Year", "This is the transmitted year", base.DEC)


The down-side here is that the relevant bits of the multi-byte field will not be shown in the tree as they otherwise would be.

For more information on the Lua BitOp Module, refer to http://bitop.luajit.org/api.html. This is necessary because we're still stuck on Lua 5.2, which doesn't support native bitops, which are supported by Lua 5.3.

See also some related Lua 5.2 -> 5.3 discussions on the wireshark-dev mailing list:

more

Many thanks for your help, it works! Even if that the exactly selected bits are not shown, the solution solved my problem.

( 2021-08-25 08:02:49 +0000 )edit