Wireshark mailing list archives
Re: Return value of a new-style dissector
From: Peter Wu <peter () lekensteyn nl>
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 () gmail com> wrote:On Wed, Jun 25, 2014 at 12:32 PM, Peter Wu <peter () lekensteyn nl> 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 () alum mit edu> 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 ___________________________________________________________________________ Sent via: Wireshark-dev mailing list <wireshark-dev () wireshark org> Archives: http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-request () wireshark org?subject=unsubscribe
Current thread:
- Return value of a new-style dissector Peter Wu (Jun 25)
- Re: Return value of a new-style dissector Peter Wu (Jun 25)
- Message not available
- Re: Return value of a new-style dissector Evan Huus (Jun 25)
- Re: Return value of a new-style dissector Peter Wu (Jun 25)
- Re: Return value of a new-style dissector Evan Huus (Jun 25)
- Message not available
- Re: Return value of a new-style dissector Evan Huus (Jun 25)