aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-10-22 08:44:33 +0000
committerGuy Harris <guy@alum.mit.edu>2002-10-22 08:44:33 +0000
commit3205a6e888a6ca6a54cd67ab50358c4e2f63922b (patch)
treeb6fc40b46cf25808d4749ae87e9b9f853f0972ce /epan
parentd97d0803b38fc101826a0bc1aaddf8850b42d676 (diff)
Add in a notion of "circuits", which are for virtual circuit-oriented
protocols (where there's a virtual circuit ID of some sort in packets) what conversations are for protocols ultimately running atop connectionless network layers. Have circuit type and ID values in the "packet_info" structure. Have the Frame Relay dissector set the circuit type and ID values, and have the Wellfleet compression protocol set up circuit information and store compression information with the circuit. svn path=/trunk/; revision=6471
Diffstat (limited to 'epan')
-rw-r--r--epan/circuit.c278
-rw-r--r--epan/circuit.h66
-rw-r--r--epan/epan.h5
3 files changed, 346 insertions, 3 deletions
diff --git a/epan/circuit.c b/epan/circuit.c
new file mode 100644
index 0000000000..d12fd6c1f1
--- /dev/null
+++ b/epan/circuit.c
@@ -0,0 +1,278 @@
+/* circuit.c
+ * Routines for building lists of packets that are part of a "circuit"
+ *
+ * $Id: circuit.c,v 1.1 2002/10/22 08:43:44 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <string.h>
+#include <glib.h>
+#include "packet.h"
+#include "circuit.h"
+
+/*
+ * Hash table for circuits.
+ */
+static GHashTable *circuit_hashtable = NULL;
+
+static GMemChunk *circuit_key_chunk = NULL;
+static GMemChunk *circuit_chunk = NULL;
+
+static guint32 new_index;
+
+static int circuit_init_count = 200;
+
+/*
+ * Protocol-specific data attached to a circuit_t structure - protocol
+ * index and opaque pointer.
+ */
+typedef struct _circuit_proto_data {
+ int proto;
+ void *proto_data;
+} circuit_proto_data;
+
+static GMemChunk *circuit_proto_data_area = NULL;
+
+/*
+ * Compute the hash value for a circuit.
+ */
+static guint
+circuit_hash(gconstpointer v)
+{
+ circuit_key *key = (circuit_key *)v;
+
+ return key->ctype ^ key->circuit_id;
+}
+
+/*
+ * Compare two circuit keys.
+ */
+static gint
+circuit_match(gconstpointer v, gconstpointer w)
+{
+ circuit_key *v1 = (circuit_key *)v;
+ circuit_key *v2 = (circuit_key *)w;
+
+ return v1->ctype == v2->ctype && v1->circuit_id == v2->circuit_id;
+}
+
+/*
+ * Initialize some variables every time a file is loaded or re-loaded.
+ * Destroy all existing circuits, and create a new hash table
+ * for the circuits in the new file.
+ */
+void
+circuit_init(void)
+{
+ if (circuit_hashtable != NULL)
+ g_hash_table_destroy(circuit_hashtable);
+ if (circuit_key_chunk != NULL)
+ g_mem_chunk_destroy(circuit_key_chunk);
+ if (circuit_chunk != NULL)
+ g_mem_chunk_destroy(circuit_chunk);
+
+ /*
+ * Free up any space allocated for circuit protocol data
+ * areas.
+ *
+ * We can free the space, as the structures it contains are
+ * pointed to by circuit data structures that were freed
+ * above.
+ */
+ if (circuit_proto_data_area != NULL)
+ g_mem_chunk_destroy(circuit_proto_data_area);
+
+ circuit_hashtable = g_hash_table_new(circuit_hash, circuit_match);
+ circuit_key_chunk = g_mem_chunk_new("circuit_key_chunk",
+ sizeof(circuit_key),
+ circuit_init_count * sizeof(struct circuit_key),
+ G_ALLOC_AND_FREE);
+ circuit_chunk = g_mem_chunk_new("circuit_chunk",
+ sizeof(circuit_t),
+ circuit_init_count * sizeof(circuit_t),
+ G_ALLOC_AND_FREE);
+
+ /*
+ * Allocate a new area for circuit protocol data items.
+ */
+ circuit_proto_data_area = g_mem_chunk_new("circuit_proto_data_area",
+ sizeof(circuit_proto_data), 20 * sizeof(circuit_proto_data), /* FIXME*/
+ G_ALLOC_ONLY);
+
+ /*
+ * Start the circuit indices over at 0.
+ */
+ new_index = 0;
+}
+
+/*
+ * Given a circuit type and circuit ID for a packet, create a new circuit
+ * to contain packets for that circuit.
+ */
+circuit_t *
+circuit_new(circuit_type ctype, guint32 circuit_id)
+{
+ circuit_t *circuit;
+ circuit_key *new_key;
+
+ new_key = g_mem_chunk_alloc(circuit_key_chunk);
+ new_key->ctype = ctype;
+ new_key->circuit_id = circuit_id;
+
+ circuit = g_mem_chunk_alloc(circuit_chunk);
+ circuit->index = new_index;
+ circuit->data_list = NULL;
+
+/* clear dissector handle */
+ circuit->dissector_handle = NULL;
+
+/* set the options and key pointer */
+ circuit->key_ptr = new_key;
+
+ new_index++;
+
+ g_hash_table_insert(circuit_hashtable, new_key, circuit);
+
+ return circuit;
+}
+
+/*
+ * Given a circuit type and ID, search for the corresponding circuit.
+ * Returns NULL if not found.
+ */
+circuit_t *
+find_circuit(circuit_type ctype, guint32 circuit_id)
+{
+ circuit_key key;
+
+ key.ctype = ctype;
+ key.circuit_id = circuit_id;
+ return g_hash_table_lookup(circuit_hashtable, &key);
+}
+
+static gint
+p_compare(gconstpointer a, gconstpointer b)
+{
+ if (((circuit_proto_data *)a)->proto > ((circuit_proto_data *)b)->proto)
+ return 1;
+ else if (((circuit_proto_data *)a)->proto == ((circuit_proto_data *)b)->proto)
+ return 0;
+ else
+ return -1;
+}
+
+void
+circuit_add_proto_data(circuit_t *conv, int proto, void *proto_data)
+{
+ circuit_proto_data *p1 = g_mem_chunk_alloc(circuit_proto_data_area);
+
+ p1->proto = proto;
+ p1->proto_data = proto_data;
+
+ /* Add it to the list of items for this circuit. */
+
+ conv->data_list = g_slist_insert_sorted(conv->data_list, (gpointer *)p1,
+ p_compare);
+}
+
+void *
+circuit_get_proto_data(circuit_t *conv, int proto)
+{
+ circuit_proto_data temp, *p1;
+ GSList *item;
+
+ temp.proto = proto;
+ temp.proto_data = NULL;
+
+ item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
+ p_compare);
+
+ if (item != NULL) {
+ p1 = (circuit_proto_data *)item->data;
+ return p1->proto_data;
+ }
+
+ return NULL;
+}
+
+void
+circuit_delete_proto_data(circuit_t *conv, int proto)
+{
+ circuit_proto_data temp;
+ GSList *item;
+
+ temp.proto = proto;
+ temp.proto_data = NULL;
+
+ item = g_slist_find_custom(conv->data_list, (gpointer *)&temp,
+ p_compare);
+
+ if (item != NULL)
+ conv->data_list = g_slist_remove(conv->data_list, item);
+}
+
+void
+circuit_set_dissector(circuit_t *circuit,
+ dissector_handle_t handle)
+{
+ circuit->dissector_handle = handle;
+}
+
+/*
+ * Given a circuit type and ID for a packet, search for a matching
+ * circuit and, if found and it has a circuit dissector,
+ * call that dissector and return TRUE, otherwise return FALSE.
+ */
+gboolean
+try_circuit_dissector(circuit_type ctype, guint32 circuit_id, tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree)
+{
+ circuit_t *circuit;
+ guint16 saved_can_desegment;
+
+ /* can_desegment is set to 2 by anyone which offers this api/service.
+ then everytime a subdissector is called it is decremented by one.
+ thus only the subdissector immediately ontop of whoever offers this
+ service can use it.
+ */
+ saved_can_desegment=pinfo->can_desegment;
+ pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
+
+ circuit = find_circuit(ctype, circuit_id);
+
+ if (circuit != NULL) {
+ if (circuit->dissector_handle == NULL){
+ pinfo->can_desegment=saved_can_desegment;
+ return FALSE;
+ }
+ call_dissector(circuit->dissector_handle, tvb, pinfo,
+ tree);
+ pinfo->can_desegment=saved_can_desegment;
+ return TRUE;
+ }
+ pinfo->can_desegment=saved_can_desegment;
+ return FALSE;
+}
diff --git a/epan/circuit.h b/epan/circuit.h
new file mode 100644
index 0000000000..87a04eceac
--- /dev/null
+++ b/epan/circuit.h
@@ -0,0 +1,66 @@
+/* circuit.h
+ * Routines for building lists of packets that are part of a "circuit"
+ *
+ * $Id: circuit.h,v 1.1 2002/10/22 08:43:44 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __CIRCUIT_H__
+#define __CIRCUIT_H__
+
+#include "packet.h" /* for circuit dissector type */
+
+/*
+ * Data structure representing a circuit.
+ */
+typedef struct circuit_key {
+ circuit_type ctype;
+ guint32 circuit_id;
+} circuit_key;
+
+typedef struct circuit {
+ struct circuit *next; /* pointer to next circuit on hash chain */
+ guint32 index; /* unique ID for circuit */
+ GSList *data_list; /* list of data associated with circuit */
+ dissector_handle_t dissector_handle;
+ /* handle for protocol dissector client associated with circuit */
+ guint options; /* wildcard flags */
+ circuit_key *key_ptr; /* pointer to the key for this circuit */
+} circuit_t;
+
+extern void circuit_init(void);
+
+extern circuit_t *circuit_new(circuit_type ctype, guint32 circuit_id);
+
+extern circuit_t *find_circuit(circuit_type ctype, guint32 circuit_id);
+
+extern void circuit_add_proto_data(circuit_t *conv, int proto,
+ void *proto_data);
+extern void *circuit_get_proto_data(circuit_t *conv, int proto);
+extern void circuit_delete_proto_data(circuit_t *conv, int proto);
+
+extern void circuit_set_dissector(circuit_t *circuit,
+ dissector_handle_t handle);
+extern gboolean
+try_circuit_dissector(circuit_type ctype, guint32 circuit_id, tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree);
+
+#endif /* circuit.h */
+
diff --git a/epan/epan.h b/epan/epan.h
index 24b02a79a7..b3efd355cc 100644
--- a/epan/epan.h
+++ b/epan/epan.h
@@ -1,6 +1,6 @@
/* epan.h
*
- * $Id: epan.h,v 1.14 2002/09/09 21:04:06 guy Exp $
+ * $Id: epan.h,v 1.15 2002/10/22 08:44:33 guy Exp $
*
* Ethereal Protocol Analyzer Library
*
@@ -36,8 +36,7 @@ void epan_init(const char * plugindir, void (register_all_protocols)(void),
void (register_all_handoffs)(void));
void epan_cleanup(void);
void epan_conversation_init(void);
-
-
+void epan_circuit_init(void);
/* A client will create one epan_t for an entire dissection session.
* A single epan_t will be used to analyze the entire sequence of packets,