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

Adding tree items according to bitmask

0

I have got a working dissector up and running using Lua, and it is working well. It does everything I need it to do and I am getting the information I need - no problems. However, I would like to make a rather large improvement. Currently, our packets are sent with a 24-bit mask in each header, informing the client which fields in the packet are valid. If the field is not valid, it is normally just padded with nulls (0x00).

Currently, I am adding all fields to my tree, without checking the mask, so I get a lot of useless tree items, and I have to manually check the flags to see which fields with 0s are valid or invalid...

My question is: How do I only add items to the tree if the mask in the header BITWISE ANDs with the field mask?

e.g. currently: fds.myfield = ProtoField.new("My field", "my_proto.my_field", ftypes.UINT32, nil, base.DEC)

then in my dissector: twig:add_le(fds.myfield, buff(28,4))

Do I have to wrap an if statement around each and every tree:add?? *gasp

asked 22 Mar '15, 20:54

Fidelius's gravatar image

Fidelius
21216
accept rate: 0%

edited 22 Mar '15, 20:56


2 Answers:

1

Do I have to wrap an if statement around each and every tree:add??

Nope, you do not have to wrap each and every tree:add call (or in your case, tree:add_le).

Really, a statement like tree:add(foo) is Lua short-hand for TreeItem.add(tree, foo), which is short-hand for "in a table named 'TreeItem', get the entry of index 'add', and call its value as a function, passing it the arguments 'tree' and 'foo'".

So what you can do is create a proxy function that will decide whether to actually call TreeItem.add() or not, based on your bit mask value. For example:

local myproto = Proto("myproto","My Protocol")

– my protocol's fields local fds = { bitmask = { – this field doesn't have a match entry, since it's the bitmask – field in the packet that decides matches pfield = ProtoField.new("The bitmask for fields", "my_proto.bitmask", ftypes.UINT24, nil, base.HEX) } myfield = { match = 0x000001, – the bit in the bitmask that represents this field pfield = ProtoField.new("My field", "my_proto.my_field", ftypes.UINT32, nil, base.DEC) }, myotherfield = { match = 0x000010, pfield = ProtoField.new("My other field", "my_proto.my_other_field", ftypes.UINT16, nil, base.DEC) }, – more fields here }

– a flat table to hold the above but only as ProtoFields local flat_fds = {} – fill that flat table for _,v in pairs(fds) do flat_fds[#flat_fds + 1] = v.pfield end – register all the fields using the flat table myproto.fields = flat_fds

– a proxy function that decides when to add a ProtField to the tree or not local function addMaskedField(tree, mask, field, …) – only add it if it's set in the passed-in mask if bit.band(mask, field.match) == field.match then TreeItem.add_le(tree, field.pfield, …) end end

function myproto.dissector(buf,pinfo,root) – add my protocol to the tree root local tree = root:add(myproto, buf(0, buf:len()))

-- add the bitmask to the tree, at byte 0 for 3 bytes
tree:add_le(fds.bitmask.pfield, buf(0, 3))

-- now get the 24-bit value into Lua so we can use it
local mask = buf(0, 3):le_uint()

addMaskedField(tree, mask, fds.myfield, buf(3, 4))
addMaskedField(tree, mask, fds.myotherfield, buf(7, 2))

-- etc., etc.

end

Note that the above is just an example - I haven’t tried it or even verified it was well-formed code. But it should give you the general idea.

answered 27 Jun ‘15, 21:36

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

0

If you want to document each dissected byte, even if it is not used, then you can use the ti.set_hidden() function on a TreeItem to hide it (you cannot undo this!). Note that if the fields are completely rubbish, then you might want to introduce a dummy field for it such as my_proto.unused).

Alternatively, do not add the field at all since it is unlikely of interest to the user. Yes, you need to check this yourself, but some structured code should help here.

answered 03 May '15, 16:05

Lekensteyn's gravatar image

Lekensteyn
2.2k3724
accept rate: 30%