Ethereal-dev: Re: [Ethereal-dev] Heuristic dissectors do not seem to show up in the dissect

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <guy@xxxxxxxxxx>
Date: Mon, 11 Mar 2002 15:45:18 -0800
On Tue, Mar 12, 2002 at 10:05:35AM +1030, Richard Sharpe wrote:
> It would seem that dissectors that are added using 
> heur_dissector_add("tcp", dissect_tup, proto_tup/*[1]*/);
> 
> do not show up in the dissect as dialog box. I am not sure if there is a 
> technical reason for that ATM (rummage, rummage),

Heuristic dissectors don't have the same calling sequence as
non-heuristic dissectors, so you can't plug a heuristic dissector into a
dissector table.

I have been thinking about changing the dissector API to make dissectors
return an "int" value, which is one of:

	positive integer - the number of bytes from the tvbuff handed to
	    the dissector that are part of the PDU being dissected (as
	    opposed to padding, subsequent PDUs in a TCP segment, etc.)

	zero - the tvbuff does not contain something the dissector
	    thinks could be a PDU for its protocol (note that a
	    dissector should *not* blithely return 0 for any error;
	    after all, one of the purposes of a sniffer program is to
	    track down network problems, and those can be caused by
	    machines sending out malformed packets - this should only be
	    used for packets that are *so* obviously wrong that they
	    have to be for some other protocol)

	negative integer - the number of additional bytes of data needed
	    to provide a fully-reassembled PDU (e.g., for TCP
	    desegmentation).

If that were done, heuristic dissectors would have the same calling
sequence.

I have some of the infrastructure in place for this.  "call_dissector()"
now returns an "int", and there's a "new_dissector_t" type and
"new_register_dissector()" to register "new-style" dissectors. 
Dissector handles have an "old vs. new" flag, "call_dissector()" will,
for old-style dissectors, just return the length of the tvbuff handed to
it.

The only new-style dissectors are the EAP and "EAP fragment" dissector;
the "EAP fragment" dissector is used for EAP fragments inside RADIUS,
and the RADIUS dissector treats a negative return value from
"call_dissector()" as telling it how much more data, from subsequent EAP
fragments, is needed.

Converting all dissectors would involve changing a fair bit of code, but
it could be done incrementally.  If that makes sense, I'd be tempted to
rename "dissector_t" to "old_dissector_t", and rename
"register_dissector()" to "old_register_dissector()", to deprecate them,
and rename "new_dissector_t" and "new_register_dissector()" to
"dissector_t" and "register_dissector()".

The positive and negative integer returns could possibly be used to
provide common code for doing TCP desegmentation and support for
multiple PDUs in a TCP segment.

The zero return could be used to handle obvious packet/protocol
mismatches; this might clean up some cases where some packet happens to
be sent from or to a port for some other protocol, and allow the packet
to be handed to the dissector for the other port, or handed to a
heuristic dissector.

Another possibility would be to have a heuristic dissector have both a
"test" and a "dissect" routine, with the former returning a Boolean and
dissecting nothing, and the latter returning nothing and dissecting. 
That wouldn't allow non-heuristic dissectors to return a "that's not one
of mine" indication, though, and might require the dissector to
duplicate some effort already done by the test routine (the ONC RPC
dissector matches responses with requests as part of the heuristic
test).