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: Sat, 18 Mar 2000 00:58:42 -0800
An issue brought up by Gilbert in mail to me a while ago (which he sent
to the list inside a later message):

  Date: Fri, 17 Sep 1999 07:41:22 -0500
  From: Gilbert Ramirez <gram@xxxxxxxxxx>
  Subject: TCP, HTTP
  To: guy@xxxxxxxxxx
  Cc: gramirez@xxxxxxxxxx

  What's TCP port 631?

  } else if (PORT_IS(TCP_PORT_HTTP) || PORT_IS(TCP_ALT_PORT_HTTP)
              || PORT_IS(631))
        dissect_http(pd, offset, fd, tree);

  Last night I was thinking about how to handle these "hand-offs", or how
  one protocol hands off processing to the next protocol. There could
  be some functionality added to the protocol registry, or an entirely new
  section of code, that allows protocols to register the fact that they wish
  to be called under certain circumstances.

  For example, the proto_register_http() function could say:

	proto_register_handoff(proto_http, "tcp.port", TCP_PORT_HTTP);
	proto_register_handoff(proto_http, "tcp.port", TCP_ALT_PORT_HTTP);
	proto_register_handoff(proto_http, "tcp.port", 631);

  I think it might be a good idea to use strings like "tcp.port" rather than
  protocol numbers (proto_tcp) because one protocol in particular, IPX, uses
  two different fields to determine who to call next. If the ipx type is a
  certain value, it calls some dissectors, otherwise if the ipx port is
  a certain value, it calls other dissectors.  When showing the field name
  as a string, I'm not suggesting that we use dfilters, but simply have
  proto_register_handoff() use that string to lookup the protocol an
  field.  We could use the variable that holds the value of that field:
	proto_register_handoff(proto_http, hf_tcp_port, TCP_PORT_HTTP);

  But then hf_tcp_port would have to be global.  Using strings would be
  easier for a user interface allowing the user to select TCP and UDP
  ports and which dissecters should get called, and in the future for any
  type of module system that we implement.  The dissector module can
  plug-in to the processing stream via proto_register_handoff().

  If the code is general enough, every dissector would be able to use it
  to determine which dissector to call next. In the TCP module we might say:

	DissectorFunc next_dissector;
	next_dissector = proto_lookup_handoff(hf_tcp_port, TCP_PORT_HTTP);

	(inside the TCP dissector there's no reason not to use hf_tcp_port)

  Just some ideas,

  --gilbert

As noted, IPX needs more than one hash table - one for the packet type
("ipx.packet_type"), and one for the destination socket
("ipx.dst.socket").

I suspect that if we replaced "find_proto_id()" with a routine that
takes a field name as an argument, looks it up in the *complete* list of
hfinfo structures (not just in the list of protocols) and returns either
NULL (if not found) or "hfinfo->sub_dissectors" for that field (if
found), that'd let us handle that case.

Presumably, TCP and UDP would register their hash table with "tcp.port"
and "udp.port", respectively, rather than with both "tcp.srcport" and
"tcp.dstport", and with both "udp.srcport" and "udp.dstport",
respectively.