Ethereal-dev: RE: [ethereal-dev] conversation wildcard entry

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

From: Jeff Foster <jfoste@xxxxxxxxxxxx>
Date: Thu, 28 Sep 2000 10:49:29 -0500
> The basic idea is to create a conversation with either source or 
> destination values set to null.  For example, set the destination to
> null.  During the conversation lookup routine check for a full 
> conversation, match both source and destination. Then check for a 
> 'one sided conversation' by testing both source and destination 
> as the destination value with the source set to null.  The fits into
> the current conversation code and shouldn't impose to much overhead
> during the conversation lookup.  

> Long term, users could use this feature to define the protocol for 
> non-standard ports on their servers and ethereal would correctly 
> dissect the traffic.

I think that this will work..

Changes to the conversation code to allow the destination host and/or port
to be anything -

In conversation.h

#define NO_DST_ADDR 0x80000
#define NO_DST_PORT 0x40000

conversation_t *
conversation_new(address *src, address *dst, int ptype,
    guint32 src_port, guint32 dst_port, void *data);

Notice that the ptype value has been changed from port_type to int. 
This will allow a dissector to create a conversation with the destination
host and/or port as a undefined value i.e.

conversation_new( src_addr, NULL, PT_TCP || NO_DST_ADDR || NO_DST_PORT,
src_port, NULL, NULL);


In conversation.c

Change hash code to consider the new flags...

static guint 
conversation_hash(gconstpointer v)
{
	conversation_key *key = (conversation_key *)v;
	guint hash_val;
	int i;

	hash_val = 0;
	for (i = 0; i < key->src.len; i++)
		hash_val += key->src.data[i];
	hash_val += key->port_src;

	if ( ! ( key->ptype & ANY_DST_ADDR)) 
		for (i = 0; i < key->dst.len; i++)
			hash_val += key->dst.data[i];

	if ( ! (key->ptype & ANY_DST_PORT))
	 	hash_val += key->port_dst;

	return hash_val;
}


Note the destination address and port tests include a test for the 
allow any flag in the following code -


static gint
conversation_equal(gconstpointer v, gconstpointer w)
{
	conversation_key *v1 = (conversation_key *)v;
	conversation_key *v2 = (conversation_key *)w;

	int port = v1->ptype && 0x0fff;	/* remove wildcard bits */

	if ((v1->ptype && 0x0fff) != v2->ptype)
		return 0;	/* different types of port */

	/*
	 * Are the first and second source ports the same, the first and
	 * second destination ports the same, the first and second source
	 * addresses the same, and the first and second destination
	 * addresses the same?
	 */
	if (v1->port_src == v2->port_src &&
	    ((v1->ptype & NO_DST_PORT) || v1->port_dst == v2->port_dst) &&
	    v1->src.type == v2->src.type &&
	    v1->src.len == v2->src.len &&
	    memcmp(v1->src.data, v2->src.data, v1->src.len) == 0 &&
	    ((v1->ptype & NO_DST_ADDR) || (v1->dst.type == v2->dst.type &&
	    v1->dst.len == v2->dst.len &&
	    memcmp(v1->dst.data, v2->dst.data, v1->dst.len) == 0))) {
		/*
		 * Yes.  It's the same conversation, and the two
		 * address/port pairs are going in the same direction.
		 */
		return 1;
	}

... repeat for the next conditional test.


Question/comments are welcome and expected.

Jeff Foster
jfoste@xxxxxxxxxxxx