diff options
author | Gerald Combs <gerald@wireshark.org> | 2013-12-10 19:23:26 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2013-12-10 19:23:26 +0000 |
commit | 17a67c3b5cb80619ab7e1260a05a28e888cee09e (patch) | |
tree | 538f734525e8a488e4fc60ad4eff509a80458c8f /epan | |
parent | 5fa7d37e377abb89e317f4ebd47ebea69ebe0fd9 (diff) |
Get the "Decode As" dialog working, albeit with a few warts. It differs
from the GTK flavor in two major ways:
- The "Decode As" and "User Specified Decodes" dialog have been unified.
- You can modify the decode as behavior at any time, not just when you
have a packet selected.
Revert part of 53498 so that we can move items marked
/*** THE FOLLOWING SHOULD NOT BE USED BY ANY DISSECTORS!!! ***/
from epan/decode_as.h to ui/decode_as_utils.h.
Move "save" code from decode_as_dlg.c to decode_as_utils.c as well.
In packet-dcerpc.c don't register a table named "ethertype". We might
want to add checks for duplicate table names.
To do:
- Add support for ranges?
- Either add support for DCERPC or make DCERPC use a regular dissector
table.
- Fix string selectors (i.e. BER).
svn path=/trunk/; revision=53910
Diffstat (limited to 'epan')
-rw-r--r-- | epan/decode_as.c | 210 | ||||
-rw-r--r-- | epan/decode_as.h | 39 | ||||
-rw-r--r-- | epan/dissectors/packet-ber.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-dcerpc.c | 2 | ||||
-rw-r--r-- | epan/packet.c | 35 | ||||
-rw-r--r-- | epan/packet.h | 38 | ||||
-rw-r--r-- | epan/prefs.c | 6 |
7 files changed, 73 insertions, 259 deletions
diff --git a/epan/decode_as.c b/epan/decode_as.c index 9f8791e765..287ffb229c 100644 --- a/epan/decode_as.c +++ b/epan/decode_as.c @@ -24,28 +24,14 @@ #include "config.h" -#include <stdlib.h> - #include <glib.h> #include "decode_as.h" #include "packet.h" -#include "prefs.h" -#include "prefs-int.h" - -#include "epan/dissectors/packet-dcerpc.h" - -#include "wsutil/filesystem.h" -#include "wsutil/file_util.h" +/* XXX Should this be in ui/decode_as_util? */ GList *decode_as_list = NULL; -/* - * A list of dissectors that need to be reset. - */ -GSList *dissector_reset_list = NULL; - - void register_decode_as(decode_as_t* reg) { /* Ensure valid functions */ @@ -92,7 +78,6 @@ void decode_as_default_populate_list(const gchar *table_name, decode_as_add_to_l dissector_table_foreach_handle(table_name, decode_proto_add_to_list, &populate); } - gboolean decode_as_default_reset(const char *name, const gpointer pattern) { dissector_reset_uint(name, GPOINTER_TO_UINT(pattern)); @@ -107,199 +92,6 @@ gboolean decode_as_default_change(const char *name, const gpointer pattern, gpoi return TRUE; } -/* UI-related functions */ - -/* - * Data structure used as user data when iterating dissector handles - */ -struct lookup_entry { - gchar* dissector_short_name; - dissector_handle_t handle; -}; - -/* - * Data structure for tracking which dissector need to be reset. This - * structure is necessary as a hash table entry cannot be removed - * while a g_hash_table_foreach walk is in progress. - */ -struct dissector_delete_item { - /* The name of the dissector table */ - const gchar *ddi_table_name; - /* The type of the selector in that dissector table */ - ftenum_t ddi_selector_type; - /* The selector in the dissector table */ - union { - guint sel_uint; - char *sel_string; - } ddi_selector; -}; - -typedef struct lookup_entry lookup_entry_t; - -/* - * A callback function to changed a dissector_handle if matched - * This is used when iterating a dissector table - */ -static void -change_dissector_if_matched(gpointer item, gpointer user_data) -{ - dissector_handle_t handle = (dissector_handle_t)item; - lookup_entry_t * lookup = (lookup_entry_t *)user_data; - if (strcmp(lookup->dissector_short_name, dissector_handle_get_short_name(handle)) == 0) { - lookup->handle = handle; - } -} - -/* - * A callback function to parse each "decode as" entry in the file and apply the change - */ -static prefs_set_pref_e -read_set_decode_as_entries(gchar *key, const gchar *value, - void *user_data _U_, - gboolean return_range_errors _U_) -{ - gchar *values[4] = {NULL, NULL, NULL, NULL}; - gchar delimiter[4] = {',', ',', ',','\0'}; - gchar *pch; - guint i, j; - dissector_table_t sub_dissectors; - prefs_set_pref_e retval = PREFS_SET_OK; - gboolean is_valid = FALSE; - - if (strcmp(key, DECODE_AS_ENTRY) == 0) { - /* Parse csv into table, selector, initial, current */ - for (i = 0; i < 4; i++) { - pch = strchr(value, delimiter[i]); - if (pch == NULL) { - for (j = 0; j < i; j++) { - g_free(values[j]); - } - return PREFS_SET_SYNTAX_ERR; - } - values[i] = g_strndup(value, pch - value); - value = pch + 1; - } - sub_dissectors = find_dissector_table(values[0]); - if (sub_dissectors != NULL) { - lookup_entry_t lookup; - lookup.dissector_short_name = values[3]; - lookup.handle = NULL; - g_slist_foreach(dissector_table_get_dissector_handles(sub_dissectors), - change_dissector_if_matched, &lookup); - if (lookup.handle != NULL || g_ascii_strcasecmp(values[3], DECODE_AS_NONE) == 0) { - is_valid = TRUE; - } - - if (is_valid) { - dissector_change_uint(values[0], atoi(values[1]), lookup.handle); - decode_build_reset_list(g_strdup(values[0]), dissector_table_get_type(sub_dissectors), - g_strdup(values[1]), NULL, NULL); - } - } else { - retval = PREFS_SET_SYNTAX_ERR; - } - - } else { - retval = PREFS_SET_NO_SUCH_PREF; - } - - for (i = 0; i < 4; i++) { - g_free(values[i]); - } - return retval; -} - -void load_decode_as_entries(void) -{ - char *daf_path; - FILE *daf; - - if (dissector_reset_list) { - decode_clear_all(); - } - - daf_path = get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME, TRUE); - if ((daf = ws_fopen(daf_path, "r")) != NULL) { - read_prefs_file(daf_path, daf, read_set_decode_as_entries, NULL); - fclose(daf); - } - g_free(daf_path); -} - -/* - * A typedef for the data structure to track the original dissector - * used for any given port on any given protocol. - */ -typedef struct dissector_delete_item dissector_delete_item_t; - -void -decode_build_reset_list (const gchar *table_name, ftenum_t selector_type, - gpointer key, gpointer value _U_, - gpointer user_data _U_) -{ - dissector_delete_item_t *item; - - item = g_new(dissector_delete_item_t,1); - item->ddi_table_name = table_name; - item->ddi_selector_type = selector_type; - switch (selector_type) { - - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - item->ddi_selector.sel_uint = GPOINTER_TO_UINT(key); - break; - - case FT_STRING: - case FT_STRINGZ: - item->ddi_selector.sel_string = (char *)key; - break; - - default: - g_assert_not_reached(); - } - dissector_reset_list = g_slist_prepend(dissector_reset_list, item); -} - -/* clear all settings */ -void -decode_clear_all(void) -{ - dissector_delete_item_t *item; - GSList *tmp; - - dissector_all_tables_foreach_changed(decode_build_reset_list, NULL); - - for (tmp = dissector_reset_list; tmp; tmp = g_slist_next(tmp)) { - item = (dissector_delete_item_t *)tmp->data; - switch (item->ddi_selector_type) { - - case FT_UINT8: - case FT_UINT16: - case FT_UINT24: - case FT_UINT32: - dissector_reset_uint(item->ddi_table_name, - item->ddi_selector.sel_uint); - break; - - case FT_STRING: - case FT_STRINGZ: - dissector_reset_string(item->ddi_table_name, - item->ddi_selector.sel_string); - break; - - default: - g_assert_not_reached(); - } - g_free(item); - } - g_slist_free(dissector_reset_list); - dissector_reset_list = NULL; - - decode_dcerpc_reset_all(); -} - /* * Editor modelines * diff --git a/epan/decode_as.h b/epan/decode_as.h index c28d7d60fd..248cdf23bf 100644 --- a/epan/decode_as.h +++ b/epan/decode_as.h @@ -94,43 +94,10 @@ WS_DLL_PUBLIC gboolean decode_as_default_reset(const char *name, const gpointer /* Add a FT_UINT32 value to dissector table list */ WS_DLL_PUBLIC gboolean decode_as_default_change(const char *name, const gpointer pattern, gpointer handle, gchar* list_name); -/*** THE FOLLOWING SHOULD NOT BE USED BY ANY DISSECTORS!!! ***/ - -WS_DLL_PUBLIC GList *decode_as_list; - -/** Reset the "decode as" entries and reload ones of the current profile. - */ -WS_DLL_PUBLIC void load_decode_as_entries(void); - -/* - * This routine creates one entry in the list of protocol dissector - * that need to be reset. It is called by the g_hash_table_foreach - * routine once for each changed entry in a dissector table. - * Unfortunately it cannot delete the entry immediately as this screws - * up the foreach function, so it builds a list of dissectors to be - * reset once the foreach routine finishes. - * - * @param table_name The table name in which this dissector is found. - * - * @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 routine in the file packet.c - but it's unused. - * - * @param user_data Unused. +/** List of registered decode_as_t structs. + * For UI code only. Should not be directly accessed by dissectors. */ -WS_DLL_PUBLIC void decode_build_reset_list (const gchar *table_name, ftenum_t selector_type, - gpointer key, gpointer value _U_, - gpointer user_data _U_); - -/** Clear all "decode as" settings - */ -WS_DLL_PUBLIC void decode_clear_all(void); - +WS_DLL_PUBLIC GList *decode_as_list; #ifdef __cplusplus } diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c index ffdc7aad39..f8dad61126 100644 --- a/epan/dissectors/packet-ber.c +++ b/epan/dissectors/packet-ber.c @@ -5463,7 +5463,7 @@ proto_register_ber(void) users_uat); ber_oid_dissector_table = register_dissector_table("ber.oid", "BER OID Dissectors", FT_STRING, BASE_NONE); - ber_syntax_dissector_table = register_dissector_table("ber.syntax", "BER Syntax Dissectors", FT_STRING, BASE_NONE); + ber_syntax_dissector_table = register_dissector_table("ber.syntax", "BER syntax", FT_STRING, BASE_NONE); syntax_table = g_hash_table_new(g_str_hash, g_str_equal); /* oid to syntax */ register_ber_syntax_dissector("ASN.1", proto_ber, dissect_ber_syntax); diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c index 86e9b9748a..6fd3bcdaaa 100644 --- a/epan/dissectors/packet-dcerpc.c +++ b/epan/dissectors/packet-dcerpc.c @@ -6322,7 +6322,7 @@ proto_register_dcerpc(void) static decode_as_t dcerpc_da = {"dcerpc", "DCE-RPC", /* XXX - DCE/RPC doesn't have a true (sub)dissector table, so provide a "fake" one to fit the Decode As algorithm */ - "ethertype", + "dcerpc.fake", 1, 0, &dcerpc_da_values, NULL, NULL, dcerpc_populate_list, decode_dcerpc_binding_reset, dcerpc_decode_as_change, dcerpc_decode_as_free}; diff --git a/epan/packet.c b/epan/packet.c index 9befce39d1..2a1da2a74a 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -1070,6 +1070,19 @@ dissector_get_uint_handle(dissector_table_t const sub_dissectors, const guint32 return NULL; } +dissector_handle_t +dissector_get_default_uint_handle(const char *name, const guint32 uint_val) +{ + dissector_table_t sub_dissectors = find_dissector_table(name); + + if (sub_dissectors != NULL) { + dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val); + if (dtbl_entry != NULL) + return dtbl_entry->initial; + } + return NULL; +} + /* Find an entry in a string dissector table. */ static dtbl_entry_t * find_string_dtbl_entry(dissector_table_t const sub_dissectors, const gchar *pattern) @@ -1323,6 +1336,19 @@ dissector_get_string_handle(dissector_table_t sub_dissectors, } dissector_handle_t +dissector_get_default_string_handle(const char *name, const gchar *string) +{ + dissector_table_t sub_dissectors = find_dissector_table(name); + + if (sub_dissectors != NULL) { + dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string); + if (dtbl_entry != NULL) + return dtbl_entry->initial; + } + return NULL; +} + +dissector_handle_t dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry) { return dtbl_entry->current; @@ -1691,7 +1717,8 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t const char * get_dissector_table_ui_name(const char *name) { - dissector_table_t sub_dissectors = find_dissector_table( name); + dissector_table_t sub_dissectors = find_dissector_table(name); + if (!sub_dissectors) return NULL; return sub_dissectors->ui_name; } @@ -1699,7 +1726,8 @@ get_dissector_table_ui_name(const char *name) ftenum_t get_dissector_table_selector_type(const char *name) { - dissector_table_t sub_dissectors = find_dissector_table( name); + dissector_table_t sub_dissectors = find_dissector_table(name); + if (!sub_dissectors) return FT_NONE; return sub_dissectors->type; } @@ -1707,7 +1735,8 @@ get_dissector_table_selector_type(const char *name) int get_dissector_table_base(const char *name) { - dissector_table_t sub_dissectors = find_dissector_table( name); + dissector_table_t sub_dissectors = find_dissector_table(name); + if (!sub_dissectors) return 0; return sub_dissectors->base; } diff --git a/epan/packet.h b/epan/packet.h index 205df7ff3b..2b850c3782 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -256,11 +256,26 @@ WS_DLL_PUBLIC gboolean dissector_try_uint(dissector_table_t sub_dissectors, WS_DLL_PUBLIC gboolean dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data); -/* Look for a given value in a given uint dissector table and, if found, - return the dissector handle for that value. */ +/** Look for a given value in a given uint dissector table and, if found, + * return the current dissector handle for that value. + * + * @param[in] sub_dissectors Dissector table to search. + * @param[in] uint_val Value to match, e.g. the port number for the TCP dissector. + * @return The matching dissector handle on success, NULL if no match is found. + */ WS_DLL_PUBLIC dissector_handle_t dissector_get_uint_handle( dissector_table_t const sub_dissectors, const guint32 uint_val); +/** Look for a given value in a given uint dissector table and, if found, + * return the default dissector handle for that value. + * + * @param[in] name Dissector table name. + * @param[in] uint_val Value to match, e.g. the port number for the TCP dissector. + * @return The matching dissector handle on success, NULL if no match is found. + */ +WS_DLL_PUBLIC dissector_handle_t dissector_get_default_uint_handle( + const char *name, const guint32 uint_val); + /* Add an entry to a string dissector table. */ WS_DLL_PUBLIC void dissector_add_string(const char *name, const gchar *pattern, dissector_handle_t handle); @@ -284,11 +299,26 @@ WS_DLL_PUBLIC void dissector_reset_string(const char *name, const gchar *pattern WS_DLL_PUBLIC gboolean dissector_try_string(dissector_table_t sub_dissectors, const gchar *string, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data); -/* Look for a given value in a given string dissector table and, if found, - return the dissector handle for that value. */ +/** Look for a given value in a given string dissector table and, if found, + * return the current dissector handle for that value. + * + * @param[in] sub_dissectors Dissector table to search. + * @param[in] string Value to match, e.g. the OID for the BER dissector. + * @return The matching dissector handle on success, NULL if no match is found. + */ WS_DLL_PUBLIC dissector_handle_t dissector_get_string_handle( dissector_table_t sub_dissectors, const gchar *string); +/** Look for a given value in a given string dissector table and, if found, + * return the default dissector handle for that value. + * + * @param[in] name Dissector table name. + * @param[in] string Value to match, e.g. the OID for the BER dissector. + * @return The matching dissector handle on success, NULL if no match is found. + */ +WS_DLL_PUBLIC dissector_handle_t dissector_get_default_string_handle( + const char *name, const gchar *string); + /* Add a handle to the list of handles that *could* be used with this table. That list is used by code in the UI. */ WS_DLL_PUBLIC void dissector_add_handle(const char *name, dissector_handle_t handle); diff --git a/epan/prefs.c b/epan/prefs.c index b3e210df43..cb4daa3bdc 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -39,7 +39,6 @@ #include <wsutil/filesystem.h> #include <epan/address.h> #include <epan/addr_resolv.h> -#include <epan/decode_as.h> #include <epan/oids.h> #ifdef HAVE_GEOIP #include <epan/geoip_db.h> @@ -3270,9 +3269,6 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return, /* load SMI modules if needed */ oids_init(); - /* load the decode as entries of this profile */ - load_decode_as_entries(); - return &prefs; } @@ -4795,7 +4791,7 @@ write_prefs(char **pf_path_return) fputs("# Configuration file for Wireshark " VERSION ".\n" "#\n" "# This file is regenerated each time preferences are saved within\n" - "# Wireshark. Making manual changes should be safe, however.\n" + "# Wireshark. Making manual changes should be safe, however.\n" "# Preferences that have been commented out have not been\n" "# changed from their default value.\n", pf); |