This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

How to store data in conversations via dissector

0

Greetings, I am building a plugin dissector that decompresses packets from a conversation for which a compression flag can be set either via a byte set on the first compressed subsequent segment or a string definition on its first segment. Subsequent segments afterwards do not have the byte set that flags a compressed stream. I've tried either finding the conversation or creating one if not found, but I need a mechanism for depicting if a packet found from a conversation has been set to "Compressed". Here is my code:


        /* First check that data is compressed */
    tvbuff_t *newBuf;
    guint8 bits1 = tvb_get_guint8(tvb, offset);
    guint8 bits2 = tvb_get_guint8(tvb, offset + 1);
    if ((bits1 == 200) && (bits2 == 300)) {
        m_IsCompressed = TRUE;
    }
/* Next check if this is a new stream or it's part of a CPOF conversation. */
conversation_t *conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
    pinfo->ptype, pinfo->srcport, pinfo->destport, 0);

// first segment to process for this side of the stream?
if (conversation == NULL){
        // Create new conversation to track
    conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
        pinfo->ptype, pinfo->srcport, pinfo->destport, 0);

/* Compression flag also gets set when "Compressing" string is found.  Other systems in conversation can also converse compressed, yet not have bytes-set flag. */
    gint newLen = tvb_reported_length_remaining(tvb, offset);
    guint8* buff_str = tvb_get_string_enc(pool, tvb, offset, newLen, ENC_ASCII | ENC_NA);
    gchar* str = convert(buff_str, strlen);
    check_compression_string_flag(str);
    newBuf = tvb_new_subset_remaining(tvb, offset);
                if (m_IsCompressed)
                       conversation_add_proto_data(conversation, proto_tag, "Compressed");
}
else {
                char* state = (char*) conversation_get_proto_data(conversation, proto_tag);
                IsCompressed = m_IsCompressed || (state || strncmp(state, "Compressed", 10) == 0);
    if (m_IsCompressed) {
        /* the remainder of the packet is compressed, decompress the payload */
        newBuf = tvb_uncompress(tvb, offset, tvb_captured_length_remaining(tvb, offset + 2));

        /* Check the return code and add a expert info warning if an error
        * occurred. The dissector continues trying to add the payload,
        * however the returned size should be 0. */
        if (newBuf) {
            /* Now re-setup the tvb buffer to have the new data */
            tvb_set_child_real_data_tvbuff(tvb, newBuf);
            add_new_data_source(pinfo, newBuf, "Decompressed Data");
        }
        else {
            /* attempt to process it as uncompressed */
            newBuf = tvb_new_subset_remaining(tvb, offset);
        }
    }
    else {
            /* process new uncompressed buffer */
        newBuf = tvb_new_subset_remaining(tvb, offset);
    }
}
/* process newBuf from here on */
offset = 0;</code></pre><hr /><p>Could I store a Boolean into a conversation that I can access and use to determine if associated/follow-on packets need decompression? A single static boolean doesn't seem to do the trick for me.</p><p>Thanks in advanced.</p></div><div id="question-tags" class="tags-container tags"><span class="post-tag tag-link-dissector" rel="tag" title="see questions tagged &#39;dissector&#39;">dissector</span> <span class="post-tag tag-link-decompression" rel="tag" title="see questions tagged &#39;decompression&#39;">decompression</span> <span class="post-tag tag-link-compressed" rel="tag" title="see questions tagged &#39;compressed&#39;">compressed</span> <span class="post-tag tag-link-decompress" rel="tag" title="see questions tagged &#39;decompress&#39;">decompress</span> <span class="post-tag tag-link-plugin" rel="tag" title="see questions tagged &#39;plugin&#39;">plugin</span></div><div id="question-controls" class="post-controls"></div><div class="post-update-info-container"><div class="post-update-info post-update-info-user"><p>asked <strong>04 Apr '16, 20:08</strong></p><img src="https://secure.gravatar.com/avatar/bfa53b64ea6967e45a614981c461a638?s=32&amp;d=identicon&amp;r=g" class="gravatar" width="32" height="32" alt="coloncm&#39;s gravatar image" /><p><span>coloncm</span><br />

7681115
accept rate: 66%

edited 07 Apr ‘16, 12:42


One Answer:

1

conversation_new() should be inside the if (conversation == NULL) block, otherwise the conversation will never exist.

answered 05 Apr '16, 04:46

Jaap's gravatar image

Jaap ♦
11.7k16101
accept rate: 14%

Changed the question after suggested fix did not change outcome to the underlying problem.

(05 Apr '16, 16:35) coloncm
1

See README.dissector 2.2.1.5 The conversation_add_proto_data function.

(06 Apr '16, 04:33) Jaap ♦

Thanks, Jaap. The mechanism seems to work except I'm not sure if I'm getting back what I'm putting in form a found conversation, e.g., gboolen values appear to be random positive or negative values instead of 1 or 0 as previously set. But, that's another question, I guess, and your comment surely answers this question.

(06 Apr '16, 18:31) coloncm