diff options
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | epan/proto.c | 162 | ||||
-rw-r--r-- | epan/proto.h | 9 | ||||
-rw-r--r-- | gtk/dfilter_expr_dlg.c | 55 |
4 files changed, 120 insertions, 108 deletions
@@ -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); |