Wireshark-dev: Re: [Wireshark-dev] : Plugin dissector not called when wireshark reassembles the

From: Merlin Hooze <me_merlin18@xxxxxxxxx>
Date: Mon, 10 Mar 2008 04:57:58 -0700 (PDT)
Hello,
I gave few prints in the tcp_dissect_pdus() function and I am getting this output.
Generally the message shown as TCP seg of reassembled pdu comes split in two frames, of len 2 bytes and 36 bytes...So actual payload is 38 bytes.
When it finds the fixed length part to be split between segments, it is not  reassembling it properly.
It goes to bounds error...
Can anyone be so kind to have a look at it and give few suggestions as to what can be going wrong ?
All 33 length messages are decoded properly.
Also below i have put the tcp_dissect_pdus() function with my prints();

Thanks lot.

In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Giving hint to tcp where next pdu starts--
remaining_bytes= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=2
can reassemble
Fixedlength part is split across segment 
Telling dissector where data for this message starts-
data starts at offset =2015108080
8 more bytes needed
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=10
can reassemble
length of pdu= 38
Giving hint to tcp where next pdu starts--
remaining_bytes= 10
plen>remaining_bytes
Fixed len part is split, Tell dissector where data for this message starts--
length_remaining= 10,,plen= 2015108080
data starts at1 offset=2015108080
28 more bytes needed1
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=28
can reassemble
length of pdu= 1028
Giving hint to tcp where next pdu starts--
remaining_bytes= 28
plen>remaining_bytes
Fixed len part is split, Tell dissector where data for this message starts--
length_remaining= 28,,plen= 2015108080
data starts at1 offset=2015108080
1000 more bytes needed1
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=262
can reassemble
length of pdu= 262
Giving hint to tcp where next pdu starts--
remaining_bytes= 262
Final length remaining len before dissecting = 262
calling dissector
stepping to next PDU
offset = 262, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=38
can reassemble
length of pdu= 17161
Giving hint to tcp where next pdu starts--
remaining_bytes= 38
plen>remaining_bytes
Fixed len part is split, Tell dissector where data for this message starts--
length_remaining= 38,,plen= 2015108080
data starts at1 offset=2015108080
17123 more bytes needed1
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=78
can reassemble
length of pdu= 36
Giving hint to tcp where next pdu starts--
remaining_bytes= 78
Final length remaining len before dissecting = 36
calling dissector
bounds ERROR2
stepping to next PDU
offset = 36, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=42
can reassemble
length of pdu= 8
Bounds error in plen < fixed_len!!!
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Giving hint to tcp where next pdu starts--
remaining_bytes= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Giving hint to tcp where next pdu starts--
remaining_bytes= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Giving hint to tcp where next pdu starts--
remaining_bytes= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080
In starting of while loop---
length_remaining from function tvb_ensure_length_remaining=33
can reassemble
length of pdu= 33
Final length remaining len before dissecting = 33
calling dissector
stepping to next PDU
offset = 33, offset before= 2015108080

_______________________________________________________
packet-tcp.c

