Wireshark-dev: [Wireshark-dev] [PATCH] Dissector hooks: Small and Simple additions
From: Shehjar Tikoo <shehjart@xxxxxxxxxxxxxxx>
Date: Thu, 22 Feb 2007 13:53:29 +1100
Hi all

Please see the attached diff for the changes I made to revision 20887 from the repository.

It brings in the dissector hooks feature discussed here a few weeks back. Its a small patch that includes basic infra for hooks and a sample hook for the NFS dissector.

Right now, the hook gets called(..using call_dissector_hooks()..) only for NFSv3 setattr call/reply but the intention is to call them in every message dissector function.

For NFS, the hooks could be called for each message(..as in this patch..), though this could be different, for eg. hooks could've been called for each field in the messages.

I'd appreciate feedback to improve this functionality and patch.

Thanks
Shehjar
 Makefile.common         |    2 ++
 dissectors/packet-nfs.c |   25 +++++++++++++++++++++++++
 hooks.c                 |   43 +++++++++++++++++++++++++++++++++++++++++++
 hooks.h                 |   26 ++++++++++++++++++++++++++
 4 files changed, 96 insertions(+)
Index: epan/hooks.c
===================================================================
--- epan/hooks.c	(revision 0)
+++ epan/hooks.c	(revision 0)
@@ -0,0 +1,43 @@
+#include "hooks.h"
+
+/* A generic function that is passed to the list_foreach
+ * Can be over-ridden by dissectors
+ */
+GFunc generic_hooks_caller(gpointer data, gpointer userdata)
+{
+	dissector_hook hook = (dissector_hook)data;
+	struct dissector_hooks_userdata *udata = (struct dissector_hooks_userdata *)userdata;
+
+	if((hook) && (udata))
+		hook(udata);
+}
+
+/* Call this function to run the hooks 
+ *
+ * hooks_list: List containing function pointers. The function
+ * pointers are the hooks.
+ *
+ * hooks_caller: A function that actually calls each hook function.
+ * Generally, give NULL here, unless something special needs to be
+ * done before the hook is called.
+ *
+ * priv: Any private or hook/protocol/dissector -specfic data that
+ * needs to be passed.
+ */
+void
+call_dissector_hooks(GSList *hooks_list, GFunc hooks_caller, tvbuff_t *tvb, 
+		int offset, packet_info *pinfo, void *priv)
+{
+	struct dissector_hook_userdata data;
+	
+	data.tvb = tvb;
+	data.offset = offset;
+	data.pinfo = pinfo;
+	data.priv = priv;
+
+	/* Use the generic function, if none provided */
+	if(hooks_caller == NULL)
+		hooks_caller = generic_hooks_caller;
+
+	g_slist_foreach(hooks_list, hooks_caller, (gpointer)&data);
+}
Index: epan/hooks.h
===================================================================
--- epan/hooks.h	(revision 0)
+++ epan/hooks.h	(revision 0)
@@ -0,0 +1,26 @@
+#ifndef __HOOKS_H__
+#define __HOOKS_H__
+
+#include <glib.h>
+#include "tvbuff.h"
+#include "packet_info.h"
+
+
+/* The args to the hook function are packed into this
+ */
+struct dissector_hook_userdata {
+	tvbuff_t *tvb;
+	int offset;
+	packet_info *pinfo;
+	void *priv;
+};
+
+/* Hook function should be of this type */
+typedef void (*dissector_hook)(struct dissector_hook_userdata *data);
+
+GFunc generic_hooks_caller(gpointer data, gpointer userdata);
+
+void call_dissector_hooks(GSList *hooks_list, GFunc hooks_caller, tvbuff_t *tvb,
+		int offset, packet_info *pinfo, void *priv);
+
+#endif
Index: epan/Makefile.common
===================================================================
--- epan/Makefile.common	(revision 20887)
+++ epan/Makefile.common	(working copy)
@@ -54,6 +54,7 @@
 	funnel.c    \
 	guid-utils.c    \
 	h225-persistentdata.c	\
+	hooks.c			\
 	in_cksum.c		\
 	ipproto.c		\
 	ipv4.c			\
@@ -138,6 +139,7 @@
 	greproto.h		\
 	guid-utils.h		\
 	h225-persistentdata.h	\
+	hooks.h			\
 	iax2_codec_type.h	\
 	in_cksum.h		\
 	ip_opts.h		\
Index: epan/dissectors/packet-nfs.c
===================================================================
--- epan/dissectors/packet-nfs.c	(revision 20887)
+++ epan/dissectors/packet-nfs.c	(working copy)
@@ -39,6 +39,7 @@
 #include <epan/prefs.h>
 #include <epan/packet.h>
 #include <epan/emem.h>
+#include <epan/hooks.h>
 
 static int proto_nfs = -1;
 
@@ -532,6 +533,8 @@
 static emem_tree_t *nfs_name_snoop_known = NULL;
 static emem_tree_t *nfs_file_handles = NULL;
 
+static GSList *nfs_dissector_hooks = NULL;
+
 /* This function will store one nfs filehandle in our global tree of
  * filehandles.
  * We store all filehandles we see in this tree so that every unique
@@ -893,6 +896,25 @@
 	}
 }
 
+
+/*  A useless test hook */
+dissector_hook nfs_donothing_hook(struct dissector_hook_userdata *data)
+{
+	fprintf(stderr, "\n NFS HOOK\n");
+	/* Do whatever processing required for a hook in such a
+	 * function, but do insert in the dissector hooks list
+	 */
+	return;
+}
+
+/* Add list append calls here to add more dissector hooks */
+static void
+nfs_register_dissector_hooks()
+{
+	nfs_dissector_hooks = g_slist_append(nfs_dissector_hooks, nfs_donothing_hook);
+}
+
+
 /* file handle dissection */
 
 static const value_string names_fhtype[] =
@@ -4259,6 +4281,7 @@
 {
 	guint32 hash;
 
+	call_dissector_hooks(nfs_dissector_hooks, NULL, tvb, offset, pinfo, NULL);
 	offset = dissect_nfs_fh3    (tvb, offset, pinfo, tree, "object", &hash);
 	offset = dissect_sattr3     (tvb, offset,        tree, "new_attributes");
 	offset = dissect_sattrguard3(tvb, offset,        tree, "guard");
@@ -4280,6 +4303,7 @@
 	guint32 status;
 	const char *err;
 
+	call_dissector_hooks(nfs_dissector_hooks, NULL, tvb, offset, pinfo, NULL);
 	offset = dissect_nfsstat3(tvb, offset, tree, &status);
 	switch (status) {
 		case 0:
@@ -9326,6 +9350,7 @@
 	nfs_file_handles=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "nfs_file_handles");
 	nfs_fhandle_frame_table=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "nfs_fhandle_frame_table");
 	register_init_routine(nfs_name_snoop_init);
+	register_init_routine(nfs_register_dissector_hooks);
 
 }