This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Lua - Dissector Functions, Buffered Data, and TCP Reconstruction

1

I'm starting out creating a wireshark dissector (in lua) for my game-in-development's multiplayer protocol to help with debugging, and have so far been dissapointed by the lack of good documentation on the subject. This protocol runs on top of TCP because I can't be bothered to implement a real solution, and TCP is good enough for me. I've found dissector.lua, which seems to be a very valuable resource, but this leaves me wondering:

  • How often is this dissector function called?
  • How full is the buffer when it's called?
  • How can I let the buffer fill up a bit more, if it's running low?
  • How can I use TCP reconstruction with my dissector? There is a stunning lack of documentation on this subject specifically

I'd love to have my dissector be a loop running in a coroutine that can call something like "stream.read(16)" to read 16 bits and that would do a coroutine.yield until I receive more data, and then once I get all my data I can just post some of it to the network dump file like so:

while(true) do
  stream.read(32)
  --construct tree from data
  dump.put(tree)
end

Unfortunately, I don't believe that Wireshark works like this.

asked 08 Jan '15, 23:25

Xenotoad's gravatar image

Xenotoad
21114
accept rate: 0%


One Answer:

1

How often is this dissector function called?

Potentially multiple times:

  1. For both Wireshark and tshark: it's called once for every packet when the capture file is loaded or the packet is captured live.
  2. For Wireshark: I believe it's called a second time for when the GUI packet list gets drawn.
  3. In Wireshark: it's called again whenever the user selects the packet in the GUI packet list window pane.
  4. In Wireshark: it's called again once per packet whenever the user applies a new display filter, or for certain statistics/graphs or preference changes, decode-as being chosen, etc.
  5. In tshark: it's called once per packet a second time if the user used the '-2' command line switch, or used the '-Y' display filter command line option.

How full is the buffer when it's called?

The Tvb contains the contents of the captured packet/frame, starting at wherever the previous layer's dissector finished. So if your dissector is registered into the TCP dissectors table, then your dissector will be given a Tvb buffer of the TCP segment's payload (i.e., not including IP/TCP headers) for that one packet/frame. So it may contain only a portion of your application's message, or it may contain multiple of your application's messages, or it may contain exactly one full message.

How can I let the buffer fill up a bit more, if it's running low? How can I use TCP reconstruction with my dissector? There is a stunning lack of documentation on this subject specifically

See the "TCP reassembly" section of http://wiki.wireshark.org/Lua/Dissectors. There is indeed a lack of documentation for TCP-based dissection, but if you ask your questions here (in new topics, not in this topic), then we can use that to help build some documentation for the wiki.

Unfortunately, I don't believe that Wireshark works like this.

Right - a Lua plugin doesn't "drive" Wireshark... Wireshark controls everything and just invokes Lua callbacks. There is an open bug in this area (bug 9851), and when that gets addressed there may be something to make TCP dissection easier, but only if your protocol has a length field somewhere early in its message format. If, on the other hand, your protocol is more like HTTP where you don't know the length of the message until you're done with it, then the DESEGMENT_ONE_MORE_SEGMENT method is the only one. Does your protocol have a length field?

answered 09 Jan '15, 09:34

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

edited 09 Jan '15, 09:36

I can read the first few bytes of the message to calculate the total length of the message. Thanks for the great answer, it's pretty close to what I was looking for!

(09 Jan '15, 15:22) Xenotoad

If I return DESEGMENT_ONE_MORE_SEGMENT, will the next call's tvb argument still contain the data from the last call?

Example:

Call #1 Buffer: {0, 0, 5, 6, 7} --Returns DESEGMENT_ONE_MORE_SEGMENT

Will Call #2's buffer be {0, 0, 5, 6, 7, 3 , 5} or {3, 5}?

(09 Jan '15, 15:37) Xenotoad

I believe it depends on what you set pinfo.desegment_offset to: if you leave it at 0, and set pinfo.desegment_len to DESEGMENT_ONE_MORE_SEGMENT, then yes you'll get all the previous Tvb bytes as well as the new ones on the next call to dissect() - i.e., you'll get {0, 0, 5, 6, 7, 3, 5}. If you set pinfo.desegment_offset to 1, then you'll get {0, 5, 6, 7, 3, 5}, and so on.

(09 Jan '15, 16:33) Hadriel