Wireshark-dev: Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
From: Richard van der Hoff <richardv@xxxxxxxxxxxxx>
Date: Sat, 03 Feb 2007 05:16:51 +0000
FEH! Now with the attachment. Sorry. Richard van der Hoff wrote:
Martin Mathieson wrote:Richard, I remember struggling with this when writing the Microsoft Media Server protocol (packet-ms-mms.c), but it did seem to work.Thanks for that, Martin; however, I've taken a look at it, and I'm really pretty sure that it doesn't work with multiple PDUs in the same packet. I even went so far as to mock up a trace with some ms-mms data packets in it - I'm sorry if you thought it worked, but it doesn't for me.I've had a good look at the code in packet-tcp.c, and whilst it's somewhat impenetrable, I've come to the conclusion that it just doesn't support multiple pdus as described.That's not entirely unreasonable in itself; my objection is solely to the fact that README.developer is completely misleading. In fact, even the example dissect_cstr won't work on the tcp dissector, because if you set desegment_len=1 the tcp dissector believes that you know what you are doing and doesn't let you change your mind later.Furthermore, 2.7.2 says that you can set desegment_len=-1; that doesn't work either, because the tcp dissector expects DESEGMENT_ONE_MORE_SEGMENT, which is 0x0fffffff, which is nowhere near -1.In short, I think the relevant section of README.developer needs a rewrite. I attach a patch - comments welcome.Regards, Richard
-- Richard van der Hoff <richardv@xxxxxxxxxxxxx> Telephony Gateways Project Manager Tel: +44 (0) 845 666 7778 http://www.mxtelecom.com
Index: README.developer =================================================================== --- README.developer (.../svn+ssh://svn/svn-ethereal/mirror/ethereal/trunk/doc/README.developer) (revision 11728) +++ README.developer (.../README.developer) (working copy) @@ -3287,37 +3287,33 @@ The second reassembly mode is preferred when the dissector cannot determine how many bytes it will need to read in order to determine the size of a PDU. +It may also be useful if your dissector needs to support reassembly from +protocols other than TCP. -This reassembly mode relies on Wireshark's mechanism for processing -multiple PDUs per frame. When a dissector processes a PDU from a tvbuff -the PDU may not be aligned to a frame of the underlying protocol. -Wireshark allows dissectors to process PDUs in an idempotent -way--dissectors only need to consider one PDU at a time. If your -dissector discovers that it can not process a complete PDU from the -current tvbuff the dissector should halt processing and request -additional bytes from the lower level dissector. +Your dissect_PROTO will initially be passed a tvbuff containing the payload of +the first packet. It should dissect as much data as it can, noting that it may +contain more than one complete PDU. If the end of the provided tvbuff coincides +with the end of a PDU then all is well and your dissector can just return as +normal. (If it is a new-style dissector, it should return the number of bytes +successfully processed.) -Your dissect_PROTO will be called by the lower level dissector whenever -sufficient new bytes become available. Each time your dissector is called it is -provided a different tvbuff, though the tvbuffs may contain data that your -dissector declined to process during a previous call. When called a dissector -should examine the tvbuff provided and determine if an entire PDU is available. -If sufficient bytes are available the dissector processes the PDU and returns -the length of the PDU from your dissect_PROTO. +If the dissector discovers that the end of the tvbuff does /not/ coincide with +the end of a PDU, (ie, there is half of a PDU at the end of the tvbuff), it can +indicate this to the parent dissector, by updating the pinfo struct. The +desegment_offset field is the offset in the tvbuff at which the dissector will +continue processing when next called. The desegment_len field should contain +the estimated number of additional bytes required for completing the PDU. Next +time your dissect_PROTO is called, it will be passed a tvbuff composed of the +end of the data from the previous tvbuff together with desegment_len more bytes. -Completion of a PDU is signified by dissect_PROTO returning a positive -value. The value is the number of bytes which were processed from the -tvbuff. If there were insufficient bytes in the tvbuff to complete a -PDU then dissect_PROTO must update the pinfo structure to indicate that -more bytes are required. The desegment_offset field is the offset in -the tvbuff at which the dissector will continue processing when next -called. The desegment_len field should contain the estimated number of -additional bytes required for completing the PDU. The dissect_PROTO -will not be called again until the specified number of bytes are -available. pinfo->desegment_len may be set to -1 if dissect_PROTO -cannot determine how many additional bytes are required. Dissectors -should set the desegment_len to a reasonable value when possible rather -than always setting -1 as it will generally be more efficient. +If the dissector cannot tell how many more bytes it will need, it should set +desegment_len=DESEGMENT_ONE_MORE_SEGMENT; it will then be called again as soon +as any more data becomes available. Dissectors should set the desegment_len to a +reasonable value when possible rather than always setting +DESEGMENT_ONE_MORE_SEGMENT as it will generally be more efficient. Also, you +*must not* set desegment_len=1 in this case, in the hope that you can change +your mind later: once you return a positive value from desegment_len, your PDU +boundary is set in stone. static hf_register_info hf[] = { {&hf_cstring, @@ -3327,7 +3323,7 @@ }; /** -* Dissect a buffer containing a C string. +* Dissect a buffer containing C strings. * * @param tvb The buffer to dissect. * @param pinfo Packet Info. @@ -3336,32 +3332,38 @@ static void 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); + while(offset < tvb_reported_length(tvb)) { + 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; - } + if( -1 == len ) { + /* we ran out of data: ask for more */ + pinfo->desegment_offset = offset; + pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; + return; + } + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_set_str(pinfo->cinfo, COL_INFO, "C String"); + } + + len += 1; /* Add one for the '\0' */ - if (check_col(pinfo->cinfo, COL_INFO)) { - col_set_str(pinfo->cinfo, COL_INFO, "C String"); + if (tree) { + proto_tree_add_item(tree, hf_cstring, tvb, offset, len, FALSE); + } + offset += (guint)len; } - len += 1; /* Add one for the '\0' */ - - if (tree) { - proto_tree_add_item(tree, hf_cstring, tvb, offset, len, FALSE); - } + /* if we get here, then the end of the tvb coincided with the end of a + string. Happy days. */ } -This simple dissector will repeatedly return -1 requesting one more byte until -the tvbuff contains a complete C string. The C string will then be added to the -protocol tree. Unfortunately since there is no way to guess the size of C -String without seeing the entire string this dissector can never request more -than one additional byte. +This simple dissector will repeatedly return DESEGMENT_ONE_MORE_SEGMENT +requesting more data until the tvbuff contains a complete C string. The C string +will then be added to the protocol tree. Note that there may be more +than one complete C string in the tvbuff, so the dissection is done in a +loop. 2.8 ptvcursors.
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- From: Richard van der Hoff
- Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- References:
- Re: [Wireshark-dev] Multiple pdus atop TCP -- a lie in README.developer?
- From: Richard van der Hoff
- Re: [Wireshark-dev] Multiple pdus atop TCP -- a lie in README.developer?
- From: Richard van der Hoff
- Re: [Wireshark-dev] Multiple pdus atop TCP -- a lie in README.developer?
- From: Martin Mathieson
- Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- From: Richard van der Hoff
- Re: [Wireshark-dev] Multiple pdus atop TCP -- a lie in README.developer?
- Prev by Date: Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- Next by Date: [Wireshark-dev] IS-41 ANSI-MAP
- Previous by thread: Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- Next by thread: Re: [Wireshark-dev] [PATCH] Multiple pdus atop TCP -- a lie in README.developer?
- Index(es):