Add an API to let a postdissector specify fields whose values it needs.
[metze/wireshark/wip.git] / epan / packet.c
index de0a84854ae3b3e9e06abec59bc990375fc59b12..4a3b5cbd6434fba6b633b8e1d11f8a02f89e42af 100644 (file)
@@ -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
  *