Wireshark-dev: Re: [Wireshark-dev] c-string dissector - desegmentation

From: "ronnie sahlberg" <ronniesahlberg@xxxxxxxxx>
Date: Tue, 12 Sep 2006 12:00:48 +0000
You are correct. You can not use tcp_dissect_pdus() for that case.

dissectors are assumed to return either TRUE or FALSE and not the
number of consumed bytes so the lower layers will not call your
dissector again for you.
This only happens when you use tcp_dissect_pdus() since it uses a
special callback that provides this information.


You will have to explicitely loop over the tvb in your dissector and
consume one pdu at a time until you reach the end of the tvb.


On 9/9/06, noix@xxxxxxxxx <noix@xxxxxxxxx> wrote:
Hello,

I'm trying to learn to write dissectors and I've run into problems
with tcp desegmentation. I would be really grateful for some advice!

I'd like to write a "c-string" dissector. My tcp stream consists of a
series of PDUs separated by \0. I can't use tcp_dissect_pdus() because
those strings have unpredictable length. So, I have to modify pinfo
struct.

README.developer seems to have a ready example for exactly this task
(paragraph 2.7.2):

static int dissect_cstr(tvbuff_t * tvb, packet_info * pinfo, proto_tree
* tree) {
    guint offset = 0;
    gint available = tvb_reported_length_remaining(tvb, offset);
    gint len = tvb_strnlen( tvb, offset, available );

    if( -1 == len ) {
        /* No '\0' found, ask for another byte. */
        pinfo->desegment_offset = offset;
        pinfo->desegment_len = 1;
        return -1;
    }

    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_set_str(pinfo->cinfo, COL_INFO, "C String");
    }

    len += 1; /* Add one for the '\0' */

    if (tree) {
        proto_tree_add_item(tree, hf_cstring, tvb, offset, len, FALSE);
    }

    return len;
}

...but it doesn't seem to work for me :(

I tested it on a series of TCP packets:
packet 1: "\001\001\000"
packet 2: "\002\002\000\003\003\000"
packet 3: "\004"
packet 4: "\004\000"
packet 5: "\005\005\000\006"
packet 6: "\006\000"

The results:
- it did correctly find a "\001\001" string in the first packet
- BUT in the second packet, it found "\002\002" and ignored "\003\003"
- then, it correctly desegmented packets 3 and 4 and gave me a "\004
\004" string
- then again, it found a "\005\005" string in packet 5, ignored
the \006 byte and incorrectly recognized a "\006" string in packet 6

It's possible that the example in README.developer wasn't meant to be
that smart... But I'd like to write one that would be and I don't know
how.
I thought the sample plugin above should work - that if a dissector
returns a positive number and it's smaller that it's tvb length, a
lower-level dissector should call the dissector again with the
remaining data.

Just in case, this is the full plugin code (maybe I'm doing the
dissector registration incorrectly?):
http://sphere.pl/~noix/wireshark/packet-noix.c

TIA,

Noix

P.S. I use vanilla wireshark 0.99.3a and compile it with gcc 4.1.2. My
distro is Debian SID.
_______________________________________________
Wireshark-dev mailing list
Wireshark-dev@xxxxxxxxxxxxx
http://www.wireshark.org/mailman/listinfo/wireshark-dev