void
tcp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		 gboolean proto_desegment, guint fixed_len,
		 guint (*get_pdu_len)(packet_info *, tvbuff_t *, int),
		 dissector_t dissect_pdu)
{
	
  volatile int offset = 0;
  int offset_before;
  guint length_remaining;
  guint plen;
  guint length;
  tvbuff_t *next_tvb;
  proto_item *item=NULL;

  while (tvb_reported_length_remaining(tvb, offset) != 0) {
	  writeFile("In starting of while loop---\n",NULL);
    /*
     * We use "tvb_ensure_length_remaining()" to make sure there actually
     * *is* data remaining.  The protocol we're handling could conceivably
     * consists of a sequence of fixed-length PDUs, and therefore the
     * "get_pdu_len" routine might not actually fetch anything from
     * the tvbuff, and thus might not cause an exception to be thrown if
     * we've run past the end of the tvbuff.
     *
     * This means we're guaranteed that "length_remaining" is positive.
     */
    length_remaining = tvb_ensure_length_remaining(tvb, offset);
	writeFile("length_remaining from function tvb_ensure_length_remaining=%ld\n",length_remaining);

    /*
     * Can we do reassembly?
     */
    if (proto_desegment && pinfo->can_desegment) {
		writeFile("can reassemble\n",NULL);
      /*
       * Yes - is the fixed-length part of the PDU split across segment
       * boundaries?
       */
      if (length_remaining < fixed_len) {
		  writeFile("Fixedlength part is split across segment \n",NULL);
	/*
	 * Yes.  Tell the TCP dissector where the data for this message
	 * starts in the data it handed us, and how many more bytes we
	 * need, and return.
	 */
	pinfo->desegment_offset = offset;
	pinfo->desegment_len = fixed_len - length_remaining;
	writeFile("Telling dissector where data for this message starts-\n",NULL);
	writeFile("data starts at offset =%ld\n",offset);
	writeFile("%ld more bytes needed\n",pinfo->desegment_len);
	return;
      }
    }

    /*
     * Get the length of the PDU.
     */
    plen = (*get_pdu_len)(pinfo, tvb, offset);
	writeFile("length of pdu= %ld\n",plen);
    if (plen < fixed_len) {
      /*
       * Either:
       *
       *	1) the length value extracted from the fixed-length portion
       *	   doesn't include the fixed-length portion's length, and
       *	   was so large that, when the fixed-length portion's
       *	   length was added to it, the total length overflowed;
       *
       *	2) the length value extracted from the fixed-length portion
       *	   includes the fixed-length portion's length, and the value
       *	   was less than the fixed-length portion's length, i.e. it
       *	   was bogus.
       *
       * Report this as a bounds error.
       */
		writeFile("Bounds error in plen < fixed_len!!!\n",NULL);
      show_reported_bounds_error(tvb, pinfo, tree);
      return;
    }
    /*
     * Display the PDU length as a field
     */
    item=proto_tree_add_uint(pinfo->tcp_tree, hf_tcp_pdu_size, tvb, 0, 0, plen);
    PROTO_ITEM_SET_GENERATED(item);



    /* give a hint to TCP where the next PDU starts
     * so that it can attempt to find it in case it starts
     * somewhere in the middle of a segment.
     */
    if(!pinfo->fd->flags.visited && tcp_analyze_seq){
       guint remaining_bytes;
       remaining_bytes=tvb_reported_length_remaining(tvb, offset);
	   writeFile("Giving hint to tcp where next pdu starts--\n",NULL);
	   writeFile("remaining_bytes= %d\n",remaining_bytes);
       if(plen>remaining_bytes){
		   writeFile("plen>remaining_bytes\n",NULL);
          pinfo->want_pdu_tracking=2;
          pinfo->bytes_until_next_pdu=plen-remaining_bytes;
       }
    }

    /*
     * Can we do reassembly?
     */
    if (proto_desegment && pinfo->can_desegment) {
      /*
       * Yes - is the PDU split across segment boundaries?
       */
      if (length_remaining < plen) {
	/*
	 * Yes.  Tell the TCP dissector where the data for this message
	 * starts in the data it handed us, and how many more bytes we
	 * need, and return.
	 */
		  writeFile("Fixed len part is split, Tell dissector where data for this message starts--\n",NULL);
		  writeFile("length_remaining= %d,,plen= %d\n",length_remaining,(int)plen);
	pinfo->desegment_offset = offset;
	pinfo->desegment_len = plen - length_remaining;
	writeFile("data starts at1 offset=%ld\n",pinfo->desegment_offset);
	writeFile("%ld more bytes needed1\n",pinfo->desegment_len);
	return;
      }
    }

    /*
     * Construct a tvbuff containing the amount of the payload we have
     * available.  Make its reported length the amount of data in the PDU.
     *
     * XXX - if reassembly isn't enabled. the subdissector will throw a
     * BoundsError exception, rather than a ReportedBoundsError exception.
     * We really want a tvbuff where the length is "length", the reported
     * length is "plen", and the "if the snapshot length were infinite"
     * length is the minimum of the reported length of the tvbuff handed
     * to us and "plen", with a new type of exception thrown if the offset
     * is within the reported length but beyond that third length, with
     * that exception getting the "Unreassembled Packet" error.
     */
    length = length_remaining;
    if (length > plen)
	length = plen;
	writeFile("Final length remaining len before dissecting = %ld\n",length);
    next_tvb = tvb_new_subset(tvb, offset, length, plen);

    /*
     * Dissect the PDU.
     *
     * Catch the ReportedBoundsError exception; if this particular message
     * happens to get a ReportedBoundsError exception, that doesn't mean
     * that we should stop dissecting PDUs within this frame or chunk of
     * reassembled data.
     *
     * If it gets a BoundsError, we can stop, as there's nothing more to
     * see, so we just re-throw it.
     */
	writeFile("calling dissector\n",NULL);
    TRY {
      (*dissect_pdu)(next_tvb, pinfo, tree);
    }
    CATCH(BoundsError) {
		writeFile("bounds ERROR1\n",NULL);
      RETHROW;
    }
    CATCH(ReportedBoundsError) {
		writeFile("bounds ERROR2\n",NULL);
     show_reported_bounds_error(tvb, pinfo, tree);
    }
    ENDTRY;

    /*
     * Step to the next PDU.
     * Make sure we don't overflow.
     */
    offset_before = offset;
    offset += plen;
	writeFile("stepping to next PDU\n",NULL);
	writeFile("offset = %d, offset before= %d\n",offset,offset_before);
	if (offset <= offset_before){
		writeFile("offset <= offset_before",NULL);
		break;}
  }
}

