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

[Lua] bytes consumed during dissection

0

Hi,

I'm new to Lua dissector and experimenting with Lua. I need some help understand how can a sub-protocol dissector return bytes consumed during its decoding to its caller dissector.

Example:

MYPROTO = Proto ("myproto", "My Simple Protocol")
local myproto_dt = DissectorTable.new ("myproto.msgid", "MYPROTO")

local f = MYPROTO.fields f.var1 = ProtoField.uint16 ("myproto.var1", "var1")
f.msgid = ProtoField.uint16 ("myproto.msgid", "Message Id") f.var2 = ProtoField.uint16 ("myproto.var1", "var1")

function MYPROTO.dissector (buffer, pinfo, tree) subtree:add (f.var1, buffer(offset, 2)) offset = offset + 2

local msgid = buffer (offset, 2)
local mi = subtree:add (f.msgid, msgid)
offset = offset + 2

--This is calling a nested/chain dissectors which has a variable length filed.
--How can this function be made to return bytes it consumed while decoding the
--variable length field?
myproto_dt:try (msgid:uint(), buffer(offset):tvb(), pinfo, subtree)

--This step is missing
offset = offset + offset_consumed

subtree:add (f.var2, buffer(offset, 2))
offset = offset + 2

end

asked 01 Jul ‘12, 12:22

nrk1983's gravatar image

nrk1983
1113
accept rate: 0%

edited 01 Jul ‘12, 12:28


One Answer:

2

Ideally, the sub-dissector would just return the number of consumed bytes, and you'd just check the return value, but DissectorTable.try() does not return any values. Neither does Dissector.call(). I suggest filing an enhancement request at http://bugs.wireshark.org to get those functions to return the rval of the called dissector.

A workaround is to declare a global variable, call DissectorTable.try() (whose sub-dissector would set the variable to the number of consumed bytes), and then check the value of the variable for the result. This is a bit ugly due to the usage of globals.

foo.rval = -1
myproto_dt:try (...) -- subdissector sets foo.rval
print('number of consumed bytes', foo.rval)
foo.rval = nil -- cleanup

You can avoid globals in this particular case by using pinfo.private, which contains a string hash table (of string keys and string values). This is only slightly less ugly than globals, but when life gives you lemons...

pinfo.private.rval = -1
myproto_dt:try (...) -- subdissector sets pinfo.private.rval
print('number of consumed bytes', pinfo.private.rval) 
pinfo.private.rval = nil -- cleanup

Note the value from a pinfo.private lookup is a string...use tonumber() to convert the string to a number if necessary.

answered 01 Jul '12, 13:55

helloworld's gravatar image

helloworld
3.1k42041
accept rate: 28%

Thanks a lot.. pinfo.private.rval solution worked..

(02 Jul '12, 10:29) nrk1983