Update Free Software Foundation address.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
92 {
93   /**
94    * Register protocol, fields, subtrees
95    *
96    * Done by calling register method of the object
97    */
98   PyObject_CallMethod(py_dissector, "register_protocol", NULL);
99
100 }
101
102 static const char *get_py_register_file(void)
103 {
104   static const char * wspython_register_file = NULL;
105
106   if (!wspython_register_file) {
107 #ifdef _WIN32
108       wspython_register_file = g_strdup_printf("%s\\register-dissector.py", get_wspython_dir());
109 #else
110       wspython_register_file = g_strdup_printf("%s/register-dissector.py", get_wspython_dir());
111 #endif /* _WIN32 */
112   }
113   return wspython_register_file;
114 }
115
116 /**
117  * Finds out all the python dissectors and register them
118  */
119 void register_all_py_protocols_func(void)
120 {
121   FILE * py_reg;
122   PyObject * global_dict, * main_module, * register_fn;
123   PyObject * py_dissectors, * py_dissector;
124   PyObject * py_args;
125   Py_ssize_t index;
126   char * name;
127
128   /* intialize the hash table where all the python dissectors are kept */
129   g_py_dissectors = g_hash_table_new(g_str_hash, g_str_equal);
130
131   /* STA TODO : init only if prefs is enabled */
132   wspy_init();
133
134   /* load the python register module */
135   py_reg = fopen(get_py_register_file(), "r");
136   if (py_reg == NULL) {
137     printf("Can't open Python registration file: %s\n", get_py_register_file());
138     return;
139   }
140   PyRun_SimpleFile(py_reg, get_py_register_file());
141
142   /* Getting the global symbols from the python register module */
143   main_module = PyImport_AddModule("__main__");
144   global_dict = PyModule_GetDict(main_module);
145
146   /* Get the python register function */
147   register_fn = PyDict_GetItemString(global_dict, "register_dissectors");
148   if (register_fn == NULL) {
149     printf("Error in Python registration file: %s\n", get_py_register_file());
150     return;
151   }
152
153   /* Execute the python register function */
154   /* This function returns a sequence of python dissectors objects */
155   py_args = Py_BuildValue("ss",  get_wspython_dir(), get_plugins_pers_dir());
156   py_dissectors = PyObject_CallObject(register_fn, py_args);
157
158   /* Check that the py_dissectors is really a sequence */
159   if (!py_dissectors || !PySequence_Check(py_dissectors)) {
160     printf("Python dissectors not registered ...\n");
161     return;
162   }
163
164   /**
165    * For each dissector, register it in cb and registers all fields, subtrees,
166    * protocol name, etc ...
167    */
168   for (index = 0; (py_dissector = PySequence_GetItem(py_dissectors, index)); index++)
169   {
170     name = py_dissector_name(py_dissector);
171     py_dissector_register(py_dissector);
172     g_hash_table_insert(g_py_dissectors, (gpointer*)name, py_dissector);
173   }
174 }
175
176 void py_dissector_args(tvbuff_t ** tvb, packet_info ** pinfo, proto_tree ** tree)
177 {
178         *tvb = g_tvb;
179         *pinfo = g_pinfo;
180         *tree = g_tree;
181 }
182
183 /*
184  * Generic Python Dissector
185  *
186  * Search the correct PyObject dissector based on
187  * pinfo->current_proto in the hash table py_dissectors.
188  *
189  * We then call the method "dissect" of this PyObject.
190  */
191 void py_dissect(tvbuff_t * tvb, packet_info * pinfo,
192     proto_tree * tree)
193 {
194   PyObject * py_dissector;
195
196   /* printf("pinfo->current_proto : %s\n", pinfo->current_proto); */
197   /* NOTE => pinfo->current_proto == "HomePlug" */
198
199   g_tree = tree;
200   g_pinfo = pinfo;
201   g_tvb = tvb;
202
203   py_dissector = g_hash_table_lookup(g_py_dissectors, pinfo->current_proto);
204   assert(py_dissector);
205
206   PyObject_CallMethod(py_dissector, "pre_dissect", NULL);
207 }
208
209 dissector_handle_t py_create_dissector_handle(const int proto)
210 {
211                 return create_dissector_handle(&py_dissect, proto);
212 }
213
214 static void register_all_py_handoffs_foreach(gpointer key _U_, gpointer value, gpointer user_data _U_)
215 {
216   PyObject * py_dissector = (PyObject *)value;
217
218   PyObject_CallMethod(py_dissector, "register_handoff", NULL);
219 }
220
221 /**
222  * Finalize the registration of the python protocol dissectors
223  */
224 void
225 register_all_py_handoffs_func(void)
226 {
227   g_hash_table_foreach(g_py_dissectors, register_all_py_handoffs_foreach, NULL);
228 }
229
230 #endif /* HAVE_PYTHON */