Ethereal-dev: Re: [Ethereal-dev] referencing specific tcp protocol data

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: Wed, 3 Apr 2002 14:16:31 -0800
On Wed, Apr 03, 2002 at 12:06:59PM +0100, Phil Williams wrote:
> Right, I've been on the lookout for these header_field_info pointers as
> they seem to be the key to achieving what I want to do.
> I have been looking in packet-tcp.c, but am confused as to what they
> look like.

You won't find them in there.

What you *will* find are the "hf_" numbers.

> A lot of variables are dclared at the start of the file e.g.
> static int hf_tcp_hdr_len = -1;
> These only seem to be used in registering the protocol.

No, they're used when putting entries into the protocol tree.

> Where abouts is the "hf_" number for a field declared?

It's *declared* - or, rather, defined - in the dissector, in statements
such as

	static int hf_tcp_hdr_len = -1;

However, it's assigned its value...

> or is this done
> at run-time when the protocol is registered?

...at run time when the protocol is registered.

> Is the line:
> struct tcpinfo *tcpinfo = pinfo->private
> where everything (i.e. the header_field_info pointers) are made private
> to the dissector?

The TCP dissector does not have the header_field_info pointers, so it
cannot export them, so, no, that's not the line.

The line to which you're referring merely fetches a pointer that's set
*elsewhere*, in "dissect_tcp()":

	  pinfo->private_data = &tcpinfo;

A "struct tcpinfo" contains a small amount of data supplied to
dissectors called from the TCP dissector.  That information isn't
available to arbitrary pieces of code.

> How difficult would it be (if I can find them) to export the
> header_field_info pointer information?

The right way to export that information is, as noted in earlier mail,
to add a routine to "epan/proto.c" that takes, as an argument, a "const
char *" pointing to the name of a field, and returns either

	a "header_field_info" pointer for that field, if such a field
	exists;

	a null pointer, if it doesn't.

The simplest implementation would just do a linear search through all
registered header fields, using a loop similar to the loop in
"proto_registrar_dump()", searching for a field whose "name" field
matches the specified one.

If the routine to fetch a field by name is only called a few times
(i.e., if code that uses it fetches those fields when that code is
initialized, and remembers the pointers it fetched), that *might* not be
too bad.

If it is too slow, however, a hash table or other data structure to
permit faster lookup would be needed.  The routine
"proto_register_field_init()" would update that data structure.