Wireshark-dev: Re: [Wireshark-dev] Return value of a new-style dissector
From: Peter Wu <peter@xxxxxxxxxxxxx>
Date: Wed, 25 Jun 2014 19:56:20 +0200
On Wednesday 25 June 2014 12:56:21 Evan Huus wrote:
> On Wed, Jun 25, 2014 at 12:54 PM, Evan Huus <eapache@xxxxxxxxx> wrote:
>
> > On Wed, Jun 25, 2014 at 12:32 PM, Peter Wu <peter@xxxxxxxxxxxxx> wrote:
> >
> >> Hi,
> >>
> >> Since Pascal's change ("TCP: do desegmentation sanity checks for all sub
> >> dissectors types"), the whois dissector was starting to throw:
> >>
> >> Dissector bug, protocol TCP, in packet 6:
> >> epan/dissectors/packet-tcp.c:3953:
> >> failed assertion "save_desegment_offset == pinfo->desegment_offset &&
> >> save_desegment_len == pinfo->desegment_len"
> >>
> >> That came from this part:
> >>
> >> pinfo->desegment_len = DESEGMENT_UNTIL_FIN;
> >> pinfo->desegment_offset = 0;
> >> return (0);
> >>
> >> It is likely supposed to mean "well, this packet is mine, please give all
> >> data
> >> until the connection is closed". The `return 0` is clearly wrong here. But
> >> what is the correct value?
> >>
> >> From epan/packet.h:
> >> /*
> >> * Dissector that returns:
> >> *
> >> * The amount of data in the protocol's PDU, if it was able to
> >> * dissect all the data;
> >>
> >
> > I think the above line is misleading, it should say "The amount of data in
> > the protocol's PDU, if the tvbuff contains a PDU for that protocol". So
> > tvb_captured_length is the right return value for whois, because it is the
> > amount of data (so far) claimed by the whois dissector.
Some dissectors (HTTP iirc) do repeated dissections, so this is more accurate:
"The amount of data in tvbuff that could form one or more PDUs"
> >> * 0, if the tvbuff doesn't contain a PDU for that protocol;
> >> *
> >> * The negative of the amount of additional data needed, if
> >> * we need more data (e.g., from subsequent TCP segments) to
> >> * dissect the entire PDU.
> >>
> >
> > If the tcp dissector respects this (what happens if return is negative
> > *and* pinfo->desegment_len is set???) then it should maybe do this instead
> > of setting desegment_len at all...
> >
>
> Does this mean we can get rid of the pinfo->desegment stuff once all
> dissectors are new-style?
Yes. Return -1 if you need *at least* 1 byte (like DESEGMENT_ONE_MORE_SEGMENT,
but smarter since it can then count before calling the dissector). Return
DESEGMENT_UNTIL_FIN if you want to have everything until the last byte.
Note: it should then not return tvb_captured_length(tvb).
> > */
> >> typedef int (*new_dissector_t)(tvbuff_t *, packet_info *, proto_tree *,
> >> void *);
> >>
> >> Almost all callers of call_dissector... ignore its return value, those who
> >> care seem only to be interested in a boolean (zero vs non-zero). The
> >> dissectors
> >> which use DESEGMENT_... do arbitrary things:
> >>
> >> - Return 0, this is just a plain error. See whois, finger, snmp,
> >> alljoyn, ms-mms.
> >> - Return tvb_length(tvb). See nbns
> >> - Return -pinfo->desegment_len. See ldp.
> >> - Return -1. See sigcomp, rtsp
> >> - Return -2. See fcip.
> >> - Return offset. See ssh, ssl
> >> - Return -DESEGMENT_ONE_MORE_SEGMENT (!!). jxta
> >> - Return the actual bytes that is wanted (offset_next - offset_before).
> >> See xot.
> >>
> >> (Found with `view -p $(grep -rnl DESEGMENT_ONE_MORE_SEGMENT)`)
> >>
> >> This suggests that something is wrong in the API definition. As it stands
> >> now,
> >> it really needs a boolean. Can someone clarify this? Is this a bug, an
> >> incomplete migration from the old-style dissector or a documentation
> >> issue?
> >> Did I misunderstood something?
> >>
> >
> > I'm not sure, I didn't write the new API. I think incomplete migration?
Ok, forget about the boolean. It would be really nice if desegment_len could
be dropped by fixing the return value.
Guy Harris introduced the new_dissector_t type according to git, the intent
was good, but the implementation is incomplete.
commit 193b8c9bfbd15afde08076ee1dc09abf914b9abe
Author: Guy Harris <guy@xxxxxxxxxxxx>
Date: Tue Feb 26 11:55:39 2002 +0000
Allow dissectors to be registered as "old-style" or "new-style"
dissectors. "Old-style" dissectors return nothing. "New-style"
dissectors return one of:
a positive integer, giving the number of bytes worth of data in
the tvbuff that it considered to be part of the PDU in the
tvbuff;
zero, if it didn't consider the data in the tvbuff to be a PDU
for its protocol;
a negative integer, giving the number of additional bytes worth
of data in needs to get the complete PDU (for use with
fragmentation/segmentation when the length of the PDU isn't
known to the protocol atop the one the dissector is dissecting).
Have "call_dissector()" return the return value of new-style dissectors,
and the length of the tvbuff handed to it for old-style dissectors.
Have "dissector_try_port()" return FALSE if the subdissector is a
new-style dissector and returned 0.
Make the EAP dissector a new-style dissector, and have a "EAP fragment"
dissector that is also a new-style dissector and handles fragmentation
of EAP messages (as happens above, for example, RADIUS). Also, clean up
some signed vs. unsigned comparison problems.
Reassemble EAP-Message AVPs in RADIUS.
svn path=/trunk/; revision=4811
Kind regards,
Peter
- References:
- [Wireshark-dev] Return value of a new-style dissector
- From: Peter Wu
- Re: [Wireshark-dev] Return value of a new-style dissector
- From: Evan Huus
- [Wireshark-dev] Return value of a new-style dissector
- Prev by Date: Re: [Wireshark-dev] Return value of a new-style dissector
- Next by Date: Re: [Wireshark-dev] DCERPC generated files
- Previous by thread: Re: [Wireshark-dev] Return value of a new-style dissector
- Next by thread: Re: [Wireshark-dev] [Wireshark-commits] master 8cde7a7: Boost the maximum packet size to 131072.
- Index(es):