Wireshark-dev: [Wireshark-dev] Re: Packet visited more than once?

From: Yaniv Kaul <yaniv.kaul@xxxxxxxxxxxx>
Date: Thu, 22 May 2025 22:39:15 +0300


On Thu, May 22, 2025 at 10:26 PM John Thacker <johnthacker@xxxxxxxxx> wrote:
On Thu, May 22, 2025 at 2:55 PM Yaniv Kaul via Wireshark-dev <wireshark-dev@xxxxxxxxxxxxx> wrote:


On Thu, 22 May 2025, 21:20 John Thacker, <johnthacker@xxxxxxxxx> wrote:
I don't understand what you mean. How would you do that? If you mean something like on the same pass through all the frames, then the TCP dissector will call your dissector with a tvbuff starting at the next offset to dissect, after all the PDUs you have dissected. If you mean on an entirely different pass through the frames (or after clicking on a different frame in the GUI), I don't understand what you mean.

I guess I need to re-read other dissectors, as I stumble to get it right. I need a state machine for my dissector, which I can easily keep in a conversation. But without re-running it as wireshark goes again dissecting the PDUs.
First packet, client to server. Great, set up conversation, save a bit of state. Server responds - we advance the state, save some more properties (which compression we've agreed upon, etc.) Now dissect more packets... And then we are suddenly back to the first client to server negotiation packet, but now there is already an existing conversation (and state), but it doesn't match - first packet is not compressed, for example. Perhaps I need to reset the state. 

I'll need to give it some more thought. 
Thanks for your response.

You cannot in general save state-like information in a conversation (or in a global variable) and expect the packets to be processed sequentially any time other than the first pass. Packets can and will be dissected out of order when a user clicks around on the GUI. To deal with state machine like information, there are generally two options:

1. Store the state information at the point of entering a packet in packet level proto data (see epan/proto_data.h, p_add_proto_data) in the first pass and retrieve it from there on subsequent passes.
2. Store state transitions in a wmem_tree or similar in the conversation, and look up the state via packet number in the tree.

Yes, I've been doing this (hopefully correct):
static scylla_conv_t *
setup_conversation(conversation_t *conversation)
{
    scylla_conv_t *scylla_conversation = NULL;

    scylla_conversation = wmem_new(wmem_file_scope(), scylla_conv_t);
    scylla_conversation->conv_map = wmem_map_new(wmem_file_scope(), wmem_int64_hash, g_int64_equal);
    scylla_conversation->state = 0;
    scylla_conversation->compression_type = 0;
    scylla_conversation->compression = false;
    scylla_conversation->timeout_propagation = false;
    scylla_conversation->streaming = false;
    conversation_add_proto_data(conversation, proto_scylla, scylla_conversation);
   
    return scylla_conversation;

}

I think I'm still missing a few things though, that I'll need to sort out:
1. The conversation itself is created only because I have the TCP handshake. I need to ensure I handle use cases where I don't have the TCP handshake prior to the higher level protocol packet - which is the first protocol packet for me - the negotiation.
2. I may be getting even a partial capture without the protocol negotiation, which for me is the beginning of the conversation I care about. I need to deal with it too.
3. I'm not deleting the conversation. I wonder where I'm supposed to do that. I don't free the conv_map data structure I've allocated, which is one concern, but another is that if I can delete everything in the 2nd pass, there's no concern with 'rerunning the state machine'.
4. Since multiple PDUs can be in a single packet, even the first packet. I think it's OK, since I can look for the protocol signature and only then know it's the 1st PDU of the 1st packet, and the rest are the rest of the PDUs.

Thanks again for your answers,
Y.

 

There are examples of both approaches in dissectors in the repository.

John
 
_______________________________________________
Wireshark-dev mailing list -- wireshark-dev@xxxxxxxxxxxxx
To unsubscribe send an email to wireshark-dev-leave@xxxxxxxxxxxxx