aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
Diffstat (limited to 'epan')
-rw-r--r--epan/packet.c84
-rw-r--r--epan/packet.h39
-rw-r--r--epan/wslua/wslua_proto.c10
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);
}