ISO14443: Fix Dead Store (Dead assignement/Dead increment) Warning found by Clang
[metze/wireshark/wip.git] / epan / epan.c
index 2a9533fc8942deda3543a5c577ca165b6ada9bb5..b2a1f5d4f64e0fdc219f0158c9c07c735136fa59 100644 (file)
@@ -1,6 +1,4 @@
 /* epan.c
- *
- * $Id$
  *
  * Wireshark Protocol Analyzer Library
  *
 
 #include "config.h"
 
-#ifdef HAVE_PYTHON
-#include <Python.h> /* to get the Python version number (PY_VERSION) */
-#endif
+#include <stdarg.h>
 
-#ifdef HAVE_LIBGCRYPT
 #include <wsutil/wsgcrypt.h>
-#endif /* HAVE_LIBGCRYPT */
 
 #ifdef HAVE_LIBGNUTLS
 #include <gnutls/gnutls.h>
 
 #include <glib.h>
 
+#include <wsutil/report_err.h>
+
+#include <epan/exceptions.h>
+
 #include "epan-int.h"
 #include "epan.h"
 #include "dfilter/dfilter.h"
@@ -51,9 +49,9 @@
 #include "tap.h"
 #include "addr_resolv.h"
 #include "oids.h"
-#include "emem.h"
 #include "wmem/wmem.h"
 #include "expert.h"
+#include "print.h"
 
 #ifdef HAVE_LUA
 #include <lua.h>
@@ -91,21 +89,22 @@ epan_register_plugin_types(void)
 #endif
 }
 
-void
+gboolean
 epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data),
          void (*register_all_handoffs_func)(register_cb cb, gpointer client_data),
          register_cb cb,
          gpointer client_data)
 {
-       /* initialize memory allocation subsystems */
-       emem_init();
+       volatile gboolean status = TRUE;
+
+       /* initialize memory allocation subsystem */
        wmem_init();
 
        /* initialize the GUID to name mapping table */
        guids_init();
 
-        /* initialize name resolution (addr_resolv.c) */
-        addr_resolv_init();
+       /* initialize name resolution (addr_resolv.c) */
+       addr_resolv_init();
 
        except_init();
 #ifdef HAVE_LIBGCRYPT
@@ -117,19 +116,42 @@ epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_da
 #ifdef HAVE_LIBGNUTLS
        gnutls_global_init();
 #endif
-       tap_init();
-       prefs_init();
-       expert_init();
-       packet_init();
-       proto_init(register_all_protocols_func, register_all_handoffs_func,
-           cb, client_data);
-       packet_cache_proto_handles();
-       dfilter_init();
-       final_registration_all_protocols();
-       expert_packet_init();
+       TRY {
+               tap_init();
+               prefs_init();
+               expert_init();
+               packet_init();
+               proto_init(register_all_protocols_func, register_all_handoffs_func,
+                   cb, client_data);
+               packet_cache_proto_handles();
+               dfilter_init();
+               final_registration_all_protocols();
+               print_cache_field_handles();
+               expert_packet_init();
 #ifdef HAVE_LUA
-       wslua_init(cb, client_data);
+               wslua_init(cb, client_data);
 #endif
+       }
+       CATCH(DissectorError) {
+               /*
+                * This is probably a dissector, or something it calls,
+                * calling REPORT_DISSECTOR_ERROR() in a registration
+                * routine or something else outside the normal dissection
+                * code path.
+                */
+               const char *exception_message = GET_MESSAGE;
+               static const char dissector_error_nomsg[] =
+                   "Dissector writer didn't bother saying what the error was";
+
+               report_failure("Dissector bug: %s",
+                              exception_message == NULL ?
+                                dissector_error_nomsg : exception_message);
+               if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
+                       abort();
+               status = FALSE;
+       }
+       ENDTRY;
+       return status;
 }
 
 void
@@ -148,6 +170,12 @@ epan_cleanup(void)
 #endif
        except_deinit();
        addr_resolv_cleanup();
+
+       if (pinfo_pool_cache != NULL) {
+               wmem_destroy_allocator(pinfo_pool_cache);
+               pinfo_pool_cache = NULL;
+       }
+
        wmem_cleanup();
 }
 
@@ -229,6 +257,21 @@ epan_circuit_cleanup(void)
        circuit_cleanup();
 }
 
