Wireshark-dev: Re: [Wireshark-dev] lua decoder accessing info from layers above

From: Martin Kaiser <lists@xxxxxxxxx>
Date: Wed, 21 Oct 2020 22:42:53 +0200
Thus wrote Maynard, Chris via Wireshark-dev (wireshark-dev@xxxxxxxxxxxxx):

> > From: Wireshark-dev <wireshark-dev-bounces@xxxxxxxxxxxxx> On Behalf Of chuck c
> > Sent: Wednesday, October 14, 2020 10:33 AM
> > To: Developer support list for Wireshark <wireshark-dev@xxxxxxxxxxxxx>
> > Subject: Re: [Wireshark-dev] lua decoder accessing info from layers above

> > local p_foo = Proto.new("foo", "foo")
> > local f_frame_protocols = Field.new("frame.protocols")

> > function p_foo.dissector(buf, pinfo, tree)
> >    print(pinfo.number, "Protocols: " .. (f_frame_protocols() and f_frame_protocols().value or "Unknown"))
> > --    print(pinfo.number, f_frame_protocols().value)
> > end

> > register_postdissector(p_foo)

> > Script above prints to the Lua console.
> > What was the situation where it doesn't work?

> It works as a post-dissector, but not as a registered dissector.  For example, replace:

>     register_postdissector(p_foo)

> with something like so, replacing the port number with whatever you can easily test with:

>     local udp_table = DissectorTable.get("udp.port")
>     udp_table:add(33333, p_foo)

> Yet you can access and print other frame fields such as "frame.len" and "frame.cap_len".

frame.protocols is added to the tree by the frame dissector after all
upper-layer protocols were running, i.e. after the big try-catch block
in packet-frame.c and before the try-catch block for postdissectors.
This makes sense to me. We have to dissect the packet completely before
we can compile the list of all protocols that got to see the packet.

Thus, by the time p_foo.dissector runs, there's no frame.protocols field in
the tree yet. f_frame_protocols() is nil. Field__call() calls
proto_get_finfo_ptr_array() which doesn't find a frame.protocols entry
in the tree.

This is different for frame.len and frame.cap_len. These fields are
added to the tree before packet-frame.c passes control to other
dissectors.

When postdissectors are called, frame.protocols is also present in the
tree and visible to postdissectors.

Best regards,
Martin