What's the difference between a dissector, post-dissector and tap?

I'm trying to write a Lua plugin for a simple UDP protocol that contains a rolling byte for packet sequencing.

I've written a working dissector that extracts this rolling byte (and other information), however I now am looking for a way to indicate missing packets by looking for gaps in the rolling byte (e.g. consecutive packets containing "00, 01, 03"). I'd hope to display these in a similar way to how Wireshark displays retransmissions - a big, bold, colour variation for the "03" packet indicating that it follows a break in the stream.

I've tried to do this using a global Lua table within the dissector, but the dissector appears not to be evaluated sequentially (or perhaps multiple times). Other Q&A's on other forums have suggested a "Tap" may be more appropriate to achieve this, but I can't find any good resource that outlines what the difference between a dissector, post-dissector and tap actually is!

So - what's the difference?

edit retag close merge delete

Sort by » oldest newest most voted

A "normal" dissector is invoked to deal with a given layer of the protocol stack present in the packet after eventual dissection of lower layers has been done, and it eventually invokes another dissector to deal with the payload part of its layer. A practical example is that Ethernet dissector invokes IP dissector which invokes TCP dissector which invokes HTTP dissector. Due to this order, the dissection tree is filled with information in the order of protocol layers: ethernet ipv4 tcp http

A post-dissector is invoked after all the "normal" dissectors have done their job, so its output can only appear at the bottom of the dissection tree.

A tap collects information from several packets as they are processed by other dissectors, in order to provide some summary information, not in a dissection tree of a single packet but in some own output window (e.g., to display the number of packets of various types captured so far during capture is an illustrative task for a tap).

To answer your real question: your approach of maintaining a global table is correct, but your observation that dissectors are called several times is also correct, and you have to match the approach to that fact.

When you open the capture file for the first time, or whenever you change the display filter, all packets are dissected in sequence. Whenever you click an individual packet in the list, it is dissected again to display the contents in the dissection pane. And clicking a packet during a live capture even breaks the rule that for the first time, all packets are dissected in sequence.

There is a pinfo.visited value, but in the past I've noticed doubts whether it works correctly, so when I deal with tasks like yours, I always build my own table to note down whether this particular packet has already been dissected once or not. This addresses even the situation where you click a packet during live capture.

more

if pinfo.visited isn't working as advertised than you should file a documented bug report so it can be fixed. This field is the only one which should be required for this task, setting up your own administration for this is undesirable.

( 2018-01-18 14:18:09 +0000 )edit

well, whenever I needed a specific first-pass handling so far, it was always assigning some value to be used during the next dissections into the global table indexed by frame.number anyway, so the "own administration for this" came at no extra cost. In another words, using pinfo.visited would be redundant in these cases. So in the answer, my intention was to notify the OP about its existence as it may be sufficient for his purpose, but with a warning as I've seen someone here (at the old site) complaining about it, I don't remember the details.

( 2018-01-18 18:03:15 +0000 )edit