diff options
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); } /* |