ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

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

Date: Sun, 10 Sep 2006 01:22:38 +0200
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.