Use correct prototypes when having no arguments.
[metze/wireshark/wip.git] / epan / wspython / wspy_register.c
1 /* wspy_register.c
2  *
3  * $Id$
4  *
5  * Wireshark Protocol Python Binding
6  *
7  * Copyright (c) 2009 by Sebastien Tandel <sebastien [AT] tandel [dot] be>
8  * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #ifdef HAVE_PYTHON
30 #include <Python.h>
31
32 #include <glib.h>
33
34 #include <stdio.h>
35
36 #include "epan.h"
37 #include "proto.h"
38 #include "packet.h"
39 #include "tvbuff.h"
40 #include "filesystem.h"
41
42 #include "wspy_register.h"
43
44 /* hash table containing all the registered python dissectors */
45 GHashTable * g_py_dissectors=NULL;
46
47 /**
48  * Global objects that python method dissect() will get. Avoid to write a
49  * function for each proto_tree*.
50  * Is it the only way to do that? I can't believe it ... think about it
51  */
52 tvbuff_t * g_tvb = NULL;
53 packet_info * g_pinfo = NULL;
54 proto_tree * g_tree = NULL;
55
56
57 /* Initialization of the Python Interpreter */
58 static inline
59 void wspy_init(void)
60 {
61   Py_Initialize();
62 }
63
64 /* Finalization of the Python Interpreter */
65 static inline
66 void wspy_finalize(void)
67 {
68   Py_Finalize();
69 }
70
71 /*const char * py_dissector_short_desc(PyObject * py_dissector)
72 {
73 }*/
74
75 /**
76  * Returns the __str__ of the python object
77  */
78 char * py_dissector_name(PyObject * py_dissector)
79 {
80   PyObject * py_object_name;
81
82   assert(py_dissector);
83   py_object_name = PyObject_Str(py_dissector);
84
85   return PyString_AS_STRING(py_object_name);
86 }
87
88 /**
89  * Register the dissector
90  */
91 void py_dissector_register(PyObject * py_dissector, char * py_name, register_cb cb, gpointer client_data)
92 {
93 /*  const char * py_name; */
94
95   /* Get the name of the dissector */
96 /*  py_name = py_dissector_name(py_dissector); */
97
98   /* Register dissector in register_cb */
99   if (cb)
100     (*cb)(RA_REGISTER, py_name, client_data);
101
102   /**
103    * Register protocol, fields, subtrees
104    *
105    * Done by calling register method of the object
106    */
107   PyObject_CallMethod(py_dissector, "register_protocol", NULL);
108
109 }
110
111 static const char *get_py_register_file(void)
112 {
113   static const char * wspython_register_file = NULL;
114
115   if (!wspython_register_file) {
116 #ifdef _WIN32
117       wspython_register_file = g_strdup_printf("%s\\register-dissector.py", get_wspython_dir());
118 #else
119       wspython_register_file = g_strdup_printf("%s/register-dissector.py", get_wspython_dir());
120 #endif /* _WIN32 */
121   }
122   return wspython_register_file;
123 }
124
125 /**
126  * Finds out all the python dissectors and register them
127  */
128 void register_all_py_protocols_func(register_cb cb, gpointer client_data)
129 {
130   FILE * py_reg;
131   PyObject * global_dict, * main_module, * register_fn;
132   PyObject * py_dissectors, * py_dissector;
133   PyObject * py_args;
134   Py_ssize_t index;
135   void * nothing;
136   char * name;
137   nothing = cb;
138   nothing = client_data;
139
140   /* intialize the hash table where all the python dissectors are kept */
141   g_py_dissectors = g_hash_table_new(g_str_hash, g_str_equal);
142
143   /* STA TODO : init only if prefs is enabled */
144   wspy_init();
145
146   /* load the python register module */
147   py_reg = fopen(get_py_register_file(), "r");
148   if (py_reg == NULL) {
149     printf("no register file %s\n", get_py_register_file());
150     return;
151   }
152   PyRun_SimpleFile(py_reg, get_py_register_file());
153
154   /* Getting the global symbols from the python register module */
155   main_module = PyImport_AddModule("__main__");
156   global_dict = PyModule_GetDict(main_module);
157
158   /* Get the python register function */
159   register_fn = PyDict_GetItemString(global_dict, "register_dissectors");
160
161   /* Execute the python register function */
162   /* This function returns a sequence of python dissectors objects */
163   py_args = Py_BuildValue("(s)", get_wspython_dir());
164   py_dissectors = PyObject_CallObject(register_fn, py_args);
165
166   /* Check that the py_dissectors is really a sequence */
167   if (!PySequence_Check(py_dissectors)) {
168     printf("not registered ...\n");
169     return;
170   }
171
172   /**
173    * For each dissector, register it in cb and registers all fields, subtrees,
174    * protocol name, etc ...
175    */
176   for (index = 0; (py_dissector = PySequence_GetItem(py_dissectors, index)); index++)
177   {
178     name = py_dissector_name(py_dissector);
179     py_dissector_register(py_dissector, name, cb, client_data);
180     g_hash_table_insert(g_py_dissectors, (gpointer*)name, py_dissector);
181   }
182 }
183
184 tvbuff_t *py_tvbuff(void)
185 {
186   return g_tvb;
187 }
188
189 packet_info * py_pinfo(void)
190 {
191   return g_pinfo;
192 }
193
194 proto_tree * py_tree(void)
195 {
196   return g_tree;
197 }
198
199 /*
200  * Generic Python Dissector
201  *
202  * Search the correct PyObject dissector based on
203  * pinfo->current_proto in the hash table py_dissectors.
204  *
205  * We then call the method "dissect" of this PyObject.
206  */
207 void py_dissect(tvbuff_t * tvb, packet_info * pinfo,
208     proto_tree * tree)
209 {
210   PyObject * py_dissector;
211
212   /* printf("pinfo->current_proto : %s\n", pinfo->current_proto); */
213   /* NOTE => pinfo->current_proto == "HomePlug" */
214
215   g_tree = tree;
216   g_pinfo = pinfo;
217   g_tvb = tvb;
218
219   py_dissector = g_hash_table_lookup(g_py_dissectors, pinfo->current_proto);
220   assert(py_dissector);
221
222   PyObject_CallMethod(py_dissector, "pre_dissect", NULL);
223 }
224
225 /*
226  * Return the pointer to the generic python dissector
227  *
228  * One could think that it could be a PyCObject but it is a
229  * workaround because ctypes is used and it complains later -not
230  * knowing how to conver the parameter - in the Python code when
231  * calling back a C function with a PyCObject as parameter
232  */
233 dissector_t py_generic_dissector(void)
234 {
235   return py_dissect;
236 }
237
238 struct SRegisterHandoffsForeach {
239   register_cb cb;
240   gpointer client_data;
241 };
242
243 static void register_all_py_handoffs_foreach(gpointer key _U_, gpointer value, gpointer user_data)
244 {
245   PyObject * py_dissector = (PyObject *)value;
246   struct SRegisterHandoffsForeach *rhf = (struct SRegisterHandoffsForeach*)user_data;
247
248   /* STA TODO : it's the short_desc field ... not really the filter field! */
249   char * handoff_name = g_strdup_printf("handoff_%s", py_dissector_name(py_dissector));
250
251   if (rhf->cb)
252     (*(rhf->cb))(RA_HANDOFF, handoff_name, rhf->client_data);
253
254   PyObject_CallMethod(py_dissector, "register_handoff", NULL);
255 }
256
257 /**
258  * Finalize the registration of the python protocol dissectors
259  */
260 void
261 register_all_py_handoffs_func(register_cb cb, gpointer client_data)
262 {
263   struct SRegisterHandoffsForeach rhf;
264
265   rhf.cb = cb;
266   rhf.client_data = client_data;
267
268   g_hash_table_foreach(g_py_dissectors, register_all_py_handoffs_foreach, &rhf);
269 }
270
271 #endif /* HAVE_PYTHON */