+/* Overrides proto_tree_visible i epan_dissect_init to make all fields visible.
+ * This is > 0 if a Lua script wanted to see all fields all the time.
+ * This is ref-counted, so clearing it won't override other taps/scripts wanting it.
+ */
+static gint always_visible_refcount = 0;
+
+void
+epan_set_always_visible(gboolean force)
+{
+       if (force)
+               always_visible_refcount++;
+       else if (always_visible_refcount > 0)
+               always_visible_refcount--;
+}
+
 epan_dissect_t*
 epan_dissect_init(epan_dissect_t *edt, epan_t *session, const gboolean create_proto_tree, const gboolean proto_tree_visible)
 {
@@ -242,12 +285,12 @@ epan_dissect_init(epan_dissect_t *edt, epan_t *session, const gboolean create_pr
                pinfo_pool_cache = NULL;
        }
        else {
-               edt->pi.pool = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK);
+               edt->pi.pool = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK_FAST);
        }
 
        if (create_proto_tree) {
                edt->tree = proto_tree_create_root(&edt->pi);
-               proto_tree_set_visible(edt->tree, proto_tree_visible);
+               proto_tree_set_visible(edt->tree, (always_visible_refcount > 0) ? TRUE : proto_tree_visible);
        }
        else {
                edt->tree = NULL;
@@ -306,37 +349,37 @@ epan_dissect_fake_protocols(epan_dissect_t *edt, const gboolean fake_protocols)
 }
 
 void
