aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wspython/wspy_register.c
diff options
context:
space:
mode:
authorSebastien Tandel <sebastien@tandel.be>2009-05-29 21:10:40 +0000
committerSebastien Tandel <sebastien@tandel.be>2009-05-29 21:10:40 +0000
commit52cc5fb1e86ac8007eabe1291bf543d3803f7148 (patch)
tree0ee2757e438e9d9db9dd0ddab19f0e84f3f29f03 /epan/wspython/wspy_register.c
parentcb4f0a40c23a3247fbb74a74dc117cbef4f83bf4 (diff)
python binding for wireshark (first commit)
* ability to write dissectors with python for wireshark. documentation (http://wiki.wireshark.org/Python) svn path=/trunk/; revision=28529
Diffstat (limited to 'epan/wspython/wspy_register.c')
-rw-r--r--epan/wspython/wspy_register.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/epan/wspython/wspy_register.c b/epan/wspython/wspy_register.c
new file mode 100644
index 0000000000..a6a9b0701b
--- /dev/null
+++ b/epan/wspython/wspy_register.c
@@ -0,0 +1,270 @@
+/* wspy_register.c
+ *
+ * $Id: $
+ *
+ * Wireshark Protocol Python Binding
+ *
+ * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
+ * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_PYTHON
+#include <Python.h>
+
+#include <glib.h>
+
+#include <stdio.h>
+
+#include "epan.h"
+#include "proto.h"
+#include "packet.h"
+#include "tvbuff.h"
+#include "filesystem.h"
+
+/* hash table containing all the registered python dissectors */
+GHashTable * g_py_dissectors=NULL;
+
+/**
+ * Global objects that python method dissect() will get. Avoid to write a
+ * function for each proto_tree*.
+ * Is it the only way to do that? I can't believe it ... think about it
+ */
+tvbuff_t * g_tvb = NULL;
+packet_info * g_pinfo = NULL;
+proto_tree * g_tree = NULL;
+
+
+/* Initialization of the Python Interpreter */
+inline
+void wspy_init()
+{
+ Py_Initialize();
+}
+
+/* Finalization of the Python Interpreter */
+inline
+void wspy_finalize()
+{
+ Py_Finalize();
+}
+
+/*const char * py_dissector_short_desc(PyObject * py_dissector)
+{
+}*/
+
+/**
+ * Returns the __str__ of the python object
+ */
+char * py_dissector_name(PyObject * py_dissector)
+{
+ PyObject * py_object_name;
+
+ assert(py_dissector);
+ py_object_name = PyObject_Str(py_dissector);
+
+ return PyString_AS_STRING(py_object_name);
+}
+
+/**
+ * Register the dissector
+ */
+void py_dissector_register(PyObject * py_dissector, char * py_name, register_cb cb, gpointer client_data)
+{
+// const char * py_name;
+
+ /* Get the name of the dissector */
+// py_name = py_dissector_name(py_dissector);
+
+ /* Register dissector in register_cb */
+ if (cb)
+ (*cb)(RA_REGISTER, py_name, client_data);
+
+ /**
+ * Register protocol, fields, subtrees
+ *
+ * Done by calling register method of the object
+ */
+ PyObject_CallMethod(py_dissector, "register_protocol", NULL);
+
+}
+
+const char *get_py_register_file()
+{
+ static const char * wspython_register_file = NULL;
+
+ if (!wspython_register_file) {
+#ifdef _WIN32
+ wspython_register_file = g_strdup_printf("%s\\register-dissector.py", get_wspython_dir());
+#else
+ wspython_register_file = g_strdup_printf("%s/register-dissector.py", get_wspython_dir());
+#endif /* _WIN32 */
+ }
+ return wspython_register_file;
+}
+
+/**
+ * Finds out all the python dissectors and register them
+ */
+void register_all_py_protocols_func(register_cb cb, gpointer client_data)
+{
+ FILE * py_reg;
+ PyObject * global_dict, * main_module, * register_fn;
+ PyObject * py_dissectors, * py_dissector;
+ PyObject * py_args;
+ Py_ssize_t index;
+ void * nothing;
+ char * name;
+ nothing = cb;
+ nothing = client_data;
+
+ /* STA TODO : init only if prefs is enabled */
+ wspy_init();
+
+ /* load the python register module */
+ py_reg = fopen(get_py_register_file(), "r");
+ PyRun_SimpleFile(py_reg, get_py_register_file());
+
+ /* Getting the global symbols from the python register module */
+ main_module = PyImport_AddModule("__main__");
+ global_dict = PyModule_GetDict(main_module);
+
+ /* Get the python register function */
+ register_fn = PyDict_GetItemString(global_dict, "register_dissectors");
+
+ /* Execute the python register function */
+ /* This function returns a sequence of python dissectors objects */
+ py_args = Py_BuildValue("(s)", get_wspython_dir());
+ py_dissectors = PyObject_CallObject(register_fn, py_args);
+ //py_dissectors = PyObject_CallObject(register_fn, NULL);
+
+ /* Check that the py_dissectors is really a sequence */
+ if (!PySequence_Check(py_dissectors)) {
+ printf("not registered ...\n");
+ return;
+ }
+
+ /* intialize the hash table where all the python dissectors are kept */
+ g_py_dissectors = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /**
+ * For each dissector, register it in cb and registers all fields, subtrees,
+ * protocol name, etc ...
+ */
+ for (index = 0; ; index++) {
+ py_dissector = PySequence_GetItem(py_dissectors, index);
+ if (!py_dissector)
+ break;
+ assert(py_dissector);
+
+ name = py_dissector_name(py_dissector);
+ py_dissector_register(py_dissector, name, cb, client_data);
+ g_hash_table_insert(g_py_dissectors, (gpointer*)name, py_dissector);
+ }
+}
+
+tvbuff_t *py_tvbuff()
+{
+ return g_tvb;
+}
+
+packet_info * py_pinfo()
+{
+ return g_pinfo;
+}
+
+proto_tree * py_tree()
+{
+ return g_tree;
+}
+
+/*
+ * Generic Python Dissector
+ *
+ * Search the correct PyObject dissector based on
+ * pinfo->current_proto in the hash table py_dissectors.
+ *
+ * We then call the method "dissect" of this PyObject.
+ */
+void py_dissect(tvbuff_t * tvb, packet_info * pinfo,
+ proto_tree * tree)
+{
+ PyObject * py_dissector;
+
+ //printf("pinfo->current_proto : %s\n", pinfo->current_proto);
+ //NOTE => pinfo->current_proto == "HomePlug"
+
+ g_tree = tree;
+ g_pinfo = pinfo;
+ g_tvb = tvb;
+
+ py_dissector = g_hash_table_lookup(g_py_dissectors, pinfo->current_proto);
+ assert(py_dissector);
+
+ PyObject_CallMethod(py_dissector, "pre_dissect", NULL);
+}
+
+/*
+ * Return the pointer to the generic python dissector
+ *
+ * One could think that it could be a PyCObject but it is a
+ * workaround because ctypes is used and it complains later -not
+ * knowing how to conver the parameter - in the Python code when
+ * calling back a C function with a PyCObject as parameter
+ */
+dissector_t py_generic_dissector()
+{
+ return py_dissect;
+}
+
+struct SRegisterHandoffsForeach {
+ register_cb cb;
+ gpointer client_data;
+};
+
+void register_all_py_handoffs_foreach(gpointer key _U_, gpointer value, gpointer user_data)
+{
+ PyObject * py_dissector = (PyObject *)value;
+ struct SRegisterHandoffsForeach *rhf = (struct SRegisterHandoffsForeach*)user_data;
+
+ /* STA TODO : it's the short_desc field ... not really the filter field! */
+ char * handoff_name = g_strdup_printf("handoff_%s", py_dissector_name(py_dissector));
+
+ if (rhf->cb)
+ (*(rhf->cb))(RA_HANDOFF, handoff_name, rhf->client_data);
+
+ PyObject_CallMethod(py_dissector, "register_handoff", NULL);
+}
+
+/**
+ * Finalize the registration of the python protocol dissectors
+ */
+void
+register_all_py_handoffs_func(register_cb cb, gpointer client_data)
+{
+ struct SRegisterHandoffsForeach rhf;
+
+ rhf.cb = cb;
+ rhf.client_data = client_data;
+
+ g_hash_table_foreach(g_py_dissectors, register_all_py_handoffs_foreach, &rhf);
+}
+
+#endif /* HAVE_PYTHON */