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

Reassembled data in custom dissector

0
1

Hi,

Iam in the process of developing my custom dissector on top of UDP(wireshark).

I have a packet data spli in many packets and reassembled together when i get "end of message" key. I have 3 keys 1. beginning of message 2. continuation of message 3. end of message.

I have to display the data (reassembled ) in a seperate TAB. (only when i get end of message key i have to do this)

I have gone through the below code and could not understand

              #include <epan/reassemble.h>
                ...
               save_fragmented = pinfo->fragmented;
            flags = tvb_get_guint8(tvb, offset); offset++;
            if (flags & FL_FRAGMENT) { /* fragmented */
            tvbuff_t* new_tvb = NULL;
           fragment_data *frag_msg = NULL;
              guint16 msg_seqid = tvb_get_ntohs(tvb, offset); offset += 2;
              guint16 msg_num = tvb_get_ntohs(tvb, offset); offset += 2;
              pinfo->fragmented = TRUE;
               frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
              msg_seqid, /* ID for fragments belonging together */
                  msg_fragment_table, /* list of message fragments */
                 msg_reassembled_table, /* list of reassembled messages */
                 msg_num, /* fragment sequence number */
                tvb_length_remaining(tvb, offset), /* fragment length - to the end */
                flags & FL_FRAG_LAST); /* More fragments? */
            new_tvb = process_reassembled_data(tvb, offset, pinfo,&quot;Reassembled      Message&quot;, frag_msg, msg_frag_items,NULL, msg_tree);

   if (frag_msg) { /* Reassembled */
   col_append_str(pinfo-&gt;cinfo, COL_INFO,&quot; (Message Reassembled)&quot;);
   } else { /* Not last packet of reassembled Short Message */
   col_append_fstr(pinfo-&gt;cinfo, COL_INFO,
    &quot; (Message fragment %u)&quot;, msg_num);
                    }
  if (new_tvb) { /* take it all */
    next_tvb = new_tvb;
    } else { /* make a new subset */
    next_tvb = tvb_new_subset(tvb, offset, -1, -1);
      }
    }
          else { /* Not fragmented */
                  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
                    }
                   .....
                  pinfo-&gt;fragmented = save_fragmented;</code></pre><p>Please suggest! Note: I do not have any seq number for each packet data..</p></div><div id="question-tags" class="tags-container tags"><span class="post-tag tag-link-reassembled" rel="tag" title="see questions tagged &#39;reassembled&#39;">reassembled</span> <span class="post-tag tag-link-data" rel="tag" title="see questions tagged &#39;data&#39;">data</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 Sep '14, 03:52</strong></p><img src="https://secure.gravatar.com/avatar/1339589a92af9455063c09e56bfc6299?s=32&amp;d=identicon&amp;r=g" class="gravatar" width="32" height="32" alt="umar&#39;s gravatar image" /><p><span>umar</span><br />

26222427
accept rate: 0%

edited 10 Sep ‘14, 00:46


2 Answers:

1

Go into epan/reassemble.h and epan/reassemble.c. There you'll find all the details in which you can reassemble fragments in a way suitable for your protocol.

answered 10 Sep '14, 04:12

Jaap's gravatar image

Jaap ♦
11.7k16101
accept rate: 14%

Hi Jaap , Thanks for your reply. my requirement is , i have n number of frames and i have three different data .. 1. beginning of message 2. continuation of message 3, end of message. when beginning of message i have to store the data and continuation of message data alo be included and when it comes to end of data i have to display it in a separate tab (reassembled data and process it). i have gone through reassemble.c and could not understand. can you help me on this.

my packet dissection is byte by byte...

Thanks

