diff options
author | Michael Mann <mmann78@netscape.net> | 2015-12-13 16:54:16 -0500 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2015-12-14 12:17:49 +0000 |
commit | 0960ac4dfdbfba5a81c56a49cfc6201ecd8f48e3 (patch) | |
tree | 3d88cd321da2fade206b9ccddff22b70ecdfae28 /epan/capture_dissectors.c | |
parent | 9319357f5e27c10f2d29e78fcdf9d323c2af36b0 (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.c | 71 |
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); } /* |