aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--epan/proto.c162
-rw-r--r--epan/proto.h9
-rw-r--r--gtk/dfilter_expr_dlg.c55
4 files changed, 120 insertions, 108 deletions
diff --git a/AUTHORS b/AUTHORS
index 33d66b8065..c7c47a7b17 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1710,6 +1710,8 @@ Matthijs Melchior <mmelchior [AT] xs4all.nl> {
TCP support in text2pcap
Support for automatically generating all declarations and
definitions for plugin ABI from a single file
+ Support for registering fields after all the protocol
+ registration routines are called
}
Garth Bushell <gbushell [AT] elipsan.com> {
diff --git a/epan/proto.c b/epan/proto.c
index 74fe13b094..6dd9a56110 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
- * $Id: proto.c,v 1.98 2003/07/31 04:18:00 guy Exp $
+ * $Id: proto.c,v 1.99 2003/08/25 00:15:01 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -124,7 +124,7 @@ static int proto_register_field_init(header_field_info *hfinfo, int parent);
static int g_strcmp(gconstpointer a, gconstpointer b);
/* special-case header field used within proto.c */
-int hf_text_only = 1;
+int hf_text_only = -1;
/* Structure for information about a protocol */
typedef struct {
@@ -138,6 +138,8 @@ typedef struct {
gboolean can_disable; /* TRUE if protocol can be disabled */
} protocol_t;
+static protocol_t *find_protocol_by_id(int proto_id);
+
/* List of all protocols */
static GList *protocols;
@@ -185,27 +187,13 @@ proto_init(const char *plugin_dir
void (register_all_protocols)(void),
void (register_all_protocol_handoffs)(void))
{
- int id, num_symbols;
- char *abbrev;
- header_field_info *hfinfo, *same_name_hfinfo, *same_name_next_hfinfo;
static hf_register_info hf[] = {
{ &hf_text_only,
{ "", "", FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
};
- if (gmc_hfinfo)
- g_mem_chunk_destroy(gmc_hfinfo);
- if (gmc_field_info)
- g_mem_chunk_destroy(gmc_field_info);
- if (gmc_proto_node)
- g_mem_chunk_destroy(gmc_proto_node);
- if (gmc_item_labels)
- g_mem_chunk_destroy(gmc_item_labels);
- if (gpa_hfinfo)
- g_ptr_array_free(gpa_hfinfo, TRUE);
- if (tree_is_expanded != NULL)
- g_free(tree_is_expanded);
+ proto_cleanup();
gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
sizeof(header_field_info),
@@ -228,10 +216,16 @@ proto_init(const char *plugin_dir
G_ALLOC_AND_FREE);
gpa_hfinfo = g_ptr_array_new();
+ gpa_name_tree = g_tree_new(g_strcmp);
/* Initialize the ftype subsystem */
ftypes_initialize();
+ /* Register one special-case FT_TEXT_ONLY field for use when
+ converting ethereal to new-style proto_tree. These fields
+ are merely strings on the GUI tree; they are not filterable */
+ proto_register_field_array(-1, hf, array_length(hf));
+
/* Have each built-in dissector register its protocols, fields,
dissector tables, and dissectors to be called through a
handle, and do whatever one-time initialization it needs to
@@ -255,72 +249,10 @@ proto_init(const char *plugin_dir
register_all_plugin_handoffs();
#endif
- /* Register one special-case FT_TEXT_ONLY field for use when
- converting ethereal to new-style proto_tree. These fields
- are merely strings on the GUI tree; they are not filterable */
- proto_register_field_array(-1, hf, array_length(hf));
-
- num_symbols = proto_registrar_n();
-
- if (gpa_name_tree) {
- /* XXX - needed? */
- g_message("I expected gpa_name_tree to be NULL\n");
- g_tree_destroy(gpa_name_tree);
-
- /* Make sure the hfinfo->same_name links are broken */
- for (id = 0; id < num_symbols; id++) {
- hfinfo = proto_registrar_get_nth(id);
- hfinfo->same_name_next = NULL;
- hfinfo->same_name_prev = NULL;
- }
- }
- gpa_name_tree = g_tree_new(g_strcmp);
-
- /* Populate the abbrev/ID GTree (header-field symbol table) */
-
- for (id = 0; id < num_symbols; id++) {
- if (id == hf_text_only) {
- continue;
- }
- abbrev = proto_registrar_get_abbrev(id);
- hfinfo = proto_registrar_get_nth(id);
-
- g_assert(abbrev); /* Not Null */
- g_assert(abbrev[0] != 0); /* Not empty string */
-
- /* We allow multiple hfinfo's to be registered under the same
- * abbreviation. This was done for X.25, as, depending
- * on whether it's modulo-8 or modulo-128 operation,
- * some bitfield fields may be in different bits of
- * a byte, and we want to be able to refer to that field
- * with one name regardless of whether the packets
- * are modulo-8 or modulo-128 packets. */
- same_name_hfinfo = g_tree_lookup(gpa_name_tree, abbrev);
- if (same_name_hfinfo) {
- /* There's already a field with this name.
- * Put it after that field in the list of
- * fields with this name, then allow the code
- * after this if{} block to replace the old
- * hfinfo with the new hfinfo in the GTree. Thus,
- * we end up with a linked-list of same-named hfinfo's,
- * with the root of the list being the hfinfo in the GTree */
- same_name_next_hfinfo =
- same_name_hfinfo->same_name_next;
-
- hfinfo->same_name_next = same_name_next_hfinfo;
- if (same_name_next_hfinfo)
- same_name_next_hfinfo->same_name_prev = hfinfo;
-
- same_name_hfinfo->same_name_next = hfinfo;
- hfinfo->same_name_prev = same_name_hfinfo;
- }
- g_tree_insert(gpa_name_tree, abbrev, hfinfo);
- }
-
/* We've assigned all the subtree type values; allocate the array
for them, and zero it out. */
tree_is_expanded = g_malloc(num_tree_types*sizeof (gint *));
- memset(tree_is_expanded, '\0', num_tree_types*sizeof (gint *));
+ memset(tree_is_expanded, 0, num_tree_types*sizeof (gint *));
}
/* String comparison func for dfilter_token GTree */
@@ -2200,6 +2132,35 @@ proto_get_next_protocol(void **cookie)
return protocol->proto_id;
}
+header_field_info *
+proto_get_first_protocol_field(int proto_id, void **cookie)
+{
+ protocol_t *protocol = find_protocol_by_id(proto_id);
+ hf_register_info *ptr;
+
+ if ((protocol == NULL) || (protocol->fields == NULL))
+ return NULL;
+
+ *cookie = protocol->fields;
+ ptr = protocol->fields->data;
+ return &ptr->hfinfo;
+}
+
+header_field_info *
+proto_get_next_protocol_field(void **cookie)
+{
+ GList *list_item = *cookie;
+ hf_register_info *ptr;
+
+ list_item = g_list_next(list_item);
+ if (list_item == NULL)
+ return NULL;
+
+ *cookie = list_item;
+ ptr = list_item->data;
+ return &ptr->hfinfo;
+}
+
/*
* Find the protocol list entry for a protocol given its field ID.
*/
@@ -2339,6 +2300,10 @@ proto_register_field_array(int parent, hf_register_info *hf, int num_records)
static int
proto_register_field_init(header_field_info *hfinfo, int parent)
{
+ /* The field must have names */
+ g_assert(hfinfo->name);
+ g_assert(hfinfo->abbrev);
+
/* These types of fields are allowed to have value_strings or true_false_strings */
g_assert((hfinfo->strings == NULL) || (
(hfinfo->type == FT_UINT8) ||
@@ -2389,6 +2354,41 @@ proto_register_field_init(header_field_info *hfinfo, int parent)
/* if we always add and never delete, then id == len - 1 is correct */
g_ptr_array_add(gpa_hfinfo, hfinfo);
hfinfo->id = gpa_hfinfo->len - 1;
+
+ /* if we have real names, enter this field in the name tree */
+ if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
+
+ header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
+
+ /* We allow multiple hfinfo's to be registered under the same
+ * abbreviation. This was done for X.25, as, depending
+ * on whether it's modulo-8 or modulo-128 operation,
+ * some bitfield fields may be in different bits of
+ * a byte, and we want to be able to refer to that field
+ * with one name regardless of whether the packets
+ * are modulo-8 or modulo-128 packets. */
+ same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
+ if (same_name_hfinfo) {
+ /* There's already a field with this name.
+ * Put it after that field in the list of
+ * fields with this name, then allow the code
+ * after this if{} block to replace the old
+ * hfinfo with the new hfinfo in the GTree. Thus,
+ * we end up with a linked-list of same-named hfinfo's,
+ * with the root of the list being the hfinfo in the GTree */
+ same_name_next_hfinfo =
+ same_name_hfinfo->same_name_next;
+
+ hfinfo->same_name_next = same_name_next_hfinfo;
+ if (same_name_next_hfinfo)
+ same_name_next_hfinfo->same_name_prev = hfinfo;
+
+ same_name_hfinfo->same_name_next = hfinfo;
+ hfinfo->same_name_prev = same_name_hfinfo;
+ }
+ g_tree_insert(gpa_name_tree, hfinfo->abbrev, hfinfo);
+ }
+
return hfinfo->id;
}
@@ -3289,7 +3289,7 @@ proto_registrar_dump_fields(void)
* with no pseudo-field being used, but that might also
* require special checks for -1 to be added.
*/
- if (strlen(hfinfo->name) == 0 || strlen(hfinfo->abbrev) == 0)
+ if (hfinfo->name[0] == 0 || hfinfo->abbrev[0] == 0)
continue;
/* format for protocols */
diff --git a/epan/proto.h b/epan/proto.h
index 24d5b3aa35..b66b52223a 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
- * $Id: proto.h,v 1.40 2003/05/03 00:48:35 guy Exp $
+ * $Id: proto.h,v 1.41 2003/08/25 00:15:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -541,10 +541,13 @@ extern gboolean proto_is_protocol_enabled(int proto_id);
/* Can item #n decoding be disabled? */
extern gboolean proto_can_disable_protocol(int proto_id);
-/* Routines to use to iterate over the protocols; they return the item
- * number of the protocol in question, and keep state in "*cookie". */
+/* Routines to use to iterate over the protocols and their fields;
+ * they return the item number of the protocol in question or the
+ * appropriate hfinfo pointer, and keep state in "*cookie". */
extern int proto_get_first_protocol(void **cookie);
extern int proto_get_next_protocol(void **cookie);
+extern header_field_info *proto_get_first_protocol_field(int proto_id, void **cookle);
+extern header_field_info *proto_get_next_protocol_field(void **cookle);
/* Given a protocol's filter_name, return it's proto_id */
extern int proto_get_id_by_filter_name(gchar* filter_name);
diff --git a/gtk/dfilter_expr_dlg.c b/gtk/dfilter_expr_dlg.c
index 0179c3e80e..a91c8c68e3 100644
--- a/gtk/dfilter_expr_dlg.c
+++ b/gtk/dfilter_expr_dlg.c
@@ -7,7 +7,7 @@
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com> and
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: dfilter_expr_dlg.c,v 1.34 2003/07/25 03:44:04 gram Exp $
+ * $Id: dfilter_expr_dlg.c,v 1.35 2003/08/25 00:15:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -1287,33 +1287,18 @@ dfilter_expr_dlg_new(GtkWidget *filter_te)
hfinfo);
g_hash_table_insert(proto_array, (gpointer)i, protocol_node);
}
-#endif
len = proto_registrar_n();
for (i = 0; i < len; i++) {
-#if GTK_MAJOR_VERSION < 2
/*
* If this field is a protocol, skip it - we already put
* it in above.
*/
if (proto_registrar_is_protocol(i))
continue;
-#else
- GtkTreeIter child_iter;
-#endif
hfinfo = proto_registrar_get_nth(i);
-#if GTK_MAJOR_VERSION >= 2
- if (hfinfo->type == FT_PROTOCOL)
- {
- /* Create a node for the protocol */
- gtk_tree_store_append(store, &iter, NULL);
- gtk_tree_store_set(store, &iter, 0, hfinfo->abbrev, 1, hfinfo, -1);
- continue;
- }
-#endif
-
/*
* If this field isn't at the head of the list of
* fields with this name, skip this field - all
@@ -1331,7 +1316,6 @@ dfilter_expr_dlg_new(GtkWidget *filter_te)
/* Create a node for the item, and put it
under its parent protocol. */
-#if GTK_MAJOR_VERSION < 2
protocol_node = g_hash_table_lookup(proto_array,
GINT_TO_POINTER(proto_registrar_get_parent(i)));
item_node = gtk_ctree_insert_node(GTK_CTREE(tree),
@@ -1341,16 +1325,39 @@ dfilter_expr_dlg_new(GtkWidget *filter_te)
FALSE, FALSE);
gtk_ctree_node_set_row_data(GTK_CTREE(tree),
item_node, hfinfo);
-#else
- gtk_tree_store_append(store, &child_iter, &iter);
- gtk_tree_store_set(store, &child_iter, 0, hfinfo->name, 1, hfinfo, -1);
-#endif
}
-#if GTK_MAJOR_VERSION < 2
g_hash_table_destroy(proto_array);
-#else
+
+#else /* GTK_MAJOR_VERSION < 2 */
+{
+ /* GTK2 code using two levels iterator to enumerate all protocol fields */
+
+ GtkTreeIter iter, child_iter;
+ void *cookie, *cookie2;
+ gchar *name;
+
+ for (i = proto_get_first_protocol(&cookie); i != -1;
+ i = proto_get_next_protocol(&cookie)) {
+
+ hfinfo = proto_registrar_get_nth(i);
+ name = proto_get_protocol_short_name(i); /* name, short_name or filter name ? */
+
+ gtk_tree_store_append(store, &iter, NULL);
+ gtk_tree_store_set(store, &iter, 0, name, 1, hfinfo, -1);
+
+ for (hfinfo = proto_get_first_protocol_field(i, &cookie2); hfinfo != NULL;
+ hfinfo = proto_get_next_protocol_field(&cookie2)) {
+
+ if (hfinfo->same_name_prev != NULL) /* ignore duplicate names */
+ continue;
+
+ gtk_tree_store_append(store, &child_iter, &iter);
+ gtk_tree_store_set(store, &child_iter, 0, hfinfo->name, 1, hfinfo, -1);
+ }
+ }
g_object_unref(G_OBJECT(store));
-#endif
+}
+#endif /* GTK_MAJOR_VERSION < 2 */
gtk_widget_show_all(tree);