diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/packet.c | 84 | ||||
-rw-r--r-- | epan/packet.h | 39 | ||||
-rw-r--r-- | epan/wslua/wslua_proto.c | 10 |
3 files changed, 115 insertions, 18 deletions
diff --git a/epan/packet.c b/epan/packet.c index de0a84854a..4a3b5cbd64 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -127,8 +127,24 @@ static GHashTable *depend_dissector_lists = NULL; * the final cleanup. */ static GSList *postseq_cleanup_routines; -static GPtrArray* post_dissectors = NULL; -static guint num_of_postdissectors = 0; +/* + * Post-dissector information - handle for the dissector and a list + * of hfids for the fields the post-dissector wants. + */ +typedef struct { + dissector_handle_t handle; + GArray *wanted_fields; +} postdissector; + +/* + * Array of all postdissectors. + */ +static GArray *postdissectors = NULL; + +/* + * i-th element of that array. + */ +#define POSTDISSECTORS(i) g_array_index(postdissectors, postdissector, i) static void destroy_depend_dissector_list(void *data) @@ -248,8 +264,8 @@ packet_cleanup(void) g_hash_table_destroy(heuristic_short_names); g_slist_foreach(shutdown_routines, &call_routine, NULL); g_slist_free(shutdown_routines); - if (post_dissectors) - g_ptr_array_free(post_dissectors, TRUE); + if (postdissectors) + g_array_free(postdissectors, TRUE); } /* @@ -3252,20 +3268,43 @@ dissector_dump_dissector_tables(void) void register_postdissector(dissector_handle_t handle) { - if (!post_dissectors) - post_dissectors = g_ptr_array_new(); + postdissector p; - g_ptr_array_add(post_dissectors, handle); - num_of_postdissectors++; + if (!postdissectors) + postdissectors = g_array_sized_new(FALSE, FALSE, (guint)sizeof(postdissector), 1); + + p.handle = handle; + p.wanted_fields = NULL; + postdissectors = g_array_append_val(postdissectors, p); +} + +void +set_postdissector_wanted_fields(dissector_handle_t handle, GArray *wanted_fields) +{ + guint i; + + if (!postdissectors) return; + + for (i = 0; i < postdissectors->len; i++) { + if (POSTDISSECTORS(i).handle == handle) { + POSTDISSECTORS(i).wanted_fields = wanted_fields; + break; + } + } } void deregister_postdissector(dissector_handle_t handle) { - if (!post_dissectors) return; + guint i; + + if (!postdissectors) return; - if (g_ptr_array_remove(post_dissectors, handle)) { - num_of_postdissectors--; + for (i = 0; i < postdissectors->len; i++) { + if (POSTDISSECTORS(i).handle == handle) { + postdissectors = g_array_remove_index_fast(postdissectors, i); + break; + } } } @@ -3275,8 +3314,8 @@ have_postdissector(void) guint i; dissector_handle_t handle; - for(i = 0; i < num_of_postdissectors; i++) { - handle = (dissector_handle_t) g_ptr_array_index(post_dissectors,i); + for (i = 0; i < postdissectors->len; i++) { + handle = POSTDISSECTORS(i).handle; if (handle->protocol != NULL && proto_is_protocol_enabled(handle->protocol)) { @@ -3292,12 +3331,25 @@ call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint i; - for(i = 0; i < num_of_postdissectors; i++) { - call_dissector_only((dissector_handle_t) g_ptr_array_index(post_dissectors,i), - tvb,pinfo,tree, NULL); + for (i = 0; i < postdissectors->len; i++) { + call_dissector_only(POSTDISSECTORS(i).handle, + tvb, pinfo, tree, NULL); } } +gboolean +postdissectors_want_fields(void) +{ + guint i; + + for (i = 0; i < postdissectors->len; i++) { + if (POSTDISSECTORS(i).wanted_fields != NULL && + POSTDISSECTORS(i).wanted_fields->len != 0) + return TRUE; + } + return FALSE; +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/epan/packet.h b/epan/packet.h index 9d4efaf02d..47eed6fe33 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -765,15 +765,50 @@ WS_DLL_PUBLIC void dissector_dump_decodes(void); WS_DLL_PUBLIC void dissector_dump_heur_decodes(void); /* - * post dissectors are to be called by packet-frame.c after every other + * postdissectors are to be called by packet-frame.c after every other * dissector has been called. */ -WS_DLL_PUBLIC void register_postdissector(dissector_handle_t); + +/* + * Register a postdissector; the argument is the dissector handle for it. + */ +WS_DLL_PUBLIC void register_postdissector(dissector_handle_t handle); + +/* + * Specify a set of fields that the postdissector will need. + * The GArray is an array of hfids. + */ +WS_DLL_PUBLIC void set_postdissector_wanted_fields(dissector_handle_t handle, + GArray *wanted_fields); + +/* + * Deregister a postdissector. Not for use in (post)dissectors or + * applications; only to be used by libwireshark itself. + */ void deregister_postdissector(dissector_handle_t handle); +/* + * Return TRUE if we have at least one postdissector, FALSE if not. + * Not for use in (post)dissectors or applications; only to be used + * by libwireshark itself. + */ extern gboolean have_postdissector(void); + +/* + * Call all postdissectors, handing them the supplied arguments. + * Not for use in (post)dissectors or applications; only to be used + * by libwireshark itself. + */ extern void call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +/* + * Return TRUE if at least one postdissector wants fields, FALSE otherwise. + * XXX - at some point this should return a bag of all fields requested by + * all postdissectors, so we can prime the epan_dissect_t with them rather + * than constructing a bogus tap with a bogus filter. + */ +WS_DLL_PUBLIC gboolean postdissectors_want_fields(void); + /** @} */ #ifdef __cplusplus diff --git a/epan/wslua/wslua_proto.c b/epan/wslua/wslua_proto.c index acbdb67e76..b8e2cc41a1 100644 --- a/epan/wslua/wslua_proto.c +++ b/epan/wslua/wslua_proto.c @@ -203,6 +203,16 @@ WSLUA_FUNCTION wslua_register_postdissector(lua_State* L) { } if (all_fields) { + /* + * XXX - are there any Lua postdissectors that need "all fields", + * i.e. the entire protocol tree, or do they just look for + * *particular* fields, with field extractors? + * + * And do all of them require the actual *displayed* format of + * the fields they need? + * + * If not, this is overkill. + */ epan_set_always_visible(TRUE); } |