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

From: Frank Lahm <franklahm@xxxxxxxxxxxxxx>
Date: Thu, 26 Aug 2010 13:58:56 +0200
2010/8/26 Frank Lahm <franklahm@xxxxxxxxxxxxxx>:
> 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!

Oh my! Nevermind! Got it. I was still resetting
request_val->spotlight_req_command = -1 at the end of the reply
dissection from an older attempt to solve this. After removing that
line, I get the decoding I want.

Cheers, Frank!