1 | initial version |
The MongoDB Lua dissector you provided a link to doesn't behave the way your code sample does. Rather, the header.lua file simply contains header-specific dissection of the MongoDB protocol, whereas it appears you're looking to stack 2 separate protocols, those being (1) the "base" or "parent" dissector, and (2), one of a number of different "child" dissectors. Assuming that's the case, then you'll need the parent dissector to register for all known ports and then call the appropriate child dissector based on the specific port number, either through a static table lookup or through a registered table. For example:
1. Static Table:
Parent:
local data_dissector = Dissector.get("data")
local child_dissector_table = {}
local udp_ports = {PORT1, PORT2, ... PORTN}
local parent = Proto("Parent", "Parent Protocol")
function parent.init()
child_dissector_table[PORT1] = Dissector.get("child1")
child_dissector_table[PORT2] = Dissector.get("child2")
...
child_dissector_table[PORTN] = Dissector.get("childN")
end
function parent.dissector(tvbuf, pinfo, tree)
-- Dissect parent stuff here.
-- Hand off remainder to child, like so:
local tvb_sub = tvbuf:range(offset_to_child_data, length_of_child_data):tvb()
if child_dissector_table[pinfo.src_port] ~= nil then
child_dissector_table[pinfo.src_port]:call(tvb_sub, pinfo, tree)
elseif child_dissector_table[pinfo.dst_port] ~= nil then
child_dissector_table[pinfo.dst_port]:call(tvb_sub, pinfo, tree)
else
data_dissector:call(tvb_sub, pinfo, tree)
end
end
local function register_udp_ports(ports)
local udp_port_table = DissectorTable.get("udp.port")
for k, v in next, ports do
udp_port_table:add(v, parent)
end
end
register_udp_ports(udp_ports)
2. Child Registration:
Parent:
local data_dissector = Dissector.get("data")
local port_table = DissectorTable.new("parent.port", "parent.port", ftypes.UINT16, base.DEC)
local udp_ports = {PORT1, PORT2, ... PORTN}
local parent = Proto("Parent", "Parent Protocol")
function parent.dissector(tvbuf, pinfo, tree)
-- Dissect parent stuff here.
-- Hand off remainder to child, like so:
local tvb_sub = tvbuf:range(offset_to_child_data, length_of_child_data):tvb()
local child
child = port_table.get_dissector(pinfo.src_port)
if child ~= nil then
child:call(tvb_sub, pinfo, tree)
else
child = port_table.get_dissector(pinfo.dst_port)
if child ~= nil then
child:call(tvb_sub, pinfo, tree)
else
data_dissector:call(tvb_sub, pinfo, tree)
end
end
end
local function register_udp_ports(ports)
local udp_port_table = DissectorTable.get("udp.port")
for k, v in next, ports do
udp_port_table:add(v, parent)
end
end
register_udp_ports(udp_ports)
Child1:
DissectorTable.get("parent.port"):add(PORT1, child1)
Child2:
DissectorTable.get("parent.port"):add(PORT2, child2)
...
ChildN:
DissectorTable.get("parent.port"):add(PORTN, childN)
DISCLAIMER: This is all pseudocode of course, but this is the general idea.