Ethereal-dev: [ethereal-dev] TFTP Dissect routine done, plus other thoughts

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

From: Richard Sharpe <sharpe@xxxxxxxxxx>
Date: Sat, 13 Feb 1999 23:45:43 +1000
Hi,

well, it is amazing how much you can get done when you have four hours in
an airport.

I was on my way to Tasmania to give a couple of presentations on Monday
(one on Samba and one on IP Security) and because of the ticket I
purchased, I had four hours to burn.

Since I need more protocols dissected (see below) I started hacking on
Ethereal.

The first cab off the rank was TFTP, because in a sense it is a bit
difficult, in that the port numbers change:

  1. Starts out highport1 to port 69
  2. Response is highport2 to highport1
  3. Subsequent requests/responses are highport1 to highport2

This seemed to need a dispatch table.  For the moment I have hacked some
things in and will send the patches to Guy Harris, as I do not have access
to the source tree.

Here is what I have added:

  1. In ethereal, ethereal_proto_init(), a routine for initializing all
     proto related things.  Here we would call any known proto_init
     routines, and any pulled in by dlopen etc.

  2. A dispatch table, as a hash table udp_table_hash[256], which points
     to structures of:

          int proto
          void (*dissect)();
	   struct hash_struct *next;

  3.  In dissect_udp, in the switch (which is naughty of me, I will have to
      go back and clean it up) I added a case UDP_TFTP which calls
      dissect_tftp, but first adds the other port to the hash table

  4.  In the default case, we check to see if the protocol we are dealing
      with is in the dispatch table, and if so, we add the other port
      (respone port) if needed, and then call the dissect routine.

What happens then is:

1 When first TFTP request is seen, it is identified by port 69, and then
  the highport is installed as a port of interest with dissect_tftp as the
  dissection routine.

2 When that highport is seen again, we first check if the other port in
  the UDP is known about in the hash table, and if not we install that into
  the hash table with a dissect routine of dissect_tftp.

Now, it all seems to work, but I need to test some more.

However, what I see now is needed, and Guy has mentioned this is the
following.  All the port based protocols (and maybe more) need an
additional structure passed to them, of private info.

Why is this? Well, when you are trying to dissect protocols like HTTP, FTP,
SMTP, etc, you have to know which is the source port and which is the
destination port so you can figure out if it was a request or response.

Eg, if you set things up so that you can handle HTTP requests to SQUID say
(wich go to port 3128 by default) you can piggyback off of the HTTP
decoding stuff, as long as you can add 3128 to the table.

But to simplify decoding etc, you need to know whether or not 3128 was in
the source port or destination port.

I propose that we add an extra parameter to the dissect routines:

dissect_xxx(u_char *pd, int offset, frame_data *fd, priv_data *priv,
GtkTree *tree)

where the priv_data can be anything that the dissect routine needs.

We also need to think about state so that when you are handling long bits
of data split across TCP segments, you can relate them to each other.

I have added all my hash table handling routines to packet-udp.c, but they
should be hoisted into their own file I sespect.  I am waiting on feedback.


Regards
-------
Richard Sharpe, sharpe@xxxxxxxxxx, NIC-Handle:RJS96
NS Computer Software and Services P/L, 
Ph: +61-8-8281-0063, FAX: +61-8-8250-2080, 
Samba (Team member), Linux, Apache, Digital UNIX, AIX, C, ...