Ask Your Question

LUA: dissector wide global table

asked 2017-11-22 16:48:01 +0000

Richard S gravatar image


I need to implement latency and concurrency analysis via Lua, similar to what is available in many other (builtin) dissectors. Typically the entry in the tree is called "Time from request", and the C dissectors simply allocate a global table of the requests to track, match the responses and display the result eventually.

However, I'm having a hard time trying to figure out how wireshark-lua lets me create a proto object, where I can add an object-wide table for reference across individual packet dissections (or even really global variables).

Also, there seems to be not a single sample of wireshark Lua where this is demonstrated.

For example, "self" seems to be missing in all object methods (?), and global variables stay "nil" (even if initialized) between packets...

Any help in figuring out how to implement a global table would be really appreciated.


edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2017-11-23 16:45:03 +0000

sindy gravatar image

updated 2017-11-23 22:47:53 +0000

You have to declare a global table in the part of your Lua code where you register the protocol fields, as this part is run once before any dissection is started. Once this is done, you can access that table from your .dissector function. You must not attempt to register that global table as protocol field, it is just your working table. The .dissector function may use values from that table to populate registered protocol fields which are marked as "generated", i.e. those which are not physically present in the packet data but the dissector calculates (generates) them from physical data of the packet being dissected as well as other information sources. The protocol fields of this kind are marked as such by [ ] around them in the dissection tree pane.

The point is that the .dissector function is run over the packet data several times - first in sequence when the file is loaded, with each selection of the packet in the packet list pane, with each application of a display filter... and the global table does not become part of packet data. So whenever the .dissector function dissects the packet, it must create all fields again and hook them at the correct place to the dissection tree.

You also have to bear in mind the above when handling the contents of the global table. In general, you must check whether the item you are going to insert doesn't exist already, as in most cases you actually fill the table only during the initial sequential pass of Wireshark through the file.

edit flag offensive delete link more


The normal term for "synthetic" fields is "generated" as in generated by the dissector.

grahamb gravatar imagegrahamb ( 2017-11-23 17:48:15 +0000 )edit

Thank you for reminding me, @grahamb, I've edited the Answer accordingly.

sindy gravatar imagesindy ( 2017-11-23 22:48:34 +0000 )edit

Thanks! I defined the base reference in the .init of the dissector, this seems to have done the trick. I keep my data in a rbtree for quickly checking if the entry already exists, seems to work so far.

One follow up question: In packet-rpc.c, this fragment adds a "hyperlink" to another frame, but there is nothing in the source code that is obvious how to make this happen:

2527    if(rpc_call->rep_num){
2528        proto_item *tmp_item;
2530        tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_reqframe,
2531            tvb, 0, 0, rpc_call->rep_num,
2532            "The reply to this request is in frame %u",
2533            rpc_call->rep_num);
2534        PROTO_ITEM_SET_GENERATED(tmp_item);
2535    }

2641    if (rpc_call->req_num) {
2642        proto_item *tmp_item;
2644        tmp_item=proto_tree_add_uint_format(rpc_tree, hf_rpc_repframe,
2645            tvb, 0, 0, rpc_call->req_num,
2646            "This is a reply to a request in frame %u",
2647            rpc_call->req_num);
2648        PROTO_ITEM_SET_GENERATED(tmp_item);
2650        nstime_delta(&ns, &pinfo->abs_ts, &rpc_call->req_time);
2651        tmp_item=proto_tree_add_time(rpc_tree, hf_rpc_time, tvb, offset, 0 ...
Richard S gravatar imageRichard S ( 2017-11-24 19:16:01 +0000 )edit

Because the hf fieldtype is set to "FT_FRAMENUM":

{ &hf_rpc_reqframe, {
  "Request Frame", "rpc.reqframe", FT_FRAMENUM, BASE_NONE,
  NULL, 0, NULL, HFILL }},
{ &hf_rpc_repframe, {
  "Reply Frame", "rpc.repframe", FT_FRAMENUM, BASE_NONE,
  NULL, 0, NULL, HFILL }},
grahamb gravatar imagegrahamb ( 2017-11-25 15:07:09 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-11-22 16:48:01 +0000

Seen: 40 times

Last updated: Nov 23