Add comments about nettl support.
[obnox/wireshark/wip.git] / conversation.c
index 0cef652d2e25622c1d9f8e8ddf7568b0f6846fff..497e80d40c4b45a3c055bc430a2435c46a30f6cb 100644 (file)
@@ -1,7 +1,7 @@
 /* conversation.c
  * Routines for building lists of packets that are part of a "conversation"
  *
- * $Id: conversation.c,v 1.1 1999/10/22 07:17:28 guy Exp $
+ * $Id: conversation.c,v 1.6 2000/01/05 21:48:16 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #include <string.h>
 #include <glib.h>
 #include "packet.h"
+#include "conversation.h"
 
 static GHashTable *conversation_hashtable = NULL;
 static GMemChunk *conversation_key_chunk = NULL;
-static GMemChunk *conversation_val_chunk = NULL;
+static GMemChunk *conversation_chunk = NULL;
 
 typedef struct conversation_key {
        struct conversation_key *next;
        address src;
        address dst;
        port_type ptype;
-       guint16 port_src;
-       guint16 port_dst;
+       guint32 port_src;
+       guint32 port_dst;
 } conversation_key;
 
 /*
@@ -60,11 +61,6 @@ typedef struct conversation_key {
  */
 static conversation_key *conversation_keys;
 
-typedef struct conversation_val {
-       struct conversation_val *next;
-       guint32 index;
-} conversation_val;
-
 static guint32 new_index;
 
 static int conversation_init_count = 200;
@@ -78,70 +74,50 @@ conversation_equal(gconstpointer v, gconstpointer w)
        conversation_key *v1 = (conversation_key *)v;
        conversation_key *v2 = (conversation_key *)w;
 
-       /*
-        * We assume that a source and a destination address for a given
-        * packet in a conversation have the same type.
-        */
-       if (v1->src.type != v2->src.type)
-               return 0;       /* different types of addresses */
-
        if (v1->ptype != v2->ptype)
                return 0;       /* different types of port */
 
