aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2013-12-10 19:23:26 +0000
committerGerald Combs <gerald@wireshark.org>2013-12-10 19:23:26 +0000
commit17a67c3b5cb80619ab7e1260a05a28e888cee09e (patch)
tree538f734525e8a488e4fc60ad4eff509a80458c8f /epan
parent5fa7d37e377abb89e317f4ebd47ebea69ebe0fd9 (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.c210
-rw-r--r--epan/decode_as.h39
-rw-r--r--epan/dissectors/packet-ber.c2
-rw-r--r--epan/dissectors/packet-dcerpc.c2
-rw-r--r--epan/packet.c35
-rw-r--r--epan/packet.h38
-rw-r--r--epan/prefs.c6
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);