-epan_dissect_run(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
-        tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
+epan_dissect_run(epan_dissect_t *edt, int file_type_subtype,
+       struct wtap_pkthdr *phdr, tvbuff_t *tvb, frame_data *fd,
+       column_info *cinfo)
 {
 #ifdef HAVE_LUA
        wslua_prime_dfilter(edt); /* done before entering wmem scope */
 #endif
        wmem_enter_packet_scope();
-       dissect_packet(edt, phdr, tvb, fd, cinfo);
+       dissect_record(edt, file_type_subtype, phdr, tvb, fd, cinfo);
 
        /* free all memory allocated */
-       ep_free_all();
        wmem_leave_packet_scope();
 }
 
 void
-epan_dissect_run_with_taps(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
-        tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
+epan_dissect_run_with_taps(epan_dissect_t *edt, int file_type_subtype,
+       struct wtap_pkthdr *phdr, tvbuff_t *tvb, frame_data *fd,
+       column_info *cinfo)
 {
        wmem_enter_packet_scope();
        tap_queue_init(edt);
-       dissect_packet(edt, phdr, tvb, fd, cinfo);
+       dissect_record(edt, file_type_subtype, phdr, tvb, fd, cinfo);
        tap_push_tapped_queue(edt);
 
        /* free all memory allocated */
-       ep_free_all();
        wmem_leave_packet_scope();
 }
 
 void
 epan_dissect_file_run(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
-        tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
+       tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
 {
 #ifdef HAVE_LUA
        wslua_prime_dfilter(edt); /* done before entering wmem scope */
@@ -345,13 +388,12 @@ epan_dissect_file_run(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
        dissect_file(edt, phdr, tvb, fd, cinfo);
 
        /* free all memory allocated */
-       ep_free_all();
        wmem_leave_packet_scope();
 }
 
 void
 epan_dissect_file_run_with_taps(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
-        tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
+       tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
 {
        wmem_enter_packet_scope();
        tap_queue_init(edt);
@@ -359,7 +401,6 @@ epan_dissect_file_run_with_taps(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
        tap_push_tapped_queue(edt);
 
        /* free all memory allocated */
-       ep_free_all();
        wmem_leave_packet_scope();
 }
 
@@ -407,38 +448,38 @@ epan_dissect_prime_dfilter(epan_dissect_t *edt, const dfilter_t* dfcode)
 
 /* ----------------------- */
 const gchar *
-epan_custom_set(epan_dissect_t *edt, int field_id,
-                             gint occurrence,
-                             gchar *result,
-                             gchar *expr, const int size )
+epan_custom_set(epan_dissect_t *edt, GSList *field_ids,
+                            gint occurrence,
+                            gchar *result,
+                            gchar *expr, const int size )
 {
-    return proto_custom_set(edt->tree, field_id, occurrence, result, expr, size);
+       return proto_custom_set(edt->tree, field_ids, occurrence, result, expr, size);
 }
 
 void
 epan_dissect_fill_in_columns(epan_dissect_t *edt, const gboolean fill_col_exprs, const gboolean fill_fd_colums)
 {
-    col_custom_set_edt(edt, edt->pi.cinfo);
-    col_fill_in(&edt->pi, fill_col_exprs, fill_fd_colums);
+       col_custom_set_edt(edt, edt->pi.cinfo);
+       col_fill_in(&edt->pi, fill_col_exprs, fill_fd_colums);
 }
 
 gboolean
 epan_dissect_packet_contains_field(epan_dissect_t* edt,
-                                   const char *field_name)
+                                  const char *field_name)
 {
-    GPtrArray* array;
-    int        field_id;
-    gboolean   contains_field;
-
-    if (!edt || !edt->tree)
-        return FALSE;
-    field_id = proto_get_id_by_filter_name(field_name);
-    if (field_id < 0)
-        return FALSE;
-    array = proto_find_finfo(edt->tree, field_id);
-    contains_field = (array->len > 0) ? TRUE : FALSE;
-    g_ptr_array_free(array, TRUE);
-    return contains_field;
+       GPtrArray* array;
+       int field_id;
+       gboolean contains_field;
+
+       if (!edt || !edt->tree)
+               return FALSE;
+       field_id = proto_get_id_by_filter_name(field_name);
+       if (field_id < 0)
+               return FALSE;
+       array = proto_find_finfo(edt->tree, field_id);
+       contains_field = (array->len > 0) ? TRUE : FALSE;
+       g_ptr_array_free(array, TRUE);
+       return contains_field;
 }
 
 /*
@@ -447,7 +488,7 @@ epan_dissect_packet_contains_field(epan_dissect_t* edt,
 void
 epan_get_compiled_version_info(GString *str)
 {
-        /* SNMP */
+       /* SNMP */
        g_string_append(str, ", ");
 #ifdef HAVE_LIBSMI
        g_string_append(str, "with SMI " SMI_VERSION_STRING);
@@ -471,7 +512,7 @@ epan_get_compiled_version_info(GString *str)
 #endif /* HAVE_GNU_ADNS */
 #endif /* HAVE_C_ARES */
 
-        /* LUA */
+       /* LUA */
        g_string_append(str, ", ");
 #ifdef HAVE_LUA
        g_string_append(str, "with ");
@@ -480,17 +521,7 @@ epan_get_compiled_version_info(GString *str)
        g_string_append(str, "without Lua");
 #endif /* HAVE_LUA */
 
-       g_string_append(str, ", ");
-#ifdef HAVE_PYTHON
-       g_string_append(str, "with Python");
-#ifdef PY_VERSION
-       g_string_append(str, " " PY_VERSION);
-#endif /* PY_VERSION */
-#else
-       g_string_append(str, "without Python");
-#endif /* HAVE_PYTHON */
-
-        /* GnuTLS */
+       /* GnuTLS */
        g_string_append(str, ", ");
 #ifdef HAVE_LIBGNUTLS
        g_string_append(str, "with GnuTLS " LIBGNUTLS_VERSION);
@@ -498,7 +529,7 @@ epan_get_compiled_version_info(GString *str)
        g_string_append(str, "without GnuTLS");
 #endif /* HAVE_LIBGNUTLS */
 
-        /* Gcrypt */
+       /* Gcrypt */
        g_string_append(str, ", ");
 #ifdef HAVE_LIBGCRYPT
        g_string_append(str, "with Gcrypt " GCRYPT_VERSION);
@@ -506,14 +537,14 @@ epan_get_compiled_version_info(GString *str)
        g_string_append(str, "without Gcrypt");
 #endif /* HAVE_LIBGCRYPT */
 
-        /* Kerberos */
-        /* XXX - I don't see how to get the version number, at least for KfW */
+       /* Kerberos */
+       /* XXX - I don't see how to get the version number, at least for KfW */
        g_string_append(str, ", ");
 #ifdef HAVE_KERBEROS
 #ifdef HAVE_MIT_KERBEROS
        g_string_append(str, "with MIT Kerberos");
 #else
-        /* HAVE_HEIMDAL_KERBEROS */
+       /* HAVE_HEIMDAL_KERBEROS */
        g_string_append(str, "with Heimdal Kerberos");
 #endif
 #else
@@ -540,14 +571,14 @@ _U_
 #endif
 )
 {
-        /* GnuTLS */
+       /* GnuTLS */
 #ifdef HAVE_LIBGNUTLS
-       g_string_append_printf(str, ", GnuTLS %s", gnutls_check_version(NULL));
+       g_string_append_printf(str, ", with GnuTLS %s", gnutls_check_version(NULL));
 #endif /* HAVE_LIBGNUTLS */
 
-        /* Gcrypt */
+       /* Gcrypt */
 #ifdef HAVE_LIBGCRYPT
-       g_string_append_printf(str, ", Gcrypt %s", gcry_check_version(NULL));
+       g_string_append_printf(str, ", with Gcrypt %s", gcry_check_version(NULL));
 #endif /* HAVE_LIBGCRYPT */
 }