# Chaining two custom dissectors Lua - no such dissector table

I'm attempting to create two Lua dissector files to read a TCP message header and subsequent messages. I would like for the main lua dissector to call a message dissector multiple times based on the number of messages present. I can't seem to get the two to work together without a "no such dissector table" when attempting to reference the other file.

I found the following link, but I'm having trouble determining what goes where in the code. I tried various combinations unsuccessfully, but I'm new to Lua Dissectors. I haven't had much success. https://stackoverflow.com/questions/5...

Any guidance is greatly appreciated.

myHeaderProtocol = Proto("customHeader", "customHeader")
numMessages = ProtoField.uint("numMessages", "numMessages", base.DEC)

length = buffer:len();

--How can I make sure mySubDissector is registered
--And recognized here?
mySubDissector(buffer(2,4):tvb(), pinfo, tree)
mySubDissector(buffer(6,4):tvb(), pinfo, tree)
--Two messages shown for simplicity
end

tcp_table = DissectorTable.get("tcp.port")

--Where should this go?
DissectorTable.new("MyCustomTable")


subDissector.lua

mySubDissector = Proto("customHeader", "customHeader")
myMessage = ProtoField.uint("myMessage","myMessage", base.HEX)
mySubDissector.fields = {myMessage}

--Where should this go, or how should I do the equivalent?
function mySubDissector.init()
end
function mySubDissector.dissector(buffer, pinfo, tree)
length = buffer:len();
pinfo.cols.protocol = mySubDissector.name

local subtree = tree:add(mySubDissector,buffer(), "Message SubTree")
end

--I'm not sure about what is below

edit retag close merge delete

Sort by » oldest newest most voted

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:

• The filter names aren't following the <protocol>.<field> naming convention.
• There is no 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 = {
}

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
}
default_prefs.subdissectionMethod,
"The subdissection method as \"try\" or \"call\".",
methods_table,
false
)

local numMessages = buffer(1, 1):uint()
local offset = 2

--[[
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
--[[
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")



And the ...

more

Thank you for your generous example. I'm still working through it to learn some of the intricacies, but it has helped me a tremendous amount so far.

( 2021-10-21 19:37:24 +0000 )edit

Since you indicated that you're new to Lua dissectors, you might want to also have a look at the sample foo.lua file I published on the Wireshark-dev mailing list recently. It closely matches the "Foo" C dissector illustrated in the Wireshark Developer Guide. It's heavily documented, which should make it easier to follow along and may help you with writing your own Lua dissectors, although this foo.lua example dissector is carried over UDP whereas your dissector is carried over TCP, so some additional work is required on your part.

In particular, you're missing TCP reassembly functionality, which should not be overlooked. There are some Lua TCP-based dissectors available that should help you with that though. See the TCP reassembly section of the Lua Dissectors wiki page as well as A dissector tutorial with TCP-reassembly section of the Examples wiki page. I also recently added a ...(more)

( 2021-10-21 21:20:04 +0000 )edit

Thanks. I tried to download and review foo.lua. The Link on Wireshark-dev shows that it points to a foo.lua file, but the actual hyperlink redirects to a .bin file below.

https://www.wireshark.org/lists/wires...

Was there another link to the text of foo.lua? Its possible the link is broken or I might not know how to access it.

( 2021-10-22 00:55:55 +0000 )edit

I don't know why the file downloads as a .bin file, but just rename it to foo.lua and open it in your editor to view it.

( 2021-10-22 05:10:05 +0000 )edit

You can also download it from the MARC Archives. My post is here and the foo.lua attachment can be found towards the bottom.

The Mail Archive is yet another source; my post is here and direct link to the foo.lua attachment is here. In either of these cases, no file renaming is necessary.

( 2021-10-22 05:43:00 +0000 )edit