1 | initial version |
For the header protocol, you're creating the DissectorTable but you're not saving the return value or doing anything with it. Your dissector table also appears to be based on a port number, which is a 16-bit value, so you should explicitly specify that as the type. If it is in fact a port number, then I find myself questioning why there are 2 different protocols involved here at all, but I'll assume there's a good reason you're doing this. Besides the problems with the subdissector table:
<protocol>.<field>
naming convention.ProtoField.uint
function. Since both fields of the header are 1 byte, you should be using ProtoField.uint8
instead.As for the subdissector, apart from the same problems with filter names and ProtoField.uint
, which should be ProtoField.uint32
in this case, there's nothing else that needs to change.
Below are some modified code samples that should help.
First, the header: There are at least 2 ways to call the subdissector and I've illustrated both. You can even try out either method by changing the "Subdissection Method" preference.
myHeaderProtocol = Proto.new("myHeader", "My Custom Header Protocol") -- Define protocol fields local pf = { headerId = ProtoField.uint8("myHeader.headerId", "headerId", base.DEC), numMessages = ProtoField.uint8("myHeader.numMessages", "numMessages", base.DEC) } myHeaderProtocol.fields = pf local myCustomTable = DissectorTable.new("MyCustomTable", "MyCustomTable", ftypes.UINT16, base.DEC) -- Preferences local METHOD_TRY = 1 local METHOD_CALL = 2 local methods_table = { {1, "Try", METHOD_TRY}, {2, "Call", METHOD_CALL} } local default_prefs = { subdissectionMethod = METHOD_TRY } myHeaderProtocol.prefs.subdissection_method = Pref.enum("Subdissection Method", default_prefs.subdissectionMethod, "The subdissection method as \"try\" or \"call\".", methods_table, false ) function myHeaderProtocol.dissector(buffer, pinfo, tree) pinfo.cols.protocol = myHeaderProtocol.name local subtree = tree:add(myHeaderProtocol,buffer(), "Header Tree") subtree:add(pf.headerId, buffer(0, 1)) subtree:add(pf.numMessages, buffer(1, 1)) local numMessages = buffer(1, 1):uint() local offset = 2 if myHeaderProtocol.prefs.subdissection_method == METHOD_TRY then --[[ This method will use dissectortable:try(). Note that we must still check if there's a subdissector registered; otherwise the data dissector will be called for us automatically if there isn't a registered dissector, and we don't want that. --]] local port if myCustomTable:get_dissector(pinfo.src_port) ~= nil then port = pinfo.src_port --pinfo.cols.info:append(" Source Port Match") elseif myCustomTable:get_dissector(pinfo.dst_port) ~= nil then port = pinfo.dst_port --pinfo.cols.info:append(" Destination Port Match") else return end while numMessages > 0 do myCustomTable:try(port, buffer(offset, 4):tvb(), pinfo, tree) offset = offset + 4 numMessages = numMessages - 1 end elseif myHeaderProtocol.prefs.subdissection_method == METHOD_CALL then --[[ This method will call the subdissector directly if a handle is successfully found in the subdissector table. --]] local subdissector_handle = myCustomTable:get_dissector(pinfo.src_port) if subdissector_handle == nil then subdissector_handle = myCustomTable:get_dissector(pinfo.dst_port) end if subdissector_handle ~= nil then while numMessages > 0 do subdissector_handle:call(buffer(offset, 4):tvb(), pinfo, tree) offset = offset + 4 numMessages = numMessages - 1 end end end end tcp_table = DissectorTable.get("tcp.port") tcp_table:add(5678, myHeaderProtocol)
And the subdissector:
mySubDissector = Proto.new("mySubDissector", "My Sub Dissector") local pf = { myMessage = ProtoField.uint32("mySubDissector.Message", "Message", base.HEX) } mySubDissector.fields = pf function mySubDissector.init() DissectorTable.get("MyCustomTable"):add(5678, mySubDissector) end function mySubDissector.dissector(buffer, pinfo, tree) pinfo.cols.protocol = mySubDissector.name local subtree = tree:add(mySubDissector, buffer(), "Message SubTree") subtree:add(pf.myMessage, buffer(0, 4)) end