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

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


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.

permanent link

answered 27 Jun '15, 21:36

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

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.

permanent link

answered 03 May '15, 16:05

Lekensteyn's gravatar image

Lekensteyn
2.2k3724
accept rate: 30%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×637
×431
×23
×9
×7

question asked: 22 Mar '15, 20:54

question was seen: 3,731 times

last updated: 27 Jun '15, 21:36

p​o​w​e​r​e​d by O​S​Q​A