summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-07-01 23:56:54 -0400
committerAnders Broman <a.broman58@gmail.com>2015-07-02 08:58:46 +0000
commitcc7dc0332ad061a457980febf62f0313788f28a9 (patch)
treedace87f1d77f34e94e6df91093d135eb45c8fc5d
parent987cf4cd167a4c950cf58479db5de17bd647d538 (diff)
downloadwireshark-cc7dc0332ad061a457980febf62f0313788f28a9.tar.gz
Add support for a "custom" dissector table. This allows for a "custom" (not UINT or string) key to register dissector handles.
This was designed for RPC dissectors, but probably has use elsewhere. Change-Id: I1bca6b50ba312129a0c4fad5cc3c18cd9297c217 Reviewed-on: https://code.wireshark.org/review/9455 Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/packet.c91
-rw-r--r--epan/packet.h24
2 files changed, 115 insertions, 0 deletions
diff --git a/epan/packet.c b/epan/packet.c
index dcd8d059d6..07ae74f76b 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -91,6 +91,7 @@ struct dissector_table {
const char *ui_name;
ftenum_t type;
int param;
+ GHashFunc hash_func;
};
static GHashTable *dissector_tables = NULL;
@@ -1474,6 +1475,53 @@ dissector_get_default_string_handle(const char *name, const gchar *string)
return NULL;
}
+/* Add an entry to a "custom" dissector table. */
+void dissector_add_custom_table_handle(const char *name, void *pattern, dissector_handle_t handle)
+{
+ dissector_table_t sub_dissectors = find_dissector_table( name);
+ dtbl_entry_t *dtbl_entry;
+
+ /*
+ * Make sure the dissector table exists.
+ */
+ if (sub_dissectors == NULL) {
+ fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
+ name);
+ fprintf(stderr, "Protocol being registered is \"%s\"\n",
+ proto_get_protocol_long_name(handle->protocol));
+ if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
+ abort();
+ return;
+ }
+
+ g_assert(sub_dissectors->type == FT_BYTES);
+
+ dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
+ dtbl_entry->current = handle;
+ dtbl_entry->initial = dtbl_entry->current;
+
+ /* do the table insertion */
+ g_hash_table_insert( sub_dissectors->hash_table, (gpointer)pattern,
+ (gpointer)dtbl_entry);
+
+ /*
+ * Now add it to the list of handles that could be used for
+ * "Decode As" with this table, because it *is* being used
+ * with this table.
+ */
+ dissector_add_for_decode_as(name, handle);
+}
+
+dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_dissectors, void *key)
+{
+ dtbl_entry_t *dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
+
+ if (dtbl_entry != NULL)
+ return dtbl_entry->current;
+
+ return NULL;
+}
+
dissector_handle_t
dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
{
@@ -1817,6 +1865,7 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t
* XXX - there's no "g_uint_hash()" or "g_uint_equal()",
* so we use "g_direct_hash()" and "g_direct_equal()".
*/
+ sub_dissectors->hash_func = g_direct_hash;
sub_dissectors->hash_table = g_hash_table_new_full( g_direct_hash,
g_direct_equal,
NULL,
@@ -1826,6 +1875,7 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t
case FT_STRING:
case FT_STRINGZ:
case FT_STRINGZPAD:
+ sub_dissectors->hash_func = g_str_hash;
sub_dissectors->hash_table = g_hash_table_new_full( g_str_hash,
g_str_equal,
&g_free,
@@ -1843,6 +1893,33 @@ register_dissector_table(const char *name, const char *ui_name, const ftenum_t t
return sub_dissectors;
}
+dissector_table_t register_custom_dissector_table(const char *name,
+ const char *ui_name, GHashFunc hash_func, GEqualFunc key_equal_func)
+{
+ dissector_table_t sub_dissectors;
+
+ /* Make sure the registration is unique */
+ if(g_hash_table_lookup( dissector_tables, name )) {
+ g_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
+ }
+
+ /* Create and register the dissector table for this name; returns */
+ /* a pointer to the dissector table. */
+ sub_dissectors = g_slice_new(struct dissector_table);
+ sub_dissectors->hash_func = hash_func;
+ sub_dissectors->hash_table = g_hash_table_new_full(hash_func,
+ key_equal_func,
+ &g_free,
+ &g_free );
+
+ sub_dissectors->dissector_handles = NULL;
+ sub_dissectors->ui_name = ui_name;
+ sub_dissectors->type = FT_BYTES; /* Consider key a "blob" of data, no need to really create new type */
+ sub_dissectors->param = BASE_NONE;
+ g_hash_table_insert( dissector_tables, (gpointer)name, (gpointer) sub_dissectors );
+ return sub_dissectors;
+}
+
const char *
get_dissector_table_ui_name(const char *name)
{
@@ -2338,6 +2415,20 @@ new_create_dissector_handle(new_dissector_t dissector, const int proto)
return handle;
}
+dissector_handle_t new_create_dissector_handle_with_name(new_dissector_t dissector,
+ const int proto, const char* name)
+{
+ struct dissector_handle *handle;
+
+ handle = wmem_new(wmem_epan_scope(), struct dissector_handle);
+ handle->name = name;
+ handle->is_new = TRUE;
+ handle->dissector.new_d = dissector;
+ handle->protocol = find_protocol_by_id(proto);
+
+ return handle;
+}
+
/* Register a dissector by name. */
dissector_handle_t
register_dissector(const char *name, dissector_t dissector, const int proto)
diff --git a/epan/packet.h b/epan/packet.h
index f4182bf4b4..846567e5ba 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -201,6 +201,13 @@ WS_DLL_PUBLIC void dissector_all_tables_foreach_table (DATFunc_table func,
WS_DLL_PUBLIC dissector_table_t register_dissector_table(const char *name,
const char *ui_name, const ftenum_t type, const int param);
+/*
+ * Similar to register_dissector_table, but with a "custom" hash function
+ * to store subdissectors.
+ */
+WS_DLL_PUBLIC dissector_table_t register_custom_dissector_table(const char *name,
+ const char *ui_name, GHashFunc hash_func, GEqualFunc key_equal_func);
+
/* Find a dissector table by table name. */
WS_DLL_PUBLIC dissector_table_t find_dissector_table(const char *name);
@@ -322,6 +329,21 @@ WS_DLL_PUBLIC dissector_handle_t dissector_get_string_handle(
WS_DLL_PUBLIC dissector_handle_t dissector_get_default_string_handle(
const char *name, const gchar *string);
+/* Add an entry to a "custom" dissector table. */
+WS_DLL_PUBLIC void dissector_add_custom_table_handle(const char *name, void *pattern,
+ dissector_handle_t handle);
+
+/** Look for a given key in a given "custom" dissector table and, if found,
+ * return the current dissector handle for that key.
+ *
+ * @param[in] sub_dissectors Dissector table to search.
+ * @param[in] key Value to match, e.g. RPC key for its subdissectors
+ * @return The matching dissector handle on success, NULL if no match is found.
+ */
+WS_DLL_PUBLIC dissector_handle_t dissector_get_custom_table_handle(
+ dissector_table_t sub_dissectors, void *key);
+
+
/* Add a handle to the list of handles that *could* be used with this
table. That list is used by the "Decode As"/"-d" code in the UI. */
WS_DLL_PUBLIC void dissector_add_for_decode_as(const char *name,
@@ -482,6 +504,8 @@ WS_DLL_PUBLIC dissector_handle_t create_dissector_handle(dissector_t dissector,
const int proto);
WS_DLL_PUBLIC dissector_handle_t new_create_dissector_handle(new_dissector_t dissector,
const int proto);
+WS_DLL_PUBLIC dissector_handle_t new_create_dissector_handle_with_name(new_dissector_t dissector,
+ const int proto, const char* name);
/** Call a dissector through a handle and if no dissector was found
* pass it over to the "data" dissector instead.