Ethereal-dev: Re: [ethereal-dev] TCP/UDP protcol dissector lookups

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: Thu, 2 Mar 2000 00:42:22 -0800
> The TCP / UDP dissectors only watch ports, right? Is there a way to add
> host/port combinations in the hash?

I'm not sure that's the best way to do it; if the goal is to handle a
source host/source port/destination host/destination port quad, the
conversation code might be what we'd want to use, and have separate
checks for generic ports and specific conversations.

> BTW
> In NetMon dissectors, if a frame is encountered a protocol is asked
> (based on the port) whether it's capable of dissecting _that_ particular
> frame or not. Depending on this answer the dissecting routine 
> receives the frame or not. How does Ethereal handle this situation?

The NetMon documentation I have describes two ways of selecting which
dissector to use - "FollowSet Parsers", where a series of dissectors are
called, and they either return an indication of whether they recognize
the frame as being a frame for their protocol or not, and if a dissector
recognizes the frame as being for its protocol, NetMon doesn't call any
subsequent dissectors in the set, and "HandoffSet Parsers", where the
dissector to call next is based on a field such as a port number.

We don't currently have a formal framework of that sort, but most of our
parsers amount to "HandoffSet Parsers", i.e. we switch on an Ethertype,
or a SAP value, or a TCP/UDP port number, or....

There are *ad hoc* "FollowSet Parsers", e.g.  we handle ONC RPC in that
fashion - the TCP and UDP dissectors call the ONC RPC dissector, and if
the ONC RPC dissector returns TRUE, no further checks of the packet type
are done, and no other dissectors are called.

NetMon's scheme involves three routines per protocol:

	a routine that takes a frame and determines whether it's a frame
	for the protocol in question - if it's part of a follow set,
	it'd have to check the data for that protocol and return an
	indication of whether it matches or not - and it can also return
	a handle for the protocol inside it (e.g., the TCP dissector
	would, instead of calling the dissector for the next protocol,
	hand back, through a pointer argument, a handle for that
	protocol);

	a routine that constructs the equivalent of the protocol tree,
	*but* doesn't put any text into it (there's no precise
	equivalent to "proto_tree_add_text()" - *all* entries in the
	protocol tree need to have an equivalent of a field);

	a routine that takes a list of entries in the equivalent of the
	protocol tree and fills in the text to be displayed.

My suspicion is that the way NetMon handles a capture is:

	it makes a pass through the file, figuring out what the
	protocols are for each packet, but *not* doing any dissection,
	and builds a list of packets;

	it builds a "virtual" CList equivalent, so that, when a line in
	the packet list is to be displayed, the routine to construct the
	equivalent of the protocol tree, and to fill in the text, is
	called, and the columns in the line come from the data the
	dissector fills in (the equivalent of the "Info" column is
	filled in with the equivalent of the text for the topmost
	protocol-tree entry for the topmost protocol);

	if you click on a packet, it builds the protocol tree and fills
	in the text (assuming it doesn't just remember what was built
	when that line was displayed);

	when packets are printed, it builds the protocol tree and fills
	in the text for each packet printed;

	if you do packet filtering or searches, it builds the protocol
	tree, but presumably doesn't bother filling in the text for it,
	as it doesn't need that.