--- On Sat, 3/1/08, Eli Ofenstein <eli.ofenstein@xxxxxxxxx> wrote:

> From: Eli Ofenstein <eli.ofenstein@xxxxxxxxx>
> Subject: Re: [Wireshark-dev] : Plugin dissector not called when wireshark reassembles the message
> To: "Developer support list for Wireshark" <wireshark-dev@xxxxxxxxxxxxx>
> Date: Saturday, March 1, 2008, 2:06 AM
> I have had a similar issue with my plugin.  What I see is
> the following
> behavior:
> 
> . my dissector is called at the beginning of the PDU
> . my dissector calls tcp_dissect_pdus().  The length
> retrieval function
> yields the correct value for the PDU length, which exceeds
> the size of the
> current packet.
> . tcp_dissect_pdus() notes that the PDU size exceeds the
> packet size and
> sets up the reassembly variables in the packet_info struct.
> . tcp_dissect_pdus() returns, my dissector exits.
> . Instead of returning to my dissector when the PDU is
> reassembled, the TCP
> dissector calls my dissector for each packet within the
> PDU.  Since
> the packet does not begin on a PDU start, my dissector
> discards them.
> 
> The result is similar to what has been stated here.  Each
> packet is denoted
> as being part of a reassembled PDU, but the reassembled PDU
> is never
> actually returned to the dissector, nor is the reassembly
> info (i.e. the
> source frames) ever denoted in the PDU's final packet.
> When I traced back into the TCP dissector, I noticed that
> there was never a
> non-null tcp_analysis struct associated with the
> conversation.  It was
> always null.  Since this is where flow state is stored, the
> dissector could
> never reassemble my fragmented PDUs.  I didn't get any
> further than that, as
> I got sidetracked onto other projects.
> On Fri, Feb 29, 2008 at 12:51 AM, Merlin Hooze
> <me_merlin18@xxxxxxxxx>
> wrote:
> 
> > Hello Thanks for your response,
> > The maximum lengths returned by get_myplugin_pdu_len()
> are 1028 and 17161
> > .
> > Is that might be a problem ?
> >
> > But I cant understand why the message length is
> showing that big a value
> > as the messages are quite small enough!
> >
> > Thanks
> >
> > --- On Thu, 2/28/08, Jaap Keuter
> <jaap.keuter@xxxxxxxxx> wrote:
> >
> > > From: Jaap Keuter <jaap.keuter@xxxxxxxxx>
> > > Subject: Re: [Wireshark-dev] : Plugin dissector
> not called when
> > wireshark reassembles the message
> > > To: me_merlin18@xxxxxxxxx, "Developer
> support list for Wireshark" <
> > wireshark-dev@xxxxxxxxxxxxx>
> > > Date: Thursday, February 28, 2008, 5:44 PM
> > > Hi,
> > >
> > > What does get_myplugin_pdu_len() return? I think
> this value
> > > is too high, hence the TCP dissector never sees
> the end of
> > > the payload.
> > >
> > > Thanx,
> > > Jaap
> > >
> > > Merlin Hooze wrote:
> > > > Hi,
> > > >
> > > > I have created a plugin for wireshark, which
> works
> > > fine normally but its not able to dissect when
> the message
> > > is split and reassembled by wireshark. In my
> dissector I am
> > > using the following function as below..
> > > >
> > > > tcp_dissect_pdus(message_tvb, pinfo, tree,
> TRUE, 5,
> > > >     get_myplugin_pdu_len, dissect_myplugin);
> > > >
> > > > But when i capture the trace, I can see the
> protocol
> > > as [TCP segment of a reassembled PDU] only. Looks
> like the
> > > dissector function for my plugin is not called.
> > > > I guess [TCP segment of a reassembled PDU]
> is
> > > displayed when wireshark is reassembling the
> packets. So
> > > when its reassembling then why its not calling my
> dissector
> > > after it has reassembled ?
> > > >
> > > > Any hints ?
> > > >
> > > > Thanks..
> > > >
> >
> >
> >
> > 
> ____________________________________________________________________________________
> > Be a better friend, newshound, and
> > know-it-all with Yahoo! Mobile.  Try it now.
> >
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
> >
> >
> > _______________________________________________
> >  Wireshark-dev mailing list
> > Wireshark-dev@xxxxxxxxxxxxx
> >
> http://www.wireshark.org/mailman/listinfo/wireshark-dev
> >_______________________________________________
> Wireshark-dev mailing list
> Wireshark-dev@xxxxxxxxxxxxx
> http://www.wireshark.org/mailman/listinfo/wireshark-dev


      ____________________________________________________________________________________
Looking for last minute shopping deals?  
Find them fast with Yahoo! Search.  http://tools.search.yahoo.com/newsearch/category.php?category=shopping