Add new dissector callback signature with data pointer
authorJoão Valverde <joao.valverde@tecnico.ulisboa.pt>
Sun, 27 Aug 2017 19:53:23 +0000 (20:53 +0100)
committerJoão Valverde <j@v6e.pt>
Thu, 14 Dec 2017 22:12:47 +0000 (22:12 +0000)
This is useful to implement language bindings (Lua, Python, etc) and
good practice in general.

Non-breaking change to the API.

Change-Id: I8d16c14880e5aa53212af8418c468a6ec3aa8954
Reviewed-on: https://code.wireshark.org/review/24814
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot
Reviewed-by: João Valverde <j@v6e.pt>
epan/packet.c
epan/packet.h

index 7895610b5abfe09cbeea269926b4d3861158033b..7c9bb1ece5743d938bb369826087a55d2b45d04f 100644 (file)
@@ -649,12 +649,19 @@ dissect_file(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
 
 /*********************** code added for sub-dissector lookup *********************/
 
+enum dissector_e {
+       DISSECTOR_TYPE_SIMPLE,
+       DISSECTOR_TYPE_CALLBACK
+};
+
 /*
  * A dissector handle.
  */
 struct dissector_handle {
        const char      *name;          /* dissector name */
-       dissector_t     dissector;
+       enum dissector_e dissector_type;
+       void            *dissector_func;
+       void            *dissector_data;
        protocol_t      *protocol;
 };
 
@@ -682,7 +689,15 @@ call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
                        proto_get_protocol_short_name(handle->protocol);
        }
 
-       len = (*handle->dissector)(tvb, pinfo, tree, data);
+       if (handle->dissector_type == DISSECTOR_TYPE_SIMPLE) {
+               len = ((dissector_t)handle->dissector_func)(tvb, pinfo, tree, data);
+       }
+       else if (handle->dissector_type == DISSECTOR_TYPE_CALLBACK) {
+               len = ((dissector_cb_t)handle->dissector_func)(tvb, pinfo, tree, data, handle->dissector_data);
+       }
+       else {
+               g_assert_not_reached();
+       }
        pinfo->current_proto = saved_proto;
 
        return len;
@@ -2945,13 +2960,15 @@ dissector_handle_get_dissector_name(const dissector_handle_t handle)
 }
 
 static dissector_handle_t
-new_dissector_handle(dissector_t dissector, int proto, const char *name)
+new_dissector_handle(enum dissector_e type, void *dissector, const int proto, const char *name, void *cb_data)
 {
        struct dissector_handle *handle;
 
        handle                  = wmem_new(wmem_epan_scope(), struct dissector_handle);
        handle->name            = name;
-       handle->dissector       = dissector;
+       handle->dissector_type  = type;
+       handle->dissector_func  = dissector;
+       handle->dissector_data  = cb_data;
        handle->protocol        = find_protocol_by_id(proto);
        return handle;
 }
@@ -2960,14 +2977,14 @@ new_dissector_handle(dissector_t dissector, int proto, const char *name)
 dissector_handle_t
 create_dissector_handle(dissector_t dissector, const int proto)
 {
-       return new_dissector_handle(dissector, proto, NULL);
+       return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, NULL, NULL);
 }
 
 dissector_handle_t
 create_dissector_handle_with_name(dissector_t dissector,
                                const int proto, const char* name)
 {
-       return new_dissector_handle(dissector, proto, name);
+       return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
 }
 
 /* Destroy an anonymous handle for a dissector. */
@@ -2998,7 +3015,17 @@ register_dissector(const char *name, dissector_t dissector, const int proto)
 {
        struct dissector_handle *handle;
 
-       handle = new_dissector_handle(dissector, proto, name);
+       handle = new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
+
+       return register_dissector_handle(name, handle);
+}
+
+dissector_handle_t
+register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data)
+{
+       struct dissector_handle *handle;
+
+       handle = new_dissector_handle(DISSECTOR_TYPE_CALLBACK, dissector, proto, name, cb_data);
 
        return register_dissector_handle(name, handle);
 }
index ffe23285a4db520765be81434508db1515d27ef5..67ed2471b52c3c8960e4c0cd1eabc402fbb0acee 100644 (file)
@@ -86,6 +86,9 @@ typedef struct dissector_table *dissector_table_t;
  */
 typedef int (*dissector_t)(tvbuff_t *, packet_info *, proto_tree *, void *);
 
+/* Same as dissector_t with an extra parameter for callback pointer */
+typedef int (*dissector_cb_t)(tvbuff_t *, packet_info *, proto_tree *, void *, void *);
+
 /** Type of a heuristic dissector, used in heur_dissector_add().
  *
  * @param tvb the tvbuff with the (remaining) packet data
@@ -522,6 +525,9 @@ WS_DLL_PUBLIC void heur_dissector_delete(const char *name, heur_dissector_t diss
 /** Register a new dissector. */
 WS_DLL_PUBLIC dissector_handle_t register_dissector(const char *name, dissector_t dissector, const int proto);
 
+/** Register a new dissector with a callback pointer. */
+WS_DLL_PUBLIC dissector_handle_t register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data);
+
 /** Deregister a dissector. */
 void deregister_dissector(const char *name);