(16 Sep '14, 19:57) umar

1

To reassemble your packets you need some information such as the ID of your fragment, the offset of the current segment in the reassembled packet, if it's the last fragment or not, and more (It depend on your protocol). All these information are passed to the fragment_add_seq_check() to attempt a reassembly.

You can also see exemple of reassemble interface in the epan/dissectors folder (packet-ipv6.c, packet-6lowpan.c, etc.)

answered 22 Sep '14, 05:49

Afrim's gravatar image

Afrim
160101116
accept rate: 22%

Hi Afrim ,

do i need to create ID on my own? because i have raw data which does not comes with ID . Can \you help me to explain step by step procedure. (define table, init table add data to reassemble data etc..) I tried to understand the existing code and could not understand.How to display the reassembled data in a separate tab ? below image for reference.

I have 3 diff type of packet pdu 1. beginning of message 2. continuation of message 3, end of message each type contain data in it. for example beginning of message got 20 octets and continuation of message got 10 octets and end of message got 15 octets. I need to reassemble all these 45 octets of data in End of message sequence. Please suggest

Thanks

RAj

(14 Oct '14, 01:58) umar

alt text

(14 Oct '14, 02:39) umar
1

The ID is needed cause when you receive your packets in Wireshark they are not sorted by fragmentation order. For exemple you will not receive :
Packet 1 : fragmentation, beginning of message
Packet 2 : fragmentation, continuation of message
Packet 3 : fragmentation, end of message

But it will be something like :
Packet 1 : fragmentation, beginning of message
Packet 2 : fragmentation, continuation of message
Packet 3 : fragmentation, beginning of message
Packet 4 : fragmentation, beginning of message
Packet 5 : fragmentation, continuation of message
Packet 6 : fragmentation, end of message
etc...
In this case you dont know if packet 6 is end of message of packet 5 or packet 2. Neither you know if packet 5 is continuation of packet 4 or 3. That's why we use IDs. But it realy depend on your protocol, if your protocol does not allow multiple "beginning of message" you can set ID to any value.

Then all what you need is to tell if there is more fragments(you have this information) to wait for this ID, if no the ressembly will occur. Ofc you have to tell the length of the fragment as the code of your first post says.

(14 Oct '14, 03:04) Afrim

Hi Afrim,

Thanks for the reply . Got it, Thanks. for my protocol only one beginning of message and may be multiple continuation of message and 1 end of message. Now i have gone through many protocols to understand how to add the data into reassemble table. As iam new to this , could you help me to guide step by step procedure to add data to table and display in a separate tab like in the image. when it comes to end of message!

         Packet 1 : fragmentation,                         beginning of message
     Packet 23 : fragmentation, continuation of message
     Packet 44 : fragmentation, continuation of message
     Packet 57 : fragmentation, continuation of message
     Packet 69 : fragmentation,                           end of message</code></pre></div><div id="comment-37032-info" class="comment-info"><span class="comment-age">(14 Oct '14, 03:11)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37037"></span><div id="comment-37037" class="comment"><div id="post-37037-score" class="comment-score">1</div><div class="comment-text"><p><span>@mrajsekar</span></p><p>Unfortunately all the protocols that do reassembly in this way are somewhat complicated, if you search for all files in epan\dissectors that include <code>fragment_add_seq_next</code>, you will see all the current dissectors that use the method you need. Try looking at those, but be aware they are all likely to have a lot of "extras" that you'll have to work through.</p><p>You'll need to understand "conversations" (README.dissector sect 2.2) and reassembly (in epan\reassemble.h) to complete your dissector.</p><p>I think you need to use <code>fragment_add_seq_next</code> as you don't have a fragment id, so must assume all fragments come in order, first to last.</p></div><div id="comment-37037-info" class="comment-info"><span class="comment-age">(14 Oct '14, 05:27)</span> <span class="comment-user userinfo">grahamb ♦</span></div></div><span id="37046"></span><div id="comment-37046" class="comment not_top_scorer"><div id="post-37046-score" class="comment-score"></div><div class="comment-text"><p>Thanks Grahamb!I will try this.</p></div><div id="comment-37046-info" class="comment-info"><span class="comment-age">(14 Oct '14, 18:49)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37326"></span><div id="comment-37326" class="comment not_top_scorer"><div id="post-37326-score" class="comment-score"></div><div class="comment-text"><p>Hi, What is the difference between conversation and reassembly and fragmentation???</p><p>for me iam developing dissector to ruunnning on top of UDP port XXXX and my PDU data comes in many packets..</p><p>Not from other destination port..</p><p>Can you please Clarify?</p><p>for me i have beginning of message in that i have a data length field : ex. 24 bytes in that beginning of message contains 15 Bytes pdu data</p><p>continuation of message contains 5 bytes and another continuaton of message contains 2 bytes and then End of Message contains 2 bytes.</p><p>How can i achieve this reassembly . using conversation or using reassembly??</p><p>i have gone through RTP and some other files but i get confuse with it. please help me on this</p><p>Thanks</p></div><div id="comment-37326-info" class="comment-info"><span class="comment-age">(24 Oct '14, 01:17)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37328"></span><div id="comment-37328" class="comment"><div id="post-37328-score" class="comment-score">1</div><div class="comment-text"><p>Fragmentation (and subsequent reassembly) occurs when an application pdu can be split across multiple transport layer segments, e.g. your pdu arrives split over multiple tcp segments. The application dissector can tell the tcp dissector how much data it needs (read from the application pdu header) and the tcp dissector then reassembles incoming data until it has enough to hand back to the application dissector. Wireshark has built-in support for tcp reassembly, for other transport protocols the application dissector will have to manage reassembly itself.</p><p>Conversation is where the application dissector may be interested in multiple application pdu's, e.g request\response.</p></div><div id="comment-37328-info" class="comment-info"><span class="comment-age">(24 Oct '14, 02:01)</span> <span class="comment-user userinfo">grahamb ♦</span></div></div><span id="37331"></span><div id="comment-37331" class="comment not_top_scorer"><div id="post-37331-score" class="comment-score"></div><div class="comment-text"><p>Should i add id to each byte of the data ? please help me on this i really could not understand this. i got stuck in this for long time. i have completed 95% of the dissector and once i did this i can complete my work.</p></div><div id="comment-37331-info" class="comment-info"><span class="comment-age">(24 Oct '14, 02:42)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37368"></span><div id="comment-37368" class="comment not_top_scorer"><div id="post-37368-score" class="comment-score"></div><div class="comment-text"><p>Is this code will satisfy my requirement?<br />

      dissect_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
        while [bytes remain in tvb from offset]
            if [pdu length is unknown]
        found = fragment_get(pinfo, 0, fragment_table);
        if [fragment was found]
            [loop through found->next and add total_length and data]
            buffer = tvb_new_real_data(data, total_length, total_length);
        else
            buffer = tvb_new_subset(tvb, offset, ...);
    bytes_available = tvb_length(buffer);
    pdu_length = get_pdu_length(buffer, &amp;pdu_offset);
    if [pdu length is known and is smaller than bytes remaining]
        complete = TRUE;
    /* bytes_to_consume is min(pdu_length, bytes_available) */
    pinfo-&gt;fragmented = !complete;
    head = fragment_add(tvb, offset, pinfo, 0, fragment_table,
            offset, bytes_to_consume, !complete);
    next_tvb = process_reassembled_data(tvb, offset,                             pinfo, &quot;Reassembled packet&quot;, head, &amp;proto_frag_items, NULL, tree);
    offset += bytes_to_consume;</code></pre></div><div id="comment-37368-info" class="comment-info"><span class="comment-age">(26 Oct '14, 23:34)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37371"></span><div id="comment-37371" class="comment"><div id="post-37371-score" class="comment-score">1</div><div class="comment-text"><p>I don't really understand the purpose of your while loop and I think in your case you dont need conversation interface.So, as Grahamb said, assuming your data comes in order you dont need an ID, then use fragment_add_seq_next().<br />

Here is the prototype of this function

fragment_head 
fragment_add_seq_next(reassembly_table table, tvbuff_t tvb, const int offset,
              const packet_info pinfo, const guint32 id,
              const void *data, const guint32 frag_data_len,
              const gboolean more_frags);

So you got the reassembly table, tvb buffer, the current offset, pinfo structure, as you dont need ID I would have set it to 0 (or any other value), set data* to NULL, frag_data_len is the length of your fragment and more_frag is a flag to tell if there is more fragment to wait. You got all these information so just fill in.

(27 Oct '14, 04:25) Afrim

Hi Afrim,

Thank you so much! This will be really helpful. I will Try this!

Thanks Grahamb!

(28 Oct '14, 20:33) umar

Hi Afrim grahamb,

Need your help.

             process_reassembled_data( next_tvb, offset_payload, pinfo, "Reassembled PDU", bgan_frag_msg,&ALSIGPDU, NULL, FT_BCnPDU_tree );

In this parameter 6 i need to pass a function ALSIG PDU How it is possible?

Those tvb i have reassemblesd had to be proceessed in ALSIG PDU function. Please suggest some idea,

(29 Oct '14, 23:10) umar

save_fragmented = pinfo->fragmented;

                                        pinfo->fragmented = TRUE;
                            my_frag_msg = fragment_add_seq_check(&amp;my_reassembly_table,tvb, offset, pinfo, my_seqid, NULL,0, reassebled_data_total_length, more_frags);

                                my_tvb = process_reassembled_data( tvb, offset, pinfo, &quot;Reassembled PDU&quot;, my_frag_msg,&amp;my_frag_items, NULL, FT_PDU_tree );

SIGPDU(my_tvb, pinfo, tree);

What is wrong my reassembly not happening?

(30 Oct ‘14, 01:15) umar

Hi,

I have

beginning of the message (in this pdu i have info about total msg length) continuation of the message end of message

I have set a global variable to take the total length and substract it from pdu length of beginning of msg and continuation of message when it comes to end of message i have added the pdu data to the reassembled table and then used process_reassembled_data to process. But its not happening

beginning of message and continuation of message shows correct for me. I dont know whether reassembled table got data added or not. please suggest!

I have used

           fragment_add_seq_next(&bgan_reassembly_table,next_tvb, offset_payload, pinfo, bgan_seqid, NULL,reassebled_data_total_length, more_frags);
(30 Oct ‘14, 02:09) umar

Hi,

My comple re assembly code is below

Please suggest what i have missed or issue

        static reassembly_table mine_reassembly_table;

    static int hf_mine_fragments = -1;
    static int hf_mine_fragment = -1;
    static int hf_mine_fragment_overlap = -1;
    static int hf_mine_fragment_overlap_conflicts = -1;
    static int hf_mine_fragment_multiple_tails = -1;
    static int hf_mine_fragment_too_long_fragment = -1;
    static int hf_mine_fragment_error = -1;
    static int hf_mine_fragment_count = -1;
    static int hf_mine_reassembled_in = -1;
    static int hf_mine_reassembled_length = -1;

    static gint ett_mine_fragment = -1;
    static gint ett_mine_fragments = -1;

    static const fragment_items mine_frag_items = {
    /* Fragment subtrees */
    &amp;ett_mine_fragment,
    &amp;ett_mine_fragments,
    /* Fragment fields */
    &amp;hf_mine_fragments,
    &amp;hf_mine_fragment,
    &amp;hf_mine_fragment_overlap,
    &amp;hf_mine_fragment_overlap_conflicts,
    &amp;hf_mine_fragment_multiple_tails,
    &amp;hf_mine_fragment_too_long_fragment,
    &amp;hf_mine_fragment_error,
    &amp;hf_mine_fragment_count,
    /* Reassembled in field */
    &amp;hf_mine_reassembled_in,
    /* Reassembled length field */
    &amp;hf_mine_reassembled_length,
    /* Reassembled data field */
    NULL,
    /* Tag */
    &quot;mine fragments&quot;
    };

    static void mine_init_protocol(void)
        {

            /* fragment_table_init(&amp;mine_fragment_table); */
            /* reassembled_table_init(&amp;mine_reassembled_table); */
            reassembly_table_init(&amp;mine_reassembly_table, &amp;addresses_reassembly_table_functions);
        }

    save_fragmented = pinfo-&gt;fragmented;

    pinfo-&gt;fragmented = TRUE;

    mine_frag_msg = fragment_add_seq_next(&amp;mine_reassembly_table,next_tvb, offset_payload, pinfo, mine_seqid, NULL,
                                                 reassebled_data_total_length, more_frags);

    mine_tvb = process_reassembled_data( next_tvb, offset_payload, pinfo, &quot;Reassembled PDU&quot;, mine_frag_msg,
        &amp;mine_frag_items, NULL, FT_BCnPDU_tree );

    reassebled_data_total_length =0;

    proto_tree_add_text(FT_BCnPDU_tree, mine_tvb, offset_payload, 1, &quot; reassebled data &quot;);

    ALSIGPDU(mine_tvb, pinfo, tree);</code></pre></div><div id="comment-37482-info" class="comment-info"><span class="comment-age">(30 Oct '14, 19:26)</span> <span class="comment-user userinfo">umar</span></div></div><span id="37483"></span><div id="comment-37483" class="comment not_top_scorer"><div id="post-37483-score" class="comment-score"></div><div class="comment-text"><p>Also How to calculate the length of the reassembled table? because i have set a variable reassebled_data_total_length and get the total length. Then when beginning continuation of msg pdu data i hv substract the pdu data length from the total length. Here when i open wireshark and open the capture file, if i go directly to the end of message pdu reassebled_data_total_length it shows as zero. but if i open beginning of msg and then open end of msg pdu it shows corrrect. please help</p></div><div id="comment-37483-info" class="comment-info"><span class="comment-age">(30 Oct '14, 19:48)</span> <span class="comment-user userinfo">umar</span></div></div><span id="39905"></span><div id="comment-39905" class="comment not_top_scorer"><div id="post-39905-score" class="comment-score"></div><div class="comment-text"><p>Hi Afrim and Grahamb,</p><p>Sorry . My message comes with sequence Number . based on the seq num i need to reassemble.</p><p>i have used fragment_add_seq_check but my fragment table itself always returning NULL.</p><p>Can i hae your mail id so that i can share my code. i think you can solve that in minute, please help</p><p>My latest question posted here</p><p><a href="https://ask.wireshark.org/questions/39824/fragmentation-error-status-access-violation">https://ask.wireshark.org/questions/39824/fragmentation-error-status-access-violation</a></p><p><a href="https://ask.wireshark.org/questions/39885/pdcp-layer-pdu-rfc-2507-arq-mechanism">https://ask.wireshark.org/questions/39885/pdcp-layer-pdu-rfc-2507-arq-mechanism</a></p></div><div id="comment-39905-info" class="comment-info"><span class="comment-age">(17 Feb '15, 00:47)</span> <span class="comment-user userinfo">umar</span></div></div></div><div id="comment-tools-36506" class="comment-tools"><span class="comments-showing"> showing 5 of 18 </span> <a href="#" class="show-all-comments-link">show 13 more comments</a></div><div class="clear"></div><div id="comment-36506-form-container" class="comment-form-container"></div><div class="clear"></div></div></td></tr></tbody></table>