Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: [Wireshark-dev] Get data from previous request packet in subsequent reply packet

From: Frank Lahm <franklahm@xxxxxxxxxxxxxx>
Date: Thu, 26 Aug 2010 13:48:46 +0200
Hi list,

I'm trying to find a way to get at data from a previous request packet
in order to correctly dissect the current packet.
I'm working on the AFP dissector in epan/dissector/packe-afp.c. AFP is
a TCP packet oriented streaming protocol. I'm currently working on a
new AFP function FPSpotlightRPC. Problem is, the request specifies
additional command codes, that I must somehow be able to get at in the
corresponding reply in order to dissect accordingly.

The AFP dissector already has code in place in the dissector that does
exactly this for the basic AFP command code. As the command code in
not repeated in the reply, it must be extracted from the request.
There's this code in the dissector in the dissctor the grabs the AFP
command code from request:
---8<---
static void
dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    ...

    conversation = find_or_create_conversation(pinfo);

    request_key.conversation = conversation->index;
    request_key.seq = aspinfo->seq;

    request_val = (afp_request_val *)
g_hash_table_lookup(afp_request_hash, &request_key);

    if (!request_val && !aspinfo->reply)  {
        /* it's a request */
        afp_command = tvb_get_guint8(tvb, offset);
        new_request_key = se_alloc(sizeof(afp_request_key));
        *new_request_key = request_key;

        request_val = se_alloc(sizeof(afp_request_val));
        request_val->command = afp_command;

//      if (afp_command == AFP_SPOTLIGHTRPC)
//           request_val->spotlight_req_command = tvb_get_ntohl(tvb,
offset + 2 + 2 + 4);

        ...

        g_hash_table_insert(afp_request_hash, new_request_key,
                                request_val);
    }

    if (!request_val) { /* missing request */
        col_set_str(pinfo->cinfo, COL_INFO, "[Reply without query?]");
        return;
    }

    afp_command = request_val->command;
    ....

    if "request"
       ...dissect request packets furterh...
    else /*reply*/
        ....
        case AFP_SPOTLIGHTRPC:
            offset = dissect_reply_afp_spotlight(tvb, pinfo, afp_tree,
offset, request_val);
            break;
}

static gint
dissect_reply_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *tree, gint offset, afp_request_val *request_val)
{
    if (request_val->spotlight_req_command == 1) {
        ...
    }
}
---8<---

The C++ style commented code is part of my attempt to achieve the same
for the data I need. Unfortunately it doesn't work. I've tried setting
request_val->spotlight_req_command = 1 unconditionally in case I was
fetching the wrong bytes, to no avail. From what I can tell, there
seems to be a general problem with this approach, is there?

Can anybody shed some light on this? Thanks a lot!

-Frank