Ethereal-dev: Re: [ethereal-dev] Plugin Questions

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

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Fri, 5 May 2000 02:49:51 -0700
> I have some stuff on which I've been working, to allow what I've been
> calling "heuristic" dissectors to be added; "heuristic" dissectors are
> in lists, rather than hash tables, and the list is handled by calling
> each of the dissectors in it until one of them returns TRUE - this is
> for dissectors that have to look at the payload in order to decide
> whether a frame contains a packet for its protocol, which currently
> includes:
> 
> 	your H1 dissector;
> 
> 	the ONC RPC dissector;
> 
> 	the GIOP and Yahoo Messenger dissectors.
> 
> I'll look into checking that in.

Done.

A list of heuristic dissectors is a "heur_dissector_list_t"; a dissector
that includes a list of heuristic subdissectors would declare it as
something such as

	static heur_dissector_list_t heur_subdissector_list;

and would register it with a call such as

	register_heur_dissector_list(<name>, &heur_subdissector_list);

where <name> is a string giving the name of the list.

A heuristic subdissector would be added to that list in a "register
handoff" routine:

	void
	proto_reg_handoff_foo(void)
	{
		heur_dissector_add(<name>, dissect_foo);
	}

"dissect_foo()" would take the usual "const u_char *pd, int offset,
frame_data *fd, proto_tree *tree" arguments, and would return a
gboolean.  It should look at the payload, starting at "pd[offset]", to
see if it's a packet for the protocol it dissects; if it is, it should
dissect the payload and return TRUE, otherwise it shouldn't dissect
anything and should just return FALSE.

A dissector with a list of heuristic dissectors would check the
dissectors in that list by calling "dissector_try_heuristic()", passing
it as arguments the heuristic dissector list, the "pd" argument it was
passed, the offset of the first byte of payload, the "fd" argument it
was passed, and the "tree" argument it was passed. 
"dissector_try_heuristic()" returns TRUE if one of the heuristic
dissectors in the list accepted the packet (in which case the payload
has been dissected) and FALSE if none of the heuristic dissectors in the
list accepted the packet (in which case the payload has not yet been
dissected).

The TCP dissector now uses it, as does the COTP dissector.  The TCP
dissector checks that list after checking for:

	conversations with dissectors;

	ONC RPC (which is not checked as a regular heuristic dissector,
	because ONC RPC should probably be checked *before* checking for
	well-known ports, as

		1) there's no guarantee that an ONC RPC service will
		   avoid using all well-known TCP ports for which
		   Ethereal has dissectors

	and

		2) the test for ONC RPC packets is *probably* strong
		   enough not to get a false hit for a packet that
		   really *is* intended for one of those well-known
		   ports);

	ports registered with TCP.

The GIOP and Yahoo Messenger dissectors are now heuristic dissectors,
registered with TCP.

The COTP dissector checks that list *if* the COTP packet was
encapsulated in a CLNP packet using the Inactive Subset of CLNP; given
that we *currently* check for the Sinec H1 protocol only for COTP
packets encapsulated in CLNP packets using the Inactive Subset, that's
the only way to make the Sinec H1 dissector a heuristic dissector, but
if the other dissector Gerrit wants to register with COTP isn't so
encapsulated, either

	1) we need to call the Sinec H1 dissector for *all* COTP
	   packets, not just those so encapsulated, and perhaps inform
	   it by some other means that the Inactive Subset is being used
	   (in which case, if the Inactive Subset *isn't* used for this
	   packet, the H1 dissector would just return FALSE)

or

	2) we need to have an additional separate heuristic dissector
	   list for COTP packets not so encapsulated.