Discussion:
Lua post-dissector not getting field values
Beth
2009-09-17 13:42:35 UTC
Permalink
What am I missing? The field extractor always returns nil, so the seq value
is always -1. The frame number is correct, however, so I know the code is
being executed. In my listener code I used the same field extractor for the
802.15.4 seq number and it worked fine there.

-- I define my "protocol":
local post154_proto = Proto("post802154", "Extra analysis of 802.15.4
fields", "Post802514");

-- I define 2 fields:
local F_frmNum = ProtoField.framenum("post802154.frmNum", "Wireshark frame
number", base.DEC)
local F_seqNum = ProtoField.int8("post802154.seqNum", "802.15.4 seq
number", base.DEC)

-- I add the field to my protocol:
post154_proto.fields = { F_frmNum, F_seqNum }

-- I declare a field extractor:
local seq_no = Field.new("ieee802.15.4.seq_no")

-- I register my postdissector:
register_postdissector(post154_proto)

-- And I create a dissector function that uses the field extractor to add an
item to the display tree:

function post154_proto.dissector(tvbuffer, pinfo, treeitem)

-- Get frame number from pinfo
local fnum = pinfo.number

-- Get value from field extractor (-1 if field is nil)
local seq = -1
if seq_no() then seq=seq_no().value end

-- Add our extra protocol subtree
local subtreeitem = treeitem:add(post154_proto, tvbuffer)

-- Display the field value
subtreeitem:add(F_frmNum, tvbuffer(0,0), fnum)
subtreeitem:add(F_seqNum, tvbuffer(0,0), seq)

end
Beth
2009-09-22 22:09:14 UTC
Permalink
I've been digging into the wslua code, and the wireshark dissection source
as well, trying to figure out why perfectly a good header field in wireshark
is not getting read by my Lua script's field extractors. Here is what I
have figured out so far (some of this will be known to most of you):

First of all, I have concluded that my Lua postdissector code is getting
called just fine. However when Field__call looks up my field, it's not
found in the "interesting_hfids" hash table.

Futher printfs uncovered the fact that, sometimes it is in the hash table
and sometimes it isn't! So I have been investigating how the hash table is
created for each packet, and how that might happen differently from one
packet dissection to the next.
From what I can tell, as wireshark processes my capture file the dissectors
and subdissectors get called three times, via the following three different
code paths:

1. Initially each packet in the capture file is dissected starting with a
call to add_packet_to_packet_list (in file.c). This leads to a call to
dissect_packet and thence to dissect_frame, which then calls any
subdissectors that are registered (each of which calls its subdissectors, if
any). Finally, call_all_postdissectors runs the postdissectors, including my
Lua code.

When this path through the code is traversed, my Lua field extractor gets
values just fine!


2. After that first pass, the wireshark GUI code (which I don't understand
very deeply) selects the first packet as the "cursor position", and this
results in two subsequent calls to cf_select_packet (also in file.c). This
calls the dissectors again, both times on frame 1, however this time nothing
is added to the "interesting_hfids" hash table because the header field
info's "ref_count" field is 0 for each field.

(I don't understand the significance of this, but it doesn't appear to be
the real source of my problem. I include it primarily for completeness.)


3. Finally, the packets are dissected again via
packet_list_dissect_and_cache_record (in gtk/packet-list_store.c). This
time only the packets that are visible in the top pane of the GUI are
dissected. The interesting_hfids hash table is created, but the header
fields that are added to it are a subset of the original fields that were
added in the first pass. In particular, the list does *not* include the
field that corresponds to my Lua field extractor. So when we get to my
postdissector, the hash table lookup fails and Field__call returns nil to
Lua.

Of course all this happens very quickly as the wireshark GUI is opening.
But by the time I can access the packet display, the data from pass 1 have
been overwritten by the nils from pass 3.


I'm continuing to dig through the code, to figure out where the list of
"interesting hfids" comes from, and why it changes. But if anybody is
familiar with this code and can throw me a hint where to look, I'd
appreciate it.


Here's a snippet of my debug output, showing the subset of fields that get
added to the hfids hash table in pass 3:

== packet_list_dissect_and_cache_iter ==
== in packet_list_dissect_and_cache_record (fnum=15) ==
::: Calling dissector Frame
Created new hfid table at 0x4715488
Inserted eth in hfid table at 0x4715488 (size=1)
Inserted ip.ttl in hfid table at 0x4715488 (size=2)
Inserted ip.checksum_bad in hfid table at 0x4715488 (size=3)
Inserted ip.dst in hfid table at 0x4715488 (size=4)
Inserted udp in hfid table at 0x4715488 (size=5)
Inserted udp.checksum_bad in hfid table at 0x4715488 (size=6)
::: Calling dissector Data
::: Dissector Data returning 2
** About to call 3 postdissectors for frame#15... "MATE" "PRP"
"POST802154"
Field__call: hfid table=0x4715488
Field__call: field info array not found for ieee802.15.4.seq_no
**
::: Dissector Frame returning 90
Beth
2009-09-23 16:36:27 UTC
Permalink
Interesting results! If I edit cf_select_packet (in file.c) and add a call
to tap_queue_init(cf->edt) just before the call to epan_dissect_run, it
fixes my problem.

tap_queue_init calls epan_dissect_prime_dfilter on each item in the
tap_listener_queue, which sets the ref_count for those fields to DIRECT.
This means that calls to proto_item_add_<whatever> will also add the field
to the interesting_hfids hash table, where they are later found by my Lua
postdissector via Field__call.

What I *don't* know is whether this is actually a reasonable strategy for
solving the original problem (described in subject of post). After only
three days of digging through the source code, I definitely do not qualify
as a Wireshark expert, just a lucky beachcomber who happened to find two
shells that seem to fit together.

Can anyone comment on this?

Thanks,
b.

Loading...