lua: fix reload with -Xlua_script
[metze/wireshark/wip.git] / epan / epan.c
1 /* epan.c
2  *
3  * Wireshark Protocol Analyzer Library
4  *
5  * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25
26 #include <wsutil/wsgcrypt.h>
27
28 #ifdef HAVE_LIBGNUTLS
29 #include <gnutls/gnutls.h>
30 #endif /* HAVE_LIBGNUTLS */
31
32 #include <glib.h>
33
34 #include <wsutil/report_err.h>
35
36 #include <epan/exceptions.h>
37
38 #include "epan-int.h"
39 #include "epan.h"
40 #include "dfilter/dfilter.h"
41 #include "epan_dissect.h"
42
43 #include "conversation.h"
44 #include "circuit.h"
45 #include "except.h"
46 #include "packet.h"
47 #include "prefs.h"
48 #include "column-utils.h"
49 #include "tap.h"
50 #include "addr_resolv.h"
51 #include "oids.h"
52 #include "wmem/wmem.h"
53 #include "expert.h"
54 #include "print.h"
55 #include "capture_dissectors.h"
56
57 #ifdef HAVE_LUA
58 #include <lua.h>
59 #include <wslua/wslua.h>
60 #endif
61
62 #ifdef HAVE_LIBSMI
63 #include <smi.h>
64 #endif
65
66 #ifdef HAVE_C_ARES
67 #include <ares_version.h>
68 #endif
69
70 static wmem_allocator_t *pinfo_pool_cache = NULL;
71
72 const gchar*
73 epan_get_version(void) {
74         return VERSION;
75 }
76
77 /*
78  * Register all the plugin types that are part of libwireshark, namely
79  * dissector and tap plugins.
80  *
81  * Must be called before init_plugins(), which must be called before
82  * any registration routines are called.
83  */
84 void
85 epan_register_plugin_types(void)
86 {
87 #ifdef HAVE_PLUGINS
88         register_dissector_plugin_type();
89         register_tap_plugin_type();
90 #endif
91 }
92
93 gboolean
94 epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
95           void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
96           register_cb cb,
97           gpointer client_data)
98 {
99         volatile gboolean status = TRUE;
100
101         /* initialize memory allocation subsystem */
102         wmem_init();
103
104         /* initialize the GUID to name mapping table */
105         guids_init();
106
107         /* initialize name resolution (addr_resolv.c) */
108         addr_resolv_init();
109
110         except_init();
111 #ifdef HAVE_LIBGCRYPT
112         /* initialize libgcrypt (beware, it won't be thread-safe) */
113         gcry_check_version(NULL);
114         gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
115         gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
116 #endif
117 #ifdef HAVE_LIBGNUTLS
118         gnutls_global_init();
119 #endif
120         TRY {
121                 tap_init();
122                 prefs_init();
123                 expert_init();
124                 packet_init();
125                 capture_dissector_init();
126                 proto_init(register_all_protocols_func, register_all_handoffs_func,
127                     cb, client_data);
128                 packet_cache_proto_handles();
129                 dfilter_init();
130                 final_registration_all_protocols();
131                 print_cache_field_handles();
132                 expert_packet_init();
133 #ifdef HAVE_LUA
134                 wslua_init(cb, client_data);
135 #endif
136         }
137         CATCH(DissectorError) {
138                 /*
139                  * This is probably a dissector, or something it calls,
140                  * calling REPORT_DISSECTOR_ERROR() in a registration
141                  * routine or something else outside the normal dissection
142                  * code path.
143                  */
144                 const char *exception_message = GET_MESSAGE;
145                 static const char dissector_error_nomsg[] =
146                     "Dissector writer didn't bother saying what the error was";
147
148                 report_failure("Dissector bug: %s",
149                                exception_message == NULL ?
150                                  dissector_error_nomsg : exception_message);
151                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
152                         abort();
153                 status = FALSE;
154         }
155         ENDTRY;
156         return status;
157 }
158
159 void
160 epan_cleanup(void)
161 {
162         dfilter_cleanup();
163         proto_cleanup();
164         prefs_cleanup();
165         packet_cleanup();
166         expert_cleanup();
167         capture_dissector_cleanup();
168 #ifdef HAVE_LUA
169         wslua_cleanup();
170 #endif
171 #ifdef HAVE_LIBGNUTLS
172         gnutls_global_deinit();
173 #endif
174         except_deinit();
175         addr_resolv_cleanup();
176
177         if (pinfo_pool_cache != NULL) {
178                 wmem_destroy_allocator(pinfo_pool_cache);
179                 pinfo_pool_cache = NULL;
180         }
181
182         wmem_cleanup();
183 }
184
185 epan_t *
186 epan_new(void)
187 {
188         epan_t *session = g_slice_new(epan_t);
189
190         /* XXX, it should take session as param */
191         init_dissection();
192
193         return session;
194 }
195
196 const char *
197 epan_get_user_comment(const epan_t *session, const frame_data *fd)
198 {
199         if (session->get_user_comment)
200                 return session->get_user_comment(session->data, fd);
201
202         return NULL;
203 }
204
205 const char *
206 epan_get_interface_name(const epan_t *session, guint32 interface_id)
207 {
208         if (session->get_interface_name)
209                 return session->get_interface_name(session->data, interface_id);
210
211         return NULL;
212 }
213
214 const nstime_t *
215 epan_get_frame_ts(const epan_t *session, guint32 frame_num)
216 {
217         const nstime_t *abs_ts = NULL;
218
219         if (session->get_frame_ts)
220                 abs_ts = session->get_frame_ts(session->data, frame_num);
221
222         if (!abs_ts)
223                 g_warning("!!! couldn't get frame ts for %u !!!\n", frame_num);
224
225         return abs_ts;
226 }
227
228 void
229 epan_free(epan_t *session)
230 {
231         if (session) {
232                 /* XXX, it should take session as param */
233                 cleanup_dissection();
234
235                 g_slice_free(epan_t, session);
236         }
237 }
238
239 void
240 epan_conversation_init(void)
241 {
242         conversation_init();
243 }
244
245 void
246 epan_conversation_cleanup(void)
247 {
248         conversation_cleanup();
249 }
250
251 void
252 epan_circuit_init(void)
253 {
254         circuit_init();
255 }
256
257 void
258 epan_circuit_cleanup(void)
259 {
260         circuit_cleanup();
261 }
262
263 /* Overrides proto_tree_visible i epan_dissect_init to make all fields visible.
264  * This is > 0 if a Lua script wanted to see all fields all the time.
265  * This is ref-counted, so clearing it won't override other taps/scripts wanting it.
266  */
267 static gint always_visible_refcount = 0;
268
269 void
270 epan_set_always_visible(gboolean force)
271 {
272         if (force)
273                 always_visible_refcount++;
274         else if (always_visible_refcount > 0)
275                 always_visible_refcount--;
276 }
277
278 epan_dissect_t*
279 epan_dissect_init(epan_dissect_t *edt, epan_t *session, const gboolean create_proto_tree, const gboolean proto_tree_visible)
280 {
281         g_assert(edt);
282
283         edt->session = session;
284
285         memset(&edt->pi, 0, sizeof(edt->pi));
286         if (pinfo_pool_cache != NULL) {
287                 edt->pi.pool = pinfo_pool_cache;
288                 pinfo_pool_cache = NULL;
289         }
290         else {
291                 edt->pi.pool = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK_FAST);
292         }
293
294         if (create_proto_tree) {
295                 edt->tree = proto_tree_create_root(&edt->pi);
296                 proto_tree_set_visible(edt->tree, (always_visible_refcount > 0) ? TRUE : proto_tree_visible);
297         }
298         else {
299                 edt->tree = NULL;
300         }
301
302         edt->tvb = NULL;
303
304         return edt;
305 }
306
307 void
308 epan_dissect_reset(epan_dissect_t *edt)
309 {
310         /* We have to preserve the pool pointer across the memzeroing */
311         wmem_allocator_t *tmp;
312
313         g_assert(edt);
314
315         g_slist_free(edt->pi.proto_data);
316         g_slist_free(edt->pi.dependent_frames);
317
318         /* Free the data sources list. */
319         free_data_sources(&edt->pi);
320
321         if (edt->tvb) {
322                 /* Free all tvb's chained from this tvb */
323                 tvb_free_chain(edt->tvb);
324                 edt->tvb = NULL;
325         }
326
327         if (edt->tree)
328                 proto_tree_reset(edt->tree);
329
330         tmp = edt->pi.pool;
331         wmem_free_all(tmp);
332
333         memset(&edt->pi, 0, sizeof(edt->pi));
334         edt->pi.pool = tmp;
335 }
336
337 epan_dissect_t*
338 epan_dissect_new(epan_t *session, const gboolean create_proto_tree, const gboolean proto_tree_visible)
339 {
340         epan_dissect_t *edt;
341
342         edt = g_new0(epan_dissect_t, 1);
343
344         return epan_dissect_init(edt, session, create_proto_tree, proto_tree_visible);
345 }
346
347 void
348 epan_dissect_fake_protocols(epan_dissect_t *edt, const gboolean fake_protocols)
349 {
350         if (edt)
351                 proto_tree_set_fake_protocols(edt->tree, fake_protocols);
352 }
353
354 void
355 epan_dissect_run(epan_dissect_t *edt, int file_type_subtype,
356         struct wtap_pkthdr *phdr, tvbuff_t *tvb, frame_data *fd,
357         column_info *cinfo)
358 {
359 #ifdef HAVE_LUA
360         wslua_prime_dfilter(edt); /* done before entering wmem scope */
361 #endif
362         wmem_enter_packet_scope();
363         dissect_record(edt, file_type_subtype, phdr, tvb, fd, cinfo);
364
365         /* free all memory allocated */
366         wmem_leave_packet_scope();
367 }
368
369 void
370 epan_dissect_run_with_taps(epan_dissect_t *edt, int file_type_subtype,
371         struct wtap_pkthdr *phdr, tvbuff_t *tvb, frame_data *fd,
372         column_info *cinfo)
373 {
374         wmem_enter_packet_scope();
375         tap_queue_init(edt);
376         dissect_record(edt, file_type_subtype, phdr, tvb, fd, cinfo);
377         tap_push_tapped_queue(edt);
378
379         /* free all memory allocated */
380         wmem_leave_packet_scope();
381 }
382
383 void
384 epan_dissect_file_run(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
385         tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
386 {
387 #ifdef HAVE_LUA
388         wslua_prime_dfilter(edt); /* done before entering wmem scope */
389 #endif
390         wmem_enter_packet_scope();
391         dissect_file(edt, phdr, tvb, fd, cinfo);
392
393         /* free all memory allocated */
394         wmem_leave_packet_scope();
395 }
396
397 void
398 epan_dissect_file_run_with_taps(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
399         tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
400 {
401         wmem_enter_packet_scope();
402         tap_queue_init(edt);
403         dissect_file(edt, phdr, tvb, fd, cinfo);
404         tap_push_tapped_queue(edt);
405
406         /* free all memory allocated */
407         wmem_leave_packet_scope();
408 }
409
410 void
411 epan_dissect_cleanup(epan_dissect_t* edt)
412 {
413         g_assert(edt);
414
415         g_slist_free(edt->pi.proto_data);
416         g_slist_free(edt->pi.dependent_frames);
417
418         /* Free the data sources list. */
419         free_data_sources(&edt->pi);
420
421         if (edt->tvb) {
422                 /* Free all tvb's chained from this tvb */
423                 tvb_free_chain(edt->tvb);
424         }
425
426         if (edt->tree) {
427                 proto_tree_free(edt->tree);
428         }
429
430         if (pinfo_pool_cache == NULL) {
431                 wmem_free_all(edt->pi.pool);
432                 pinfo_pool_cache = edt->pi.pool;
433         }
434         else {
435                 wmem_destroy_allocator(edt->pi.pool);
436         }
437 }
438
439 void
440 epan_dissect_free(epan_dissect_t* edt)
441 {
442         epan_dissect_cleanup(edt);
443         g_free(edt);
444 }
445
446 void
447 epan_dissect_prime_dfilter(epan_dissect_t *edt, const dfilter_t* dfcode)
448 {
449         dfilter_prime_proto_tree(dfcode, edt->tree);
450 }
451
452 void
453 epan_dissect_prime_hfid(epan_dissect_t *edt, int hfid)
454 {
455         proto_tree_prime_hfid(edt->tree, hfid);
456 }
457
458 /* ----------------------- */
459 const gchar *
460 epan_custom_set(epan_dissect_t *edt, GSList *field_ids,
461                              gint occurrence,
462                              gchar *result,
463                              gchar *expr, const int size )
464 {
465         return proto_custom_set(edt->tree, field_ids, occurrence, result, expr, size);
466 }
467
468 void
469 epan_dissect_fill_in_columns(epan_dissect_t *edt, const gboolean fill_col_exprs, const gboolean fill_fd_colums)
470 {
471         col_custom_set_edt(edt, edt->pi.cinfo);
472         col_fill_in(&edt->pi, fill_col_exprs, fill_fd_colums);
473 }
474
475 gboolean
476 epan_dissect_packet_contains_field(epan_dissect_t* edt,
477                                    const char *field_name)
478 {
479         GPtrArray* array;
480         int field_id;
481         gboolean contains_field;
482
483         if (!edt || !edt->tree)
484                 return FALSE;
485         field_id = proto_get_id_by_filter_name(field_name);
486         if (field_id < 0)
487                 return FALSE;
488         array = proto_find_finfo(edt->tree, field_id);
489         contains_field = (array->len > 0) ? TRUE : FALSE;
490         g_ptr_array_free(array, TRUE);
491         return contains_field;
492 }
493
494 /*
495  * Get compile-time information for libraries used by libwireshark.
496  */
497 void
498 epan_get_compiled_version_info(GString *str)
499 {
500         /* SNMP */
501         g_string_append(str, ", ");
502 #ifdef HAVE_LIBSMI
503         g_string_append(str, "with SMI " SMI_VERSION_STRING);
504 #else /* no SNMP library */
505         g_string_append(str, "without SMI");
506 #endif /* _SMI_H */
507
508         /* c-ares */
509         g_string_append(str, ", ");
510 #ifdef HAVE_C_ARES
511         g_string_append(str, "with c-ares " ARES_VERSION_STR);
512 #else
513         g_string_append(str, "without c-ares");
514 #endif /* HAVE_C_ARES */
515
516         /* LUA */
517         g_string_append(str, ", ");
518 #ifdef HAVE_LUA
519         g_string_append(str, "with ");
520         g_string_append(str, LUA_VERSION);
521 #else
522         g_string_append(str, "without Lua");
523 #endif /* HAVE_LUA */
524
525         /* GnuTLS */
526         g_string_append(str, ", ");
527 #ifdef HAVE_LIBGNUTLS
528         g_string_append(str, "with GnuTLS " LIBGNUTLS_VERSION);
529 #else
530         g_string_append(str, "without GnuTLS");
531 #endif /* HAVE_LIBGNUTLS */
532
533         /* Gcrypt */
534         g_string_append(str, ", ");
535 #ifdef HAVE_LIBGCRYPT
536         g_string_append(str, "with Gcrypt " GCRYPT_VERSION);
537 #else
538         g_string_append(str, "without Gcrypt");
539 #endif /* HAVE_LIBGCRYPT */
540
541         /* Kerberos */
542         /* XXX - I don't see how to get the version number, at least for KfW */
543         g_string_append(str, ", ");
544 #ifdef HAVE_KERBEROS
545 #ifdef HAVE_MIT_KERBEROS
546         g_string_append(str, "with MIT Kerberos");
547 #else
548         /* HAVE_HEIMDAL_KERBEROS */
549         g_string_append(str, "with Heimdal Kerberos");
550 #endif
551 #else
552         g_string_append(str, "without Kerberos");
553 #endif /* HAVE_KERBEROS */
554
555         /* GeoIP */
556         g_string_append(str, ", ");
557 #ifdef HAVE_GEOIP
558         g_string_append(str, "with GeoIP");
559 #else
560         g_string_append(str, "without GeoIP");
561 #endif /* HAVE_GEOIP */
562
563 }
564
565 /*
566  * Get runtime information for libraries used by libwireshark.
567  */
568 void
569 epan_get_runtime_version_info(GString *str
570 #if !defined(HAVE_LIBGNUTLS) && !defined(HAVE_LIBGCRYPT)
571 _U_
572 #endif
573 )
574 {
575         /* GnuTLS */
576 #ifdef HAVE_LIBGNUTLS
577         g_string_append_printf(str, ", with GnuTLS %s", gnutls_check_version(NULL));
578 #endif /* HAVE_LIBGNUTLS */
579
580         /* Gcrypt */
581 #ifdef HAVE_LIBGCRYPT
582         g_string_append_printf(str, ", with Gcrypt %s", gcry_check_version(NULL));
583 #endif /* HAVE_LIBGCRYPT */
584 }
585
586 /*
587  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
588  *
589  * Local variables:
590  * c-basic-offset: 8
591  * tab-width: 8
592  * indent-tabs-mode: t
593  * End:
594  *
595  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
596  * :indentSize=8:tabSize=8:noTabs=false:
597  */