diff --git a/epan/packet.c b/epan/packet.c index bee5f2a43e..e13d86d629 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -1,7 +1,7 @@ /* packet.c * Routines for packet disassembly * - * $Id: packet.c,v 1.49 2001/12/03 05:07:17 guy Exp $ + * $Id: packet.c,v 1.50 2001/12/03 08:47:30 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -203,8 +203,6 @@ dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header, /*********************** code added for sub-dissector lookup *********************/ -static GHashTable *dissector_tables = NULL; - /* * An dissector handle. */ @@ -214,11 +212,32 @@ struct dissector_handle { int proto_index; }; +/* + * An entry in the hash table portion of a dissector table. + */ struct dtbl_entry { dissector_handle_t initial; dissector_handle_t current; }; +/* + * A dissector table. + * + * "hash_table" is a hash table, indexed by port number, supplying + * a "struct dtbl_entry"; it records what dissector is assigned to + * that port number in that table. + * + * "dissector_handles" is a list of all dissectors that *could* be + * used in that table; not all of them are necessarily in the table, + * as they may be for protocols that don't have a fixed port number. + */ +struct dissector_table { + GHashTable *hash_table; + GSList *dissector_handles; +}; + +static GHashTable *dissector_tables = NULL; + /* Finds a dissector table by field name. */ static dissector_table_t find_dissector_table(const char *name) @@ -241,8 +260,14 @@ dissector_add(const char *name, guint32 pattern, dissector_handle_t handle) dtbl_entry->initial = dtbl_entry->current; /* do the table insertion */ - g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern), - (gpointer)dtbl_entry); + g_hash_table_insert( sub_dissectors->hash_table, + GUINT_TO_POINTER( pattern), (gpointer)dtbl_entry); + + /* + * Now add it to the list of handles that could be used with this + * table, because it *is* being used with this table. + */ + dissector_add_handle(name, handle); } /* delete the entry for this dissector at this pattern */ @@ -264,14 +289,15 @@ dissector_delete(const char *name, guint32 pattern, dissector_handle_t handle) /* * Find the entry. */ - dtbl_entry = g_hash_table_lookup(sub_dissectors, + dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)); if (dtbl_entry != NULL) { /* * Found - remove it. */ - g_hash_table_remove(sub_dissectors, GUINT_TO_POINTER(pattern)); + g_hash_table_remove(sub_dissectors->hash_table, + GUINT_TO_POINTER(pattern)); /* * Now free up the entry. @@ -292,7 +318,7 @@ dissector_change(const char *name, guint32 pattern, dissector_handle_t handle) /* * See if the entry already exists. If so, reuse it. */ - dtbl_entry = g_hash_table_lookup(sub_dissectors, + dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)); if (dtbl_entry != NULL) { dtbl_entry->current = handle; @@ -312,8 +338,8 @@ dissector_change(const char *name, guint32 pattern, dissector_handle_t handle) dtbl_entry->current = handle; /* do the table insertion */ - g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern), - (gpointer)dtbl_entry); + g_hash_table_insert( sub_dissectors->hash_table, + GUINT_TO_POINTER( pattern), (gpointer)dtbl_entry); } /* Reset a dissector in a sub-dissector table to its initial value. */ @@ -329,7 +355,7 @@ dissector_reset(const char *name, guint32 pattern) /* * Find the entry. */ - dtbl_entry = g_hash_table_lookup(sub_dissectors, + dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)); if (dtbl_entry == NULL) @@ -341,7 +367,8 @@ dissector_reset(const char *name, guint32 pattern) if (dtbl_entry->initial != NULL) { dtbl_entry->current = dtbl_entry->initial; } else { - g_hash_table_remove(sub_dissectors, GUINT_TO_POINTER(pattern)); + g_hash_table_remove(sub_dissectors->hash_table, + GUINT_TO_POINTER(pattern)); g_free(dtbl_entry); } } @@ -358,7 +385,7 @@ dissector_try_port(dissector_table_t sub_dissectors, guint32 port, guint32 saved_match_port; guint16 saved_can_desegment; - dtbl_entry = g_hash_table_lookup(sub_dissectors, + dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(port)); if (dtbl_entry != NULL) { /* @@ -423,7 +450,7 @@ dissector_get_port_handle(dissector_table_t sub_dissectors, guint32 port) { dtbl_entry_t *dtbl_entry; - dtbl_entry = g_hash_table_lookup(sub_dissectors, + dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(port)); if (dtbl_entry != NULL) return dtbl_entry->current; @@ -437,6 +464,31 @@ dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry) return dtbl_entry->current; } +/* Add a handle to the list of handles that *could* be used with this + table. That list is used by code in the UI. */ +void +dissector_add_handle(const char *name, dissector_handle_t handle) +{ + dissector_table_t sub_dissectors = find_dissector_table( name); + GSList *entry; + + /* sanity check */ + g_assert(sub_dissectors != NULL); + + /* Is it already in this list? */ + entry = g_slist_find(sub_dissectors->dissector_handles, (gpointer)handle); + if (entry != NULL) { + /* + * Yes - don't insert it again. + */ + return; + } + + /* Add it to the list. */ + sub_dissectors->dissector_handles = + g_slist_append(sub_dissectors->dissector_handles, (gpointer)handle); +} + dissector_handle_t dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry) { @@ -520,8 +572,8 @@ dissector_all_tables_foreach (DATFunc func, } /* - * Walk one dissector table calling a user supplied function on each - * entry. + * Walk one dissector table's hash table calling a user supplied function + * on each entry. */ void dissector_table_foreach (char *name, @@ -529,15 +581,28 @@ dissector_table_foreach (char *name, gpointer user_data) { dissector_foreach_info_t info; - GHashTable *hash_table; - - hash_table = find_dissector_table(name); - g_assert(hash_table); + dissector_table_t sub_dissectors = find_dissector_table( name); info.table_name = name; info.caller_func = func; info.caller_data = user_data; - g_hash_table_foreach(hash_table, dissector_table_foreach_func, &info); + g_hash_table_foreach(sub_dissectors->hash_table, dissector_table_foreach_func, &info); +} + +/* + * Walk one dissector table's list of handles calling a user supplied + * function on each entry. + */ +void +dissector_table_foreach_handle(char *name, DATFunc_handle func, gpointer user_data) +{ + dissector_foreach_info_t info; + dissector_table_t sub_dissectors = find_dissector_table( name); + GSList *tmp; + + for (tmp = sub_dissectors->dissector_handles; tmp != NULL; + tmp = g_slist_next(tmp)) + func(name, tmp->data, user_data); } /* @@ -590,15 +655,13 @@ dissector_table_foreach_changed (char *name, gpointer user_data) { dissector_foreach_info_t info; - GHashTable *hash_table; - - hash_table = find_dissector_table(name); - g_assert(hash_table); + dissector_table_t sub_dissectors = find_dissector_table( name); info.table_name = name; info.caller_func = func; info.caller_data = user_data; - g_hash_table_foreach(hash_table, dissector_table_foreach_changed_func, &info); + g_hash_table_foreach(sub_dissectors->hash_table, + dissector_table_foreach_changed_func, &info); } dissector_table_t @@ -617,7 +680,10 @@ register_dissector_table(const char *name) /* Create and register the dissector table for this name; returns */ /* a pointer to the dissector table. */ - sub_dissectors = g_hash_table_new( g_direct_hash, g_direct_equal ); + sub_dissectors = g_malloc(sizeof (struct dissector_table)); + sub_dissectors->hash_table = g_hash_table_new( g_direct_hash, + g_direct_equal ); + sub_dissectors->dissector_handles = NULL; g_hash_table_insert( dissector_tables, (gpointer)name, (gpointer) sub_dissectors ); return sub_dissectors; } @@ -716,89 +782,6 @@ register_heur_dissector_list(const char *name, heur_dissector_list_t *sub_dissec (gpointer) sub_dissectors); } -static GHashTable *conv_dissector_lists = NULL; - -/* Finds a conversation dissector table by table name. */ -static conv_dissector_list_t * -find_conv_dissector_list(const char *name) -{ - g_assert(conv_dissector_lists != NULL); - return g_hash_table_lookup(conv_dissector_lists, name); -} - -void -conv_dissector_add(const char *name, dissector_handle_t handle) -{ - conv_dissector_list_t *sub_dissectors = find_conv_dissector_list(name); - - /* sanity check */ - g_assert(sub_dissectors != NULL); - - /* do the table insertion */ - *sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)handle); -} - -void -register_conv_dissector_list(const char *name, conv_dissector_list_t *sub_dissectors) -{ - /* Create our hash-of-lists if it doesn't already exist */ - if (conv_dissector_lists == NULL) { - conv_dissector_lists = g_hash_table_new(g_str_hash, g_str_equal); - g_assert(conv_dissector_lists != NULL); - } - - /* Make sure the registration is unique */ - g_assert(g_hash_table_lookup(conv_dissector_lists, name) == NULL); - - *sub_dissectors = NULL; /* initially empty */ - g_hash_table_insert(conv_dissector_lists, (gpointer)name, - (gpointer) sub_dissectors); -} - -void -dissector_conv_foreach (char *name, - DATFunc func, - gpointer user_data) -{ - conv_dissector_list_t *sub_dissectors = find_conv_dissector_list(name); - GSList *tmp; - - /* sanity check */ - g_assert(sub_dissectors != NULL); - - for (tmp = *sub_dissectors; tmp; tmp = g_slist_next(tmp)) { - func(name, 0, tmp->data, user_data); - } -} - -static void -dissector_all_conv_foreach_func (gpointer key, gpointer value, gpointer user_data) -{ - conv_dissector_list_t *sub_dissectors; - GSList *tmp; - dissector_foreach_info_t *info; - - g_assert(value); - g_assert(user_data); - - sub_dissectors = value; - for (tmp = *sub_dissectors; tmp; tmp = g_slist_next(tmp)) { - info = user_data; - info->caller_func(key, 0, tmp->data, info->caller_data); - } -} - -void -dissector_all_conv_foreach (DATFunc func, - gpointer user_data) -{ - dissector_foreach_info_t info; - - info.caller_data = user_data; - info.caller_func = func; - g_hash_table_foreach(conv_dissector_lists, dissector_all_conv_foreach_func, &info); -} - /* * Register dissectors by name; used if one dissector always calls a * particular dissector, or if it bases the decision of which dissector diff --git a/epan/packet.h b/epan/packet.h index c4235eecf9..3229786c82 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.44 2001/12/03 05:07:18 guy Exp $ + * $Id: packet.h,v 1.45 2001/12/03 08:47:30 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -85,14 +85,17 @@ extern void packet_cleanup(void); struct dissector_handle; typedef struct dissector_handle *dissector_handle_t; -/* Hash table for matching port numbers and dissectors */ -typedef GHashTable* dissector_table_t; +/* Hash table for matching port numbers and dissectors; this is opaque + outside of "packet.c". */ +struct dissector_table; +typedef struct dissector_table *dissector_table_t; /* types for sub-dissector lookup */ typedef void (*old_dissector_t)(const u_char *, int, frame_data *, proto_tree *); typedef void (*dissector_t)(tvbuff_t *, packet_info *, proto_tree *); typedef void (*DATFunc) (gchar *table_name, gpointer key, gpointer value, gpointer user_data); +typedef void (*DATFunc_handle) (gchar *table_name, gpointer value, gpointer user_data); /* Opaque structure - provides type checking but no access to components */ typedef struct dtbl_entry dtbl_entry_t; @@ -105,6 +108,8 @@ extern void dissector_table_foreach (char *name, DATFunc func, gpointer user_data); extern void dissector_all_tables_foreach_changed (DATFunc func, gpointer user_data); +extern void dissector_table_foreach_handle(char *name, DATFunc_handle func, + gpointer user_data); /* a protocol uses the function to register a sub-dissector table */ extern dissector_table_t register_dissector_table(const char *name); @@ -136,6 +141,10 @@ extern gboolean dissector_try_port(dissector_table_t sub_dissectors, extern dissector_handle_t dissector_get_port_handle( dissector_table_t sub_dissectors, guint32 port); +/* Add a handle to the list of handles that *could* be used with this + table. That list is used by code in the UI. */ +extern void dissector_add_handle(const char *name, dissector_handle_t handle); + /* List of "heuristic" dissectors (which get handed a packet, look at it, and either recognize it as being for their protocol, dissect it, and return TRUE, or don't recognize it and return FALSE) to be called @@ -161,35 +170,6 @@ extern void heur_dissector_add(const char *name, heur_dissector_t dissector, extern gboolean dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); -/* List of "conversation" dissectors (they're not heuristic, but are - assigned to a conversation if some other dissector sees some traffic - saying "traffic between these hosts on these ports will be of type - XXX", e.g. RTSP traffic doing so). - - These lists are for use by the UI, which, for a given conversation, - would offer a list of dissectors that could be used with it; this - would include dissectors on the conversation dissector list for - the transport-layer protocol for the conversation, as well as - dissectors for any port-based lists for that protocol (as a conversation - between two ports, both of which have dissectors associated with them, - might have been given to the wrong one of those dissectors). */ -typedef GSList *conv_dissector_list_t; - -/* A protocol uses this function to register a conversation dissector list */ -extern void register_conv_dissector_list(const char *name, - conv_dissector_list_t *list); - -/* Add a sub-dissector to a conversation dissector list. Called by the - protocol routine that wants to register a sub-dissector. */ -extern void conv_dissector_add(const char *name, dissector_handle_t handle); - -/* Opaque structure - provides type checking but no access to components */ -typedef struct conv_dtbl_entry conv_dtbl_entry_t; - -extern void dissector_conv_foreach(char *name, DATFunc func, - gpointer user_data); -extern void dissector_all_conv_foreach(DATFunc func, gpointer user_data); - /* Register a dissector. */ extern void register_dissector(const char *name, dissector_t dissector, int proto); diff --git a/gtk/decode_as_dlg.c b/gtk/decode_as_dlg.c index a89cc39d75..118eca3a2c 100644 --- a/gtk/decode_as_dlg.c +++ b/gtk/decode_as_dlg.c @@ -1,6 +1,6 @@ /* decode_as_dlg.c * - * $Id: decode_as_dlg.c,v 1.14 2001/12/03 04:00:19 guy Exp $ + * $Id: decode_as_dlg.c,v 1.15 2001/12/03 08:47:31 guy Exp $ * * Routines to modify dissector tables on the fly. * @@ -64,22 +64,6 @@ enum action_type { E_DECODE_NO }; -/* - * Enum used to track which transport layer protocol menu item is - * currently selected in the dialog. These items are labeled "TCP", - * "UDP", and "TCP/UDP". - */ -enum tcpudp_type { - /* The "TCP" menu item is currently selected. */ - E_DECODE_TCP, - - /* The "TCP" menu item is currently selected. */ - E_DECODE_UDP, - - /* The "TCP/UDP" menu item is currently selected. */ - E_DECODE_TCPUDP -}; - /* * Enum used to track which transport layer port menu item is * currently selected in the dialog. These items are labeled "source", @@ -97,7 +81,6 @@ enum srcdst_type { #define E_DECODE_MIN_HEIGHT 100 #define E_NOTEBOOK "notebook" -#define E_MENU_TCPUDP "menu_tcp_udp" #define E_MENU_SRCDST "menu_src_dst" #define E_PAGE_ACTION "notebook_page_action" @@ -112,8 +95,7 @@ enum srcdst_type { #define E_CLIST_S_PROTO_NAME 0 #define E_CLIST_S_TABLE 1 /* The following is for debugging in decode_add_to_clist */ -#define E_CLIST_S_ISCONV 2 -#define E_CLIST_S_MAX E_CLIST_S_ISCONV +#define E_CLIST_S_MAX E_CLIST_S_TABLE #define E_CLIST_S_COLUMNS (E_CLIST_S_MAX + 1) /* @@ -155,13 +137,20 @@ static GtkWidget *decode_show_w = NULL; static GSList *decode_dimmable = NULL; /* - * A list of additional IP port numbers that are currently being - * decodes as either TCP or UDP. This is used to determine whether or - * not to include a "transport" page in the dialog notebook. This - * list never includes values for the standard TCP or UDP protocol - * numbers. + * A list of additional IP protocol numbers that are currently being + * decodes as TCP. This is used to determine whether or not to include + * a "transport" page for TCP in the dialog notebook. This list never + * includes values for the standard TCP protocol number. */ -static GSList *decode_as_tcpudp = NULL; +static GSList *decode_as_tcp = NULL; + +/* + * A list of additional IP protocol numbers that are currently being + * decodes as UDP. This is used to determine whether or not to include + * a "transport" page for UDP in the dialog notebook. This list never + * includes values for the standard UDP protocol number. + */ +static GSList *decode_as_udp = NULL; /* * Remember the "action" radio button that is currently selected in @@ -523,16 +512,17 @@ static void decode_debug (GtkCList *clist, gchar *leadin) { gchar *string, *text[E_CLIST_S_COLUMNS]; - gint row, proto_num; + dissector_handle_t handle; + gint row; string = g_malloc(1024); if (clist->selection) { row = GPOINTER_TO_INT(clist->selection->data); gtk_clist_get_text(clist, row, E_CLIST_S_PROTO_NAME, &text[E_CLIST_S_PROTO_NAME]); gtk_clist_get_text(clist, row, E_CLIST_S_TABLE, &text[E_CLIST_S_TABLE]); - proto_num = GPOINTER_TO_INT(gtk_clist_get_row_data(clist, row)); - sprintf(string, "%s clist row %d: proto %d, name %s, table %s", - leadin, row, proto_num, text[E_CLIST_S_PROTO_NAME], + handle = gtk_clist_get_row_data(clist, row); + sprintf(string, "%s clist row %d: , name %s, table %s", + leadin, row, text[E_CLIST_S_PROTO_NAME], text[E_CLIST_S_TABLE]); } else { sprintf(string, "%s clist row (none), aka do not decode", leadin); @@ -557,6 +547,9 @@ static void decode_simple (GtkWidget *notebook_pg) { GtkCList *clist; +#ifdef DEBUG + gchar *string; +#endif gchar *table_name; gint value; @@ -581,8 +574,8 @@ decode_simple (GtkWidget *notebook_pg) * "Decode As..." dialog window and the network page is foremost. * This routine takes care of making any changes requested to the * dissector tables. This routine uses the decode_simple() routine to - * perform the heavy lifting, and then updates a list of protocol that - * are being decoded as TCP/UDP. * + * perform the heavy lifting, and then updates the lists of protocol that + * are being decoded as TCP and as UDP. * * @param notebook_pg A pointer to the "network" notebook page. */ @@ -591,12 +584,15 @@ decode_network (GtkWidget *notebook_pg) { GtkCList *clist; GSList *item; - gint row, assigned, port_num; + gint row, port_num; + dissector_handle_t handle; + gchar *short_name; /* Do the real work */ decode_simple(notebook_pg); - /* Now tweak a local table of protocol ids currently decoded as TCP/UDP */ + /* Now tweak the local tables of protocol ids currently decoded as TCP + and UDP */ port_num = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(notebook_pg), E_PAGE_VALUE)); @@ -604,30 +600,47 @@ decode_network (GtkWidget *notebook_pg) if ((port_num == IP_PROTO_TCP) || (port_num == IP_PROTO_UDP)) return; - /* Not decoding - remove any entry for this IP protocol number */ if (requested_action == E_DECODE_NO) { - decode_as_tcpudp = - g_slist_remove(decode_as_tcpudp, GINT_TO_POINTER(port_num)); + /* Not decoding at all; remove any entry for this IP protocol number + in the lists of protocol numbers to be decoded as TCP or + UDP. */ + decode_as_tcp = + g_slist_remove(decode_as_tcp, GINT_TO_POINTER(port_num)); + decode_as_udp = + g_slist_remove(decode_as_udp, GINT_TO_POINTER(port_num)); return; } - /* Not assigning TCP or UDP - remove any entry for this IP protocol number. - Note: if the action was E_DECODE_NO, the selection on the clist + /* Note: if the action was E_DECODE_NO, the selection on the clist was cleared, so the code to get "row" below would blow up. */ clist = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(notebook_pg), E_PAGE_CLIST)); row = GPOINTER_TO_INT(clist->selection->data); - assigned = GPOINTER_TO_INT(gtk_clist_get_row_data(clist, row)); - if ((assigned != IP_PROTO_TCP) && (assigned != IP_PROTO_UDP)) { - decode_as_tcpudp = - g_slist_remove(decode_as_tcpudp, GINT_TO_POINTER(port_num)); - return; - } - - /* Assigning TCP or UDP - add if not already present */ - item = g_slist_find(decode_as_tcpudp, GINT_TO_POINTER(port_num)); - if (!item) { - decode_as_tcpudp = - g_slist_prepend(decode_as_tcpudp, GINT_TO_POINTER(port_num)); + handle = gtk_clist_get_row_data(clist, row); + short_name = dissector_handle_get_short_name(handle); + if (strcmp(short_name, "TCP") == 0) { + /* Assigning as TCP; add to the list of IP protocol numbers + decoded as TCP if not already present on that list. */ + item = g_slist_find(decode_as_tcp, GINT_TO_POINTER(port_num)); + if (!item) { + decode_as_tcp = + g_slist_prepend(decode_as_tcp, GINT_TO_POINTER(port_num)); + } + } else if (strcmp(short_name, "UDP") == 0) { + /* Assigning as UDP; add to the list of IP protocol numbers + decoded as UDP if not already present on that list. */ + item = g_slist_find(decode_as_udp, GINT_TO_POINTER(port_num)); + if (!item) { + decode_as_udp = + g_slist_prepend(decode_as_udp, GINT_TO_POINTER(port_num)); + } + } else { + /* Not assigning TCP or UDP; remove any entry for this IP protocol + number in the lists of protocol numbers to be decoded as TCP or + UDP. */ + decode_as_tcp = + g_slist_remove(decode_as_tcp, GINT_TO_POINTER(port_num)); + decode_as_udp = + g_slist_remove(decode_as_udp, GINT_TO_POINTER(port_num)); } } @@ -636,11 +649,7 @@ decode_network (GtkWidget *notebook_pg) * This routine is called when the user clicks the "OK" button in the * "Decode As..." dialog window and the transport page is foremost. * This routine takes care of making any changes requested to the TCP - * and UDP dissector tables. - * - * Note: The negative tests catch multiple cases. For example, if the - * user didn't select UDP, then they either selected TCP or TCP/UDP. - * Either way they *did* select TCP. + * or UDP dissector tables. * * @param notebook_pg A pointer to the "transport" notebook page. */ @@ -649,16 +658,13 @@ decode_transport (GtkObject *notebook_pg) { GtkWidget *menu, *menuitem; GtkCList *clist; - gint requested_tcpudp, requested_srcdst; + gchar *table_name; + gint requested_srcdst; clist = GTK_CLIST(gtk_object_get_data(notebook_pg, E_PAGE_CLIST)); if (requested_action == E_DECODE_NO) gtk_clist_unselect_all(clist); - menu = gtk_object_get_data(notebook_pg, E_MENU_TCPUDP); - menuitem = gtk_menu_get_active(GTK_MENU(menu)); - requested_tcpudp = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem))); - menu = gtk_object_get_data(notebook_pg, E_MENU_SRCDST); menuitem = gtk_menu_get_active(GTK_MENU(menu)); requested_srcdst = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem))); @@ -668,18 +674,11 @@ decode_transport (GtkObject *notebook_pg) decode_debug(clist, string); #endif - if (requested_tcpudp != E_DECODE_UDP) { - if (requested_srcdst != E_DECODE_DPORT) - decode_change_one_dissector("tcp.port", cfile.edt->pi.srcport, clist); - if (requested_srcdst != E_DECODE_SPORT) - decode_change_one_dissector("tcp.port", cfile.edt->pi.destport, clist); - } - if (requested_tcpudp != E_DECODE_TCP) { - if (requested_srcdst != E_DECODE_DPORT) - decode_change_one_dissector("udp.port", cfile.edt->pi.srcport, clist); - if (requested_srcdst != E_DECODE_SPORT) - decode_change_one_dissector("udp.port", cfile.edt->pi.destport, clist); - } + table_name = gtk_object_get_data(GTK_OBJECT(notebook_pg), E_PAGE_TABLE); + if (requested_srcdst != E_DECODE_DPORT) + decode_change_one_dissector(table_name, cfile.edt->pi.srcport, clist); + if (requested_srcdst != E_DECODE_SPORT) + decode_change_one_dissector(table_name, cfile.edt->pi.destport, clist); } /**************************************************/ @@ -863,54 +862,6 @@ decode_add_pack_menu (GtkWidget *optmenu) return(alignment); } -/* - * This routine is called to add the transport protocol selection menu - * to the dialog box. This is a three choice menu: TCP, UDP, and - * TCP/UDP. The default choice for the menu is set to the transport - * layer protocol of the currently selected packet. - * - * @param page A pointer notebook page that will contain all - * widgets created by this routine. - * - * @return GtkWidget * A pointer to the newly created alignment into - * which we've packed the newly created option menu. - */ -static GtkWidget * -decode_add_tcpudp_menu (GtkWidget *page) -{ - GtkWidget *optmenu, *menu, *menuitem, *alignment; - gint requested_tcpudp; - - optmenu = gtk_option_menu_new(); - menu = gtk_menu_new(); - menuitem = gtk_menu_item_new_with_label("TCP"); - gtk_object_set_user_data(GTK_OBJECT(menuitem), - GINT_TO_POINTER(E_DECODE_TCP)); - gtk_menu_append(GTK_MENU(menu), menuitem); - gtk_widget_show(menuitem); /* gtk_widget_show_all() doesn't show this */ - - menuitem = gtk_menu_item_new_with_label("UDP"); - gtk_object_set_user_data(GTK_OBJECT(menuitem), - GINT_TO_POINTER(E_DECODE_UDP)); - gtk_menu_append(GTK_MENU(menu), menuitem); - gtk_widget_show(menuitem); /* gtk_widget_show_all() doesn't show this */ - - menuitem = gtk_menu_item_new_with_label("TCP/UDP"); - gtk_object_set_user_data(GTK_OBJECT(menuitem), - GINT_TO_POINTER(E_DECODE_TCPUDP)); - gtk_menu_append(GTK_MENU(menu), menuitem); - gtk_widget_show(menuitem); /* gtk_widget_show_all() doesn't show this */ - - requested_tcpudp = (cfile.edt->pi.ipproto == IP_PROTO_TCP) ? E_DECODE_TCP : E_DECODE_UDP; - gtk_menu_set_active(GTK_MENU(menu), requested_tcpudp == E_DECODE_UDP); - gtk_object_set_data(GTK_OBJECT(page), E_MENU_TCPUDP, menu); - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); - - alignment = decode_add_pack_menu(optmenu); - - return(alignment); -} - /* * This routine is called to add the transport port selection menu to @@ -965,30 +916,20 @@ decode_add_srcdst_menu (GtkWidget *page) /**************************************************/ -typedef struct decode_build_clist_info { - GtkCList *clist; - gboolean conv; -} decode_build_clist_info_t; - /* * This routine creates one entry in the list of protocol dissector - * that can be used. It is called by the g_hash_foreach routine once - * for each entry in a dissector table. It guarantees unique entries - * by iterating over the list of entries build up to this point, + * that can be used. It is called by the dissector_table_foreach_handle + * routine once for each entry in a dissector table's list of handles + * for dissectors that could be used in that table. It guarantees unique + * entries by iterating over the list of entries build up to this point, * looking for a duplicate name. If there is no duplicate, then this * entry is added to the list of possible dissectors. * - * @param table_name The name of the dissector hash table currently + * @param table_name The name of the dissector table currently * being walked. * - * @param key A pointer to the key for this entry in the - * dissector hash table. This is generally the numeric selector of - * the protocol, i.e. the ethernet type code, IP port number, TCP port - * number, etc. - * - * @param value A pointer to the value for this entry in the - * dissector hash table. This is an opaque pointer that can only be - * handed back to routines in the file packet.c + * @param value The dissector handle for this entry. This is an opaque + * pointer that can only be handed back to routines in the file packet.c * * @param user_data A data block passed into each instance of this * routine. It contains information from the caller of the foreach @@ -996,38 +937,32 @@ typedef struct decode_build_clist_info { * to store any information generated by this routine. */ static void -decode_add_to_clist (gchar *table_name, gpointer key, - gpointer value, gpointer user_data) +decode_add_to_clist (gchar *table_name, gpointer value, gpointer user_data) { GtkCList *clist; - gchar *proto_name, *isconv; + gchar *proto_name; gchar *text[E_CLIST_S_COLUMNS]; dissector_handle_t handle; gint row; - decode_build_clist_info_t *info; g_assert(user_data); g_assert(value); - info = user_data; - clist = info->clist; - if (info->conv) { - handle = value; - isconv = "TRUE"; - } else { - handle = dtbl_entry_get_handle(value); - isconv = "FALSE"; - } + clist = user_data; + handle = value; proto_name = dissector_handle_get_short_name(handle); row = gtk_clist_find_row_from_data(clist, handle); if (row != -1) { + /* + * We already have an entry for this handle. + * XXX - will this ever happen? + */ return; } text[E_CLIST_S_PROTO_NAME] = proto_name; text[E_CLIST_S_TABLE] = table_name; - text[E_CLIST_S_ISCONV] = isconv; row = gtk_clist_prepend(clist, text); gtk_clist_set_row_data(clist, row, handle); } @@ -1050,8 +985,7 @@ static void decode_clist_menu_start (GtkWidget *page, GtkCList **clist_p, GtkWidget **scrolled_win_p) { - gchar *titles[E_CLIST_S_COLUMNS] = {"Short Name", "Table Name", - "Is Conversation"}; + gchar *titles[E_CLIST_S_COLUMNS] = {"Short Name", "Table Name"}; GtkCList *clist; GtkWidget *window; gint column; @@ -1092,9 +1026,8 @@ decode_clist_menu_finish (GtkCList *clist) text[E_CLIST_S_PROTO_NAME] = "(default)"; text[E_CLIST_S_TABLE] = "(none)"; - text[E_CLIST_S_ISCONV] = "(who cares)"; row = gtk_clist_prepend(clist, text); - gtk_clist_set_row_data(clist, row, GINT_TO_POINTER(-1)); + gtk_clist_set_row_data(clist, row, NULL); gtk_clist_select_row(clist, 0, -1); gtk_clist_sort(clist); @@ -1110,8 +1043,8 @@ decode_clist_menu_finish (GtkCList *clist) * * @param page A pointer to the notebook page currently being created. * - * @param table_name The name of the dissector hash table to use to - * build this (clist) menu. + * @param table_name The name of the dissector table to use to build + * this (clist) menu. * * @return GtkWidget * A pointer to the newly created clist within a * scrolled window. @@ -1121,48 +1054,9 @@ decode_add_simple_menu (GtkWidget *page, gchar *table_name) { GtkWidget *scrolled_window; GtkCList *clist; - decode_build_clist_info_t info; decode_clist_menu_start(page, &clist, &scrolled_window); - { - info.clist = clist; - info.conv = FALSE; - dissector_table_foreach(table_name, decode_add_to_clist, &info); - } - decode_clist_menu_finish(clist); - return(scrolled_window); -} - -/* - * This routine is called to add the dissector selection list to - * notebook page. This scrolled list contains an entry labeled - * "default", and an entry for each protocol that has had a dissector - * registered. The default choice for the list is set to the - * "default" choice, which will return the protocol/port selections to - * their original dissector(s). - * - * @param page A pointer to the notebook page currently being created. - * - * @return GtkWidget * A pointer to the newly created option menu. - */ -static GtkWidget * -decode_add_transport_menu (GtkWidget *page) -{ - GtkWidget *scrolled_window; - GtkCList *clist; - decode_build_clist_info_t info; - - decode_clist_menu_start(page, &clist, &scrolled_window); - { - info.clist = clist; - info.conv = FALSE; - dissector_table_foreach("tcp.port", decode_add_to_clist, &info); - dissector_table_foreach("udp.port", decode_add_to_clist, &info); - - info.conv = TRUE; - dissector_conv_foreach("udp", decode_add_to_clist, &info); - dissector_conv_foreach("tcp", decode_add_to_clist, &info); - } + dissector_table_foreach_handle(table_name, decode_add_to_clist, clist); decode_clist_menu_finish(clist); return(scrolled_window); } @@ -1181,10 +1075,9 @@ decode_add_transport_menu (GtkWidget *page) * * @param prompt The prompt for this notebook page * - * @param title A table name from which all dissector names will - * be extracted. + * @param title A title for this page to use when debugging. * - * @param table_name The name of the dissector hash table to use to + * @param table_name The name of the dissector table to use to * build this page. * * @param value The protocol/port value that is to be changed. @@ -1221,35 +1114,41 @@ decode_add_simple_page (gchar *prompt, gchar *title, gchar *table_name, /* - * This routine creates the TCP/UDP notebook page in the dialog box. + * This routine creates the TCP or UDP notebook page in the dialog box. * All items created by this routine are packed into a single - * horizontal box. First is a menu allowing the user to select the - * TCP or UDP transport layer protocol. Second is a menu allowing the - * user to select whether the source port, destination port, or both - * ports will have dissectors added for them. Last is a - * (conditionally enabled) popup menu listing all possible dissectors - * that can be used to decode the packets, and the choice or returning - * to the default dissector for these ports. + * horizontal box. First is a label indicating whether the port(s) for + * which the user can set the dissection is a TCP port or a UDP port. + * Second is a menu allowing the user to select whether the source port, + * destination port, or both ports will have dissectors added for them. + * Last is a (conditionally enabled) popup menu listing all possible + * dissectors that can be used to decode the packets, and the choice + * or returning to the default dissector for these ports. * * The defaults for these items are the transport layer protocol of * the currently selected packet, the source port of the currently * selected packet, and the "default dissector". * + * @param prompt The prompt for this notebook page + * + * @param table_name The name of the dissector table to use to + * build this page. + * * @return GtkWidget * A pointer to the notebook page created by * this routine. */ static GtkWidget * -decode_add_tcpudp_page (void) +decode_add_tcpudp_page (gchar *prompt, gchar *table_name) { GtkWidget *page, *label, *scrolled_window, *optmenu; page = gtk_hbox_new(FALSE, 5); gtk_object_set_data(GTK_OBJECT(page), E_PAGE_ACTION, decode_transport); + gtk_object_set_data(GTK_OBJECT(page), E_PAGE_TABLE, table_name); gtk_object_set_data(GTK_OBJECT(page), E_PAGE_TITLE, "Transport"); /* Always enabled */ - optmenu = decode_add_tcpudp_menu(page); - gtk_box_pack_start(GTK_BOX(page), optmenu, TRUE, TRUE, 0); + label = gtk_label_new(prompt); + gtk_box_pack_start(GTK_BOX(page), label, TRUE, TRUE, 0); optmenu = decode_add_srcdst_menu(page); gtk_box_pack_start(GTK_BOX(page), optmenu, TRUE, TRUE, 0); label = gtk_label_new("port(s)"); @@ -1259,13 +1158,51 @@ decode_add_tcpudp_page (void) label = gtk_label_new("as"); gtk_box_pack_start(GTK_BOX(page), label, TRUE, TRUE, 0); decode_dimmable = g_slist_prepend(decode_dimmable, label); - scrolled_window = decode_add_transport_menu(page); + scrolled_window = decode_add_simple_menu(page, table_name); gtk_box_pack_start(GTK_BOX(page), scrolled_window, TRUE, TRUE, 0); decode_dimmable = g_slist_prepend(decode_dimmable, scrolled_window); return(page); } +/* + * Indicate if a transport page for TCP should be included, based upon the + * IP protocol number. + * + * @param ip_protocol The IP protocol number in question. + * + * @return gboolean TRUE if this protocol is being decoded as TCP. + */ +static gboolean +decode_as_tcp_ok (gint ip_protocol) +{ + if (ip_protocol == IP_PROTO_TCP) + return(TRUE); + + if (g_slist_find(decode_as_tcp, GINT_TO_POINTER(ip_protocol))) + return(TRUE); + return(FALSE); +} + +/* + * Indicate if a transport page for UDP should be included, based upon the + * IP protocol number. + * + * @param ip_protocol The IP protocol number in question. + * + * @return gboolean TRUE if this protocol is being decoded as UDP. + */ +static gboolean +decode_as_udp_ok (gint ip_protocol) +{ + if (ip_protocol == IP_PROTO_UDP) + return(TRUE); + + if (g_slist_find(decode_as_udp, GINT_TO_POINTER(ip_protocol))) + return(TRUE); + return(FALSE); +} + /* * Indicate if a transport page should be included, based upon the iP * protocol number. @@ -1278,12 +1215,18 @@ decode_add_tcpudp_page (void) static gboolean decode_as_transport_ok (gint ip_protocol) { - if ((ip_protocol == IP_PROTO_TCP) || (ip_protocol == IP_PROTO_UDP)) - return(TRUE); + return(decode_as_tcp_ok(ip_protocol) || decode_as_udp_ok(ip_protocol)); +} - if (g_slist_find(decode_as_tcpudp, GINT_TO_POINTER(ip_protocol))) - return(TRUE); - return(FALSE); +/* + * This routine indicates whether we'd actually have any pages in the + * notebook in a "Decode As" dialog box; if there wouldn't be, we + * inactivate the menu item for "Decode As". + */ +gboolean +decode_as_ok(void) +{ + return cfile.edt->pi.ethertype || cfile.edt->pi.ipproto || decode_as_transport_ok(cfile.edt->pi.ipproto); } @@ -1324,8 +1267,13 @@ decode_add_notebook (GtkWidget *format_hb) } /* Add transport selection page */ - if (decode_as_transport_ok(cfile.edt->pi.ipproto)) { - page = decode_add_tcpudp_page(); + if (decode_as_tcp_ok(cfile.edt->pi.ipproto)) + page = decode_add_tcpudp_page("TCP", "tcp.port"); + else if (decode_as_udp_ok(cfile.edt->pi.ipproto)) + page = decode_add_tcpudp_page("UDP", "udp.port"); + else + page = NULL; + if (page != NULL) { label = gtk_label_new("Transport"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label); } @@ -1424,17 +1372,6 @@ decode_as_cb (GtkWidget * w, gpointer data) gtk_widget_show_all(decode_w); } -/* - * This routine indicates whether we'd actually have any pages in the - * notebook in a "Decode As" dialog box; if there wouldn't be, we - * inactivate the menu item for "Decode As". - */ -gboolean -decode_as_ok(void) -{ - return cfile.edt->pi.ethertype || cfile.edt->pi.ipproto || decode_as_transport_ok(cfile.edt->pi.ipproto); -} - /* * Local Variables: diff --git a/packet-rtcp.c b/packet-rtcp.c index 367ef9826c..685793625c 100644 --- a/packet-rtcp.c +++ b/packet-rtcp.c @@ -1,6 +1,6 @@ /* packet-rtcp.c * - * $Id: packet-rtcp.c,v 1.25 2001/12/03 03:59:39 guy Exp $ + * $Id: packet-rtcp.c,v 1.26 2001/12/03 08:47:27 guy Exp $ * * Routines for RTCP dissection * RTCP = Real-time Transport Control Protocol @@ -1226,9 +1226,9 @@ proto_reg_handoff_rtcp(void) dissector_handle_t rtcp_handle; /* - * Register this dissector as one that can be assigned to a - * UDP conversation. + * Register this dissector as one that can be selected by a + * UDP port number. */ rtcp_handle = find_dissector("rtcp"); - conv_dissector_add("udp", rtcp_handle); + dissector_add_handle("udp.port", rtcp_handle); } diff --git a/packet-rtp.c b/packet-rtp.c index 557f9951b5..cdd3d5f368 100644 --- a/packet-rtp.c +++ b/packet-rtp.c @@ -6,7 +6,7 @@ * Copyright 2000, Philips Electronics N.V. * Written by Andreas Sikkema * - * $Id: packet-rtp.c,v 1.29 2001/12/03 03:59:39 guy Exp $ + * $Id: packet-rtp.c,v 1.30 2001/12/03 08:47:27 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -785,9 +785,9 @@ proto_reg_handoff_rtp(void) data_handle = find_dissector("data"); /* - * Register this dissector as one that can be assigned to a - * UDP conversation. + * Register this dissector as one that can be selected by a + * UDP port number. */ rtp_handle = find_dissector("rtp"); - conv_dissector_add("udp", rtp_handle); + dissector_add_handle("udp.port", rtp_handle); } diff --git a/packet-tcp.c b/packet-tcp.c index 06e98f1940..269ecf2b8b 100644 --- a/packet-tcp.c +++ b/packet-tcp.c @@ -1,7 +1,7 @@ /* packet-tcp.c * Routines for TCP packet disassembly * - * $Id: packet-tcp.c,v 1.119 2001/12/03 03:59:40 guy Exp $ + * $Id: packet-tcp.c,v 1.120 2001/12/03 08:47:27 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -88,7 +88,6 @@ static gint ett_tcp_segments = -1; static dissector_table_t subdissector_table; static heur_dissector_list_t heur_subdissector_list; -static conv_dissector_list_t conv_subdissector_list; static dissector_handle_t data_handle; /* TCP structs and definitions */ @@ -1210,7 +1209,6 @@ proto_register_tcp(void) /* subdissector code */ subdissector_table = register_dissector_table("tcp.port"); register_heur_dissector_list("tcp", &heur_subdissector_list); - register_conv_dissector_list("tcp", &conv_subdissector_list); /* Register configuration preferences */ tcp_module = prefs_register_protocol(proto_tcp, NULL); diff --git a/packet-ucp.c b/packet-ucp.c index 17018cd37a..e4ab13cb0d 100644 --- a/packet-ucp.c +++ b/packet-ucp.c @@ -2,7 +2,7 @@ * Routines for Universal Computer Protocol dissection * Copyright 2001, Tom Uijldert * - * $Id: packet-ucp.c,v 1.6 2001/12/03 03:59:40 guy Exp $ + * $Id: packet-ucp.c,v 1.7 2001/12/03 08:47:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -2510,9 +2510,10 @@ proto_reg_handoff_ucp(void) * one whenever TCP is spoken. */ heur_dissector_add("tcp", dissect_ucp_heur, proto_ucp); + /* - * Also register as one that can be assigned to a TCP conversation. + * Also register as one that can be selected by a TCP port number. */ ucp_handle = create_dissector_handle(dissect_ucp, proto_ucp); - conv_dissector_add("tcp", ucp_handle); + dissector_add_handle("tcp.port", ucp_handle); } diff --git a/packet-udp.c b/packet-udp.c index 2b941a7c55..7a89441a8b 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,7 +1,7 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.97 2001/12/03 03:59:40 guy Exp $ + * $Id: packet-udp.c,v 1.98 2001/12/03 08:47:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -77,7 +77,6 @@ typedef struct _e_udphdr { static dissector_table_t udp_dissector_table; static heur_dissector_list_t heur_subdissector_list; -static conv_dissector_list_t conv_subdissector_list; static dissector_handle_t data_handle; /* Determine if there is a sub-dissector and call it. This has been */ @@ -270,7 +269,6 @@ proto_register_udp(void) /* subdissector code */ udp_dissector_table = register_dissector_table("udp.port"); register_heur_dissector_list("udp", &heur_subdissector_list); - register_conv_dissector_list("udp", &conv_subdissector_list); /* Register configuration preferences */ udp_module = prefs_register_protocol(proto_udp, NULL);