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: Mon, 8 Apr 2002 14:14:01 -0700
On Mon, Apr 08, 2002 at 03:09:09PM +0100, Phil Williams wrote:
> I have made a routine in epan/proto.c that takes in a const char *
> pointing to a name of a field (eg "tcp.seq").
> The routine finds the "hf_" number of the field, then uses
> proto_registrar_get_nth()
> with this number as the argument to return a header_field_info pointer.

Actually, it might be more efficient to have the routine directly find
the "header_field_info" pointer rather than finding the hf_ number and
looking it up, but that's a start.

Pleas send us that code, so we can make it a standard part of Ethereal,
so that you don't have to keep modifying Ethereal as each new release
comes out.

> Now I have enough information to access the data I require, right?

That plus the protocol tree, yes.

> I loop through all packets, using a loop like the one in "print_packets"
> in file.c

Actually, as per earlier mail, I'd suggest using a loop like the one in
"ph_stats_new()" in "proto_hier_stats.c".

> Now I am not sure exactly how I reference the data I want.  Assuming I
> have called my routine to get the header_field_info pointer, and I call
> this pointer "*ptr"
> 
> Do i construct the tree using:

> ---------------------------------------------------
> 
>   protocol_tree = proto_tree_create_root();
>   edt = epan_dissect_new(true,true);

No, you'd do

	edt = epan_dissect_new(TRUE, FALSE);

as you don't need to make the protocol tree visible - "visible" means
that the text strings that would show up in the second pane in Ethereal,
or in "tethereal -V" output", are generated, and you don't need that.

>   /* How do I retrieve my data here?, in this case the tcp sequence
>    * number? I have the pointer, *ptr, found using
>    * proto_registrar_get_nth(x);
>    * where x is the "hf_" number of the field
>    */

See "process_tree()" in "proto_hier_stats.c" and the routines it calls.

You'd do something similar, except that you want to look for nodes
*under* IP or TCP nodes (an IP or TCP node has "finfo->hfinfo" equal to
the header_field_info pointer for "ip" or "tcp"), and process those
nodes if their "finfo->hfinfo" pointers match the header_field_info
pointers for the fields (e.g., "tcp.seq") you're looking for.

I'd be inclined to look for IP and TCP nodes only at the top level of
the protocol tree, so that you don't, for example, process IP or TCP
headers in the payload of ICMP "unreachable" messages (which contain
part of the offending packet).

(See my earlier mail on this.)

If you find one of the nodes under IP or TCP, you'd get the value of the
item for that node with, say

	fvalue_get_integer(finfo->value);

(as per Gilbert's earlier mail).

"finfo" would be set from

	finfo = PITEM_FINFO(ptree_node);

as is done in the "proto_hier_stats.c" code.

>   protocol_tree_free(protocol_tree);

No, you'd want to free the result of "epan_dissect_new()", with

	epan_dissect_free(edt);

That will free the protocol tree *and* other stuff as well.