aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/decode_as.c202
-rw-r--r--epan/decode_as.h43
-rw-r--r--epan/dissectors/packet-dcerpc.h14
-rw-r--r--epan/packet.c30
-rw-r--r--epan/packet.h63
-rw-r--r--epan/prefs.c5
6 files changed, 341 insertions, 16 deletions
diff --git a/epan/decode_as.c b/epan/decode_as.c
index a792d84150..f6761e4ddd 100644
--- a/epan/decode_as.c
+++ b/epan/decode_as.c
@@ -25,13 +25,25 @@
#include "config.h"
#include <glib.h>
-#include "packet.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"
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,3 +104,191 @@ gboolean decode_as_default_change(const char *name, const gpointer pattern, gpoi
dissector_change_uint(name, GPOINTER_TO_UINT(pattern), *dissector);
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;
+
+ 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) {
+ 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();
+}
diff --git a/epan/decode_as.h b/epan/decode_as.h
index e25df5d41a..9308dda42d 100644
--- a/epan/decode_as.h
+++ b/epan/decode_as.h
@@ -27,6 +27,9 @@
#include "ws_symbol_export.h"
+#include "ftypes/ftypes.h"
+#include "packet_info.h"
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -35,6 +38,12 @@ extern "C" {
*/
#define MAX_DECODE_AS_PROMPT_LEN 200
+#define DECODE_AS_ENTRY "decode_as_entry"
+/*
+ * Filename of the "decode as" entry preferences
+ */
+#define DECODE_AS_ENTRIES_FILE_NAME "decode_as_entries"
+
/** callback function definition: return formatted label string */
typedef void (*build_label_func)(packet_info *pinfo, gchar* result);
@@ -87,6 +96,40 @@ WS_DLL_PUBLIC gboolean decode_as_default_change(const char *name, const gpointer
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.
+ */
+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);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/epan/dissectors/packet-dcerpc.h b/epan/dissectors/packet-dcerpc.h
index 01435864fa..10062cfd90 100644
--- a/epan/dissectors/packet-dcerpc.h
+++ b/epan/dissectors/packet-dcerpc.h
@@ -29,6 +29,10 @@
#include <epan/conversation.h>
#include "ws_symbol_export.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
/*
* Data representation.
*/
@@ -253,7 +257,7 @@ int dissect_ndr_uint64 (tvbuff_t *tvb, gint offset, packet_info *pinfo,
int PIDL_dissect_uint64 (tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex, guint32 param);
int PIDL_dissect_uint64_val (tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex, guint32 param, guint64 *pval);
int dissect_ndr_float (tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, dcerpc_info *di, guint8 *drep,
+ proto_tree *tree, dcerpc_info *di, guint8 *drep,
int hfindex, gfloat *pdata);
WS_DLL_PUBLIC
int dissect_ndr_double (tvbuff_t *tvb, gint offset, packet_info *pinfo,
@@ -351,7 +355,7 @@ int PIDL_dissect_cvstring(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_t
int dissect_ndr_cstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, dcerpc_info *di, guint8 *drep, int size_is,
int hfindex, gboolean add_subtree, char **data);
-int dissect_ndr_vstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
+int dissect_ndr_vstring(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, dcerpc_info *di, guint8 *drep, int size_is,
int hfinfo, gboolean add_subtree,
char **data);
@@ -546,6 +550,10 @@ extern int hf_dcerpc_drep_byteorder;
\
/* we need di->call_data->flags.NDR64 == 0 */ \
call_data.flags = 0; \
- di.call_data = &call_data;
+ di.call_data = &call_data;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
#endif /* packet-dcerpc.h */
diff --git a/epan/packet.c b/epan/packet.c
index 5e5f5bdb83..d814fb5c81 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1394,6 +1394,18 @@ dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry)
return dtbl_entry->initial;
}
+GSList *
+dissector_table_get_dissector_handles(dissector_table_t dissector_table) {
+ if (!dissector_table) return NULL;
+ return dissector_table->dissector_handles;
+}
+
+ftenum_t
+dissector_table_get_type(dissector_table_t dissector_table) {
+ if (!dissector_table) return FT_NONE;
+ return dissector_table->type;
+}
+
/**************************************************/
/* */
/* Routines to walk dissector tables */
@@ -1478,14 +1490,14 @@ dissector_all_tables_foreach (DATFunc func,
* on each entry.
*/
void
-dissector_table_foreach (const char *name,
+dissector_table_foreach (const char *table_name,
DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
- dissector_table_t sub_dissectors = find_dissector_table( name);
+ dissector_table_t sub_dissectors = find_dissector_table(table_name);
- info.table_name = name;
+ info.table_name = table_name;
info.selector_type = sub_dissectors->type;
info.caller_func = func;
info.caller_data = user_data;
@@ -1497,16 +1509,16 @@ dissector_table_foreach (const char *name,
* function on each entry.
*/
void
-dissector_table_foreach_handle(const char *name,
+dissector_table_foreach_handle(const char *table_name,
DATFunc_handle func,
gpointer user_data)
{
- dissector_table_t sub_dissectors = find_dissector_table( name);
+ dissector_table_t sub_dissectors = find_dissector_table(table_name);
GSList *tmp;
for (tmp = sub_dissectors->dissector_handles; tmp != NULL;
tmp = g_slist_next(tmp))
- func(name, tmp->data, user_data);
+ func(table_name, tmp->data, user_data);
}
/*
@@ -1555,14 +1567,14 @@ dissector_all_tables_foreach_changed (DATFunc func,
* any entry that has been changed from its original state.
*/
void
-dissector_table_foreach_changed (const char *name,
+dissector_table_foreach_changed (const char *table_name,
DATFunc func,
gpointer user_data)
{
dissector_foreach_info_t info;
- dissector_table_t sub_dissectors = find_dissector_table( name);
+ dissector_table_t sub_dissectors = find_dissector_table(table_name);
- info.table_name = name;
+ info.table_name = table_name;
info.selector_type = sub_dissectors->type;
info.caller_func = func;
info.caller_data = user_data;
diff --git a/epan/packet.h b/epan/packet.h
index e176623614..78531c18ed 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -140,14 +140,63 @@ typedef struct dtbl_entry dtbl_entry_t;
WS_DLL_PUBLIC dissector_handle_t dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry);
WS_DLL_PUBLIC dissector_handle_t dtbl_entry_get_initial_handle (dtbl_entry_t * entry);
-void dissector_table_foreach_changed (const char *name, DATFunc func,
+
+/** Iterate over dissectors in a table with non-default "decode as" settings.
+ *
+ * Walk one dissector table calling a user supplied function only on
+ * any entry that has been changed from its original state.
+ *
+ * @param[in] table_name The name of the dissector table, e.g. "ip.proto".
+ * @param[in] func The function to call for each dissector.
+ * @param[in] user_data User data to pass to the function.
+ */
+void dissector_table_foreach_changed (const char *table_name, DATFunc func,
gpointer user_data);
-WS_DLL_PUBLIC void dissector_table_foreach (const char *name, DATFunc func,
+
+/** Iterate over dissectors in a table.
+ *
+ * Walk one dissector table's hash table calling a user supplied function
+ * on each entry.
+ *
+ * @param[in] table_name The name of the dissector table, e.g. "ip.proto".
+ * @param[in] func The function to call for each dissector.
+ * @param[in] user_data User data to pass to the function.
+ */
+WS_DLL_PUBLIC void dissector_table_foreach (const char *table_name, DATFunc func,
gpointer user_data);
+
+/** Iterate over dissectors with non-default "decode as" settings.
+ *
+ * Walk all dissector tables calling a user supplied function only on
+ * any "decode as" entry that has been changed from its original state.
+ *
+ * @param[in] func The function to call for each dissector.
+ * @param[in] data User data to pass to the function.
+ */
WS_DLL_PUBLIC void dissector_all_tables_foreach_changed (DATFunc func,
gpointer user_data);
-WS_DLL_PUBLIC void dissector_table_foreach_handle(const char *name, DATFunc_handle func,
+
+/** Iterate over dissectors in a table by handle.
+ *
+ * Walk one dissector table's list of handles calling a user supplied
+ * function on each entry.
+ *
+ * @param[in] table_name The name of the dissector table, e.g. "ip.proto".
+ * @param[in] func The function to call for each dissector.
+ * @param[in] user_data User data to pass to the function.
+ */
+WS_DLL_PUBLIC void dissector_table_foreach_handle(const char *table_name, DATFunc_handle func,
gpointer user_data);
+
+/** Iterate over dissectors in a table matching against a given function.
+ *
+ * Walk all dissector tables calling a user supplied function on each
+ * table.
+ * @param[in] func The function to call for each dissector.
+ * @param[in] user_data User data to pass to the function.
+ * @param[in] compare_key_func Hash table key comparison function. All entries
+ * are matched if NULL.
+ */
WS_DLL_PUBLIC void dissector_all_tables_foreach_table (DATFunc_table func,
gpointer user_data, GCompareFunc compare_key_func);
@@ -246,6 +295,14 @@ WS_DLL_PUBLIC dissector_handle_t dissector_get_string_handle(
table. That list is used by code in the UI. */
WS_DLL_PUBLIC void dissector_add_handle(const char *name, dissector_handle_t handle);
+/** Get the list of handles for a dissector table
+ */
+WS_DLL_PUBLIC GSList *dissector_table_get_dissector_handles(dissector_table_t dissector_table);
+
+/** Get a dissector table's type
+ */
+WS_DLL_PUBLIC ftenum_t dissector_table_get_type(dissector_table_t dissector_table);
+
/* 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
diff --git a/epan/prefs.c b/epan/prefs.c
index d0cf5817bc..ab55672406 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -39,6 +39,7 @@
#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>
@@ -3036,6 +3037,7 @@ prefs_reset(void)
and a pointer to the path of the file into "*pf_path_return", and
return NULL. */
e_prefs *
+
read_prefs(int *gpf_errno_return, int *gpf_read_errno_return,
char **gpf_path_return, int *pf_errno_return,
int *pf_read_errno_return, char **pf_path_return)
@@ -3148,6 +3150,9 @@ 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;
}