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