-       if (v1->src.len == v2->src.len &&
-           memcmp(v1->src.data, v2->src.data, v1->src.len) == 0) {
+       /*
+        * 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->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->dst.type == v2->dst.type &&
+           v1->dst.len == v2->dst.len &&
+           memcmp(v1->dst.data, v2->dst.data, v1->dst.len) == 0) {
                /*
-                * The first and second source addresses are the same.
+                * Yes.  It's the same conversation, and the two
+                * address/port pairs are going in the same direction.
                 */
-               if (v1->dst.len == v2->dst.len &&
-                   memcmp(v1->dst.data, v2->dst.data, v1->dst.len) == 0) {
-                       /*
-                        * The first and second destination addresses
-                        * are the same, so they're both going from
-                        * the same machine and they're both going to
-                        * the same machine.
-                        */
-                       if (v1->port_src == v2->port_src &&
-                           v1->port_dst == v2->port_dst) {
-                               /*
-                                * The first and second source ports
-                                * are the same, and the first and second
-                                * destination ports are the same, so
-                                * it's the same conversation, and the two
-                                * address/port pairs are going in the same
-                                * direction.
-                                */
-                               return 1;
-                       }
-               }
-       } else if (v1->src.len == v2->dst.len &&
-           memcmp(v1->src.data, v2->dst.data, v1->src.len) == 0) {
+               return 1;
+       }
+
+       /*
+        * Is the first source port the same as the second destination
+        * port, the first destination port the same as the first
+        * source port, the first source address the same as the second
+        * destination address, and the first destination address the
+        * same as the second source address?
+        */
+       if (v1->port_src == v2->port_dst &&
+           v1->port_dst == v2->port_src &&
+           v1->src.type == v2->dst.type &&
+           v1->src.len == v2->dst.len &&
+           memcmp(v1->src.data, v2->dst.data, v1->src.len) == 0 &&
+           v1->dst.type == v2->src.type &&
+           v1->dst.len == v2->src.len &&
+           memcmp(v1->dst.data, v2->src.data, v1->dst.len) == 0) {
                /*
-                * The first source address is the same as the second
-                * destination address.
+                * Yes.  It's the same conversation, and the two
+                * address/port pairs are going in opposite directions.
                 */
-               if (v1->dst.len == v2->src.len &&
-                   memcmp(v1->dst.data, v2->src.data, v1->dst.len) == 0) {
-                       /*
-                        * The first destination address is the same as
-                        * the second source address, so they're going
-                        * between the same machines, but in opposite
-                        * directions.
-                        */
-                       if (v1->port_src == v2->port_dst &&
-                           v1->port_dst == v2->port_src) {
-                               /*
-                                * The first source port is the same as
-                                * the second destination port, and the
-                                * first destination port is the same as
-                                * the second source port, so it's
-                                * the same conversation, and the two
-                                * address/port pairs are going in
-                                * opposite directions.
-                                */
-                               return 1;
-                       }
-               }
+               return 1;
        }
 
        /*
@@ -203,12 +179,13 @@ conversation_init(void)
                g_free((gpointer)key->src.data);
                g_free((gpointer)key->dst.data);
        }
+       conversation_keys = NULL;
        if (conversation_hashtable != NULL)
                g_hash_table_destroy(conversation_hashtable);
        if (conversation_key_chunk != NULL)
                g_mem_chunk_destroy(conversation_key_chunk);
-       if (conversation_val_chunk != NULL)
-               g_mem_chunk_destroy(conversation_val_chunk);
+       if (conversation_chunk != NULL)
+               g_mem_chunk_destroy(conversation_chunk);
 
        conversation_hashtable = g_hash_table_new(conversation_hash,
            conversation_equal);
@@ -216,9 +193,9 @@ conversation_init(void)
            sizeof(conversation_key),
            conversation_init_count * sizeof(struct conversation_key),
            G_ALLOC_AND_FREE);
-       conversation_val_chunk = g_mem_chunk_new("conversation_val_chunk",
-           sizeof(conversation_val),
-           conversation_init_count * sizeof(struct conversation_val),
+       conversation_chunk = g_mem_chunk_new("conversation_chunk",
+           sizeof(conversation_t),
+           conversation_init_count * sizeof(conversation_t),
            G_ALLOC_AND_FREE);
 
        /*
@@ -243,18 +220,45 @@ copy_address(address *to, address *from)
 }
 
 /*
- * Given source and destination addresses and ports for a packet, add
- * it to the conversation containing packets between those address/port
- * pairs, creating a new conversation if none exists between them.
- *
- * Returns an index to use to refer to the conversation.
+ * Given source and destination addresses and ports for a packet,
+ * create a new conversation to contain packets between those address/port
+ * pairs.
+ */
+conversation_t *
+conversation_new(address *src, address *dst, port_type ptype,
+    guint32 src_port, guint32 dst_port, void *data)
+{
+       conversation_t *conversation;
+       conversation_key *new_key;
+
+       new_key = g_mem_chunk_alloc(conversation_key_chunk);
+       new_key->next = conversation_keys;
+       conversation_keys = new_key;
+       copy_address(&new_key->src, src);
+       copy_address(&new_key->dst, dst);
+       new_key->ptype = ptype;
+       new_key->port_src = src_port;
+       new_key->port_dst = dst_port;
+
+       conversation = g_mem_chunk_alloc(conversation_chunk);
+       conversation->index = new_index;
+       conversation->data = data;
+       new_index++;
+
+       g_hash_table_insert(conversation_hashtable, new_key, conversation);
+       return conversation;
+}
+
+/*
+ * Given source and destination addresses and ports for a packet,
+ * search for a conversation containing packets between those address/port
+ * pairs.  Returns NULL if not found.
  */
-guint32
-add_to_conversation(address *src, address *dst, port_type ptype,
-    guint16 src_port, guint16 dst_port)
+conversation_t *
+find_conversation(address *src, address *dst, port_type ptype,
+    guint32 src_port, guint32 dst_port)
 {
-       conversation_val *conversation;
-       conversation_key key, *new_key;
+       conversation_key key;
 
        /*
         * We don't make a copy of the address data, we just copy the
@@ -265,30 +269,5 @@ add_to_conversation(address *src, address *dst, port_type ptype,
        key.ptype = ptype;
        key.port_src = src_port;
        key.port_dst = dst_port;
-       conversation =
-           (conversation_val *)g_hash_table_lookup(conversation_hashtable,
-           &key);
-       if (conversation == NULL) {
-               /*
-                * No such conversation yet.
-                * Allocate a new one.
-                * Here, we *do* have to copy the address data.
-                */
-               new_key = g_mem_chunk_alloc(conversation_key_chunk);
-               new_key->next = conversation_keys;
-               conversation_keys = new_key;
-               copy_address(&new_key->src, src);
-               copy_address(&new_key->dst, dst);
-               new_key->ptype = ptype;
-               new_key->port_src = src_port;
-               new_key->port_dst = dst_port;
-
-               conversation = g_mem_chunk_alloc(conversation_val_chunk);
-               conversation->index = new_index;
-               new_index++;
-
-               g_hash_table_insert(conversation_hashtable, new_key,
-                   conversation);
-       }
-       return conversation->index;
+       return g_hash_table_lookup(conversation_hashtable, &key);
 }