/* 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>
#endif /* HAVE_LIBGNUTLS */
#include <glib.h>
+
+#include <wsutil/report_err.h>
+
+#include <epan/exceptions.h>
+
#include "epan-int.h"
#include "epan.h"
+#include "dfilter/dfilter.h"
#include "epan_dissect.h"
-#include "wsutil/report_err.h"
#include "conversation.h"
#include "circuit.h"
#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>
#include <ares_version.h>
#endif
+static wmem_allocator_t *pinfo_pool_cache = NULL;
+
const gchar*
epan_get_version(void) {
return VERSION;
}
+/*
+ * Register all the plugin types that are part of libwireshark, namely
+ * dissector and tap plugins.
+ *
+ * Must be called before init_plugins(), which must be called before
+ * any registration routines are called.
+ */
void
+epan_register_plugin_types(void)
+{
+#ifdef HAVE_PLUGINS
+ register_dissector_plugin_type();
+ register_tap_plugin_type();
+#endif
+}
+
+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,
- void (*report_failure_fcn_p)(const char *, va_list),
- void (*report_open_failure_fcn_p)(const char *, int, gboolean),
- void (*report_read_failure_fcn_p)(const char *, int),
- void (*report_write_failure_fcn_p)(const char *, int))
+ gpointer client_data)
{
- init_report_err(report_failure_fcn_p, report_open_failure_fcn_p,
- report_read_failure_fcn_p, report_write_failure_fcn_p);
+ volatile gboolean status = TRUE;
- /* initialize memory allocation subsystems */
- emem_init();
+ /* 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
#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
prefs_cleanup();
packet_cleanup();
expert_cleanup();
+#ifdef HAVE_LUA
+ wslua_cleanup();
+#endif
#ifdef HAVE_LIBGNUTLS
gnutls_global_deinit();
#endif
except_deinit();
addr_resolv_cleanup();
+
+ if (pinfo_pool_cache != NULL) {
+ wmem_destroy_allocator(pinfo_pool_cache);
+ pinfo_pool_cache = NULL;
+ }
+
wmem_cleanup();
}
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)
{
edt->session = session;
+ memset(&edt->pi, 0, sizeof(edt->pi));
+ if (pinfo_pool_cache != NULL) {
+ edt->pi.pool = pinfo_pool_cache;
+ pinfo_pool_cache = NULL;
+ }
+ else {
+ 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;
edt->tvb = NULL;
- memset(&edt->pi, 0, sizeof(edt->pi));
- edt->pi.pool = wmem_allocator_new(WMEM_ALLOCATOR_SIMPLE);
-
return edt;
}
g_assert(edt);
+ g_slist_free(edt->pi.proto_data);
g_slist_free(edt->pi.dependent_frames);
/* Free the data sources list. */
}
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 */
+ 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)
+{
+#ifdef HAVE_LUA
+ wslua_prime_dfilter(edt); /* done before entering wmem scope */
+#endif
+ wmem_enter_packet_scope();
+ dissect_file(edt, phdr, tvb, fd, cinfo);
+
+ /* free all memory allocated */
+ 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)
+{
+ wmem_enter_packet_scope();
+ tap_queue_init(edt);
+ dissect_file(edt, phdr, tvb, fd, cinfo);
tap_push_tapped_queue(edt);
/* free all memory allocated */
- ep_free_all();
wmem_leave_packet_scope();
}
{
g_assert(edt);
+ g_slist_free(edt->pi.proto_data);
g_slist_free(edt->pi.dependent_frames);
/* Free the data sources list. */
proto_tree_free(edt->tree);
}
- wmem_destroy_allocator(edt->pi.pool);
+ if (pinfo_pool_cache == NULL) {
+ wmem_free_all(edt->pi.pool);
+ pinfo_pool_cache = edt->pi.pool;
+ }
+ else {
+ wmem_destroy_allocator(edt->pi.pool);
+ }
}
void
/* ----------------------- */
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;
}
/*
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);
#endif /* HAVE_GNU_ADNS */
#endif /* HAVE_C_ARES */
- /* LUA */
+ /* LUA */
g_string_append(str, ", ");
#ifdef HAVE_LUA
g_string_append(str, "with ");
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);
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);
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
#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 */
}