aboutsummaryrefslogtreecommitdiffstats
path: root/epan/capture_dissectors.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-12-13 16:54:16 -0500
committerMichael Mann <mmann78@netscape.net>2015-12-14 12:17:49 +0000
commit0960ac4dfdbfba5a81c56a49cfc6201ecd8f48e3 (patch)
tree3d88cd321da2fade206b9ccddff22b70ecdfae28 /epan/capture_dissectors.c
parent9319357f5e27c10f2d29e78fcdf9d323c2af36b0 (diff)
Create capture dissector tables.
They are modeled after dissection dissector tables, but for the moment, don't have/need the flexibility. They are intended to be much simpler/faster than full dissection. The two most used/needed are "wtap_encap" and "ethertype", so they were the basis of starting to use and test capture dissector table API. Others may be added in the future. The "capture dissector" function signature needed a bit of tweeking to handling "claiming" of a packet. The current application of this is capture functions returning TRUE if they affected a "type" of packet count. Returning FALSE ends up considering the packet an "other" type. Change-Id: I81d06a6ccb2c03665f087258a46b9d78d513d6cd Reviewed-on: https://code.wireshark.org/review/12607 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/capture_dissectors.c')
-rw-r--r--epan/capture_dissectors.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/epan/capture_dissectors.c b/epan/capture_dissectors.c
index 738bacbc90..1368c254e0 100644
--- a/epan/capture_dissectors.c
+++ b/epan/capture_dissectors.c
@@ -27,48 +27,93 @@
#include "capture_dissectors.h"
+struct capture_dissector_table {
+ GHashTable *hash_table;
+ const char *ui_name;
+};
+
struct capture_dissector_handle
{
- gint linktype;
+ guint32 pattern;
capture_dissector_t dissector;
protocol_t* protocol;
};
-static GHashTable *registered_capture_dissectors = NULL;
+static GHashTable *capture_dissector_tables = NULL;
+
+static void
+destroy_capture_dissector_table(void *data)
+{
+ struct capture_dissector_table *table = (struct capture_dissector_table *)data;
+
+ g_hash_table_destroy(table->hash_table);
+ g_free(data);
+}
void capture_dissector_init(void)
{
- registered_capture_dissectors = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
+ capture_dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, destroy_capture_dissector_table);
}
void capture_dissector_cleanup(void)
{
- g_hash_table_destroy(registered_capture_dissectors);
- registered_capture_dissectors = NULL;
+ g_hash_table_destroy(capture_dissector_tables);
}
-void register_capture_dissector(gint linktype, capture_dissector_t dissector, const int proto)
+void register_capture_dissector_table(const char *name, const char *ui_name)
{
+ struct capture_dissector_table* sub_dissectors;
+
+ /* Make sure the registration is unique */
+ if(g_hash_table_lookup( capture_dissector_tables, name )) {
+ g_error("The capture dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
+ }
+
+ sub_dissectors = g_new(struct capture_dissector_table, 1);
+
+ sub_dissectors->hash_table = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, NULL );
+ sub_dissectors->ui_name = ui_name;
+ g_hash_table_insert( capture_dissector_tables, (gpointer)name, (gpointer) sub_dissectors );
+
+}
+
+void register_capture_dissector(const char* name, const guint32 pattern, capture_dissector_t dissector, const int proto)
+{
+ struct capture_dissector_table* sub_dissectors;
struct capture_dissector_handle *handle;
+ /* Make sure table exists */
+ sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name );
+ g_assert(sub_dissectors != NULL);
+
/* Make sure the registration is unique */
- g_assert(g_hash_table_lookup(registered_capture_dissectors, GUINT_TO_POINTER(linktype)) == NULL);
+ g_assert(g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)) == NULL);
handle = wmem_new(wmem_epan_scope(), struct capture_dissector_handle);
- handle->linktype = linktype;
+ handle->pattern = pattern;
handle->dissector = dissector;
handle->protocol = find_protocol_by_id(proto);
- g_hash_table_insert(registered_capture_dissectors, GUINT_TO_POINTER(linktype), (gpointer) handle);
+ g_hash_table_insert(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern), (gpointer) handle);
}
-void call_capture_dissector(gint linktype, const guchar *pd, int offset, int len, packet_counts *ld, const union wtap_pseudo_header *pseudo_header)
+gboolean try_capture_dissector(const char* name, const guint32 pattern, const guchar *pd, int offset, int len, packet_counts *ld, const union wtap_pseudo_header *pseudo_header)
{
- struct capture_dissector_handle* handle = (struct capture_dissector_handle *)g_hash_table_lookup(registered_capture_dissectors, GUINT_TO_POINTER(linktype));
+ struct capture_dissector_table* sub_dissectors;
+ struct capture_dissector_handle* handle;
+
+ sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name );
+ if (sub_dissectors == NULL)
+ {
+ /* XXX - ASSERT? */
+ return FALSE;
+ }
+
+ handle = (struct capture_dissector_handle *)g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern));
if (handle == NULL)
- return;
+ return FALSE;
- handle->dissector(pd, offset, len, ld, pseudo_header);
+ return handle->dissector(pd, offset, len, ld, pseudo_header);
}
/*