diff --git a/epan/dissectors/asn1/ldap/packet-ldap-template.c b/epan/dissectors/asn1/ldap/packet-ldap-template.c index be679ece64..9b9b9afdcf 100644 --- a/epan/dissectors/asn1/ldap/packet-ldap-template.c +++ b/epan/dissectors/asn1/ldap/packet-ldap-template.c @@ -451,10 +451,12 @@ typedef struct _attribute_type_t { gchar* attribute_desc; } attribute_type_t; -static attribute_type_t* attribute_types = NULL; -static guint num_attribute_types = 0; +static attribute_type_t* attribute_types; +static guint num_attribute_types; -static GHashTable* attribute_types_hash = NULL; +static GHashTable* attribute_types_hash; +static hf_register_info* dynamic_hf; +static guint dynamic_hf_size; static gboolean attribute_types_update_cb(void *r, char **err) @@ -531,51 +533,67 @@ get_hf_for_header(char* attribute_type) * */ static void -attribute_types_initialize_cb(void) +deregister_attribute_types(void) { - static hf_register_info* hf; - gint* hf_id; - guint i; - gchar* attribute_type; - - if (attribute_types_hash && hf) { - guint hf_size = g_hash_table_size (attribute_types_hash); + if (dynamic_hf) { /* Deregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field (proto_ldap, *(hf[i].p_id)); - g_free (hf[i].p_id); + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field (proto_ldap, *(dynamic_hf[i].p_id)); + g_free (dynamic_hf[i].p_id); } + + proto_add_deregistered_data (dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (attribute_types_hash) { g_hash_table_destroy (attribute_types_hash); - proto_add_deregistered_data (hf); attribute_types_hash = NULL; } +} + +static void +attribute_types_post_update_cb(void) +{ + gint* hf_id; + gchar* attribute_type; + + deregister_attribute_types(); if (num_attribute_types) { attribute_types_hash = g_hash_table_new(g_str_hash, g_str_equal); - hf = g_new0(hf_register_info,num_attribute_types); + dynamic_hf = g_new0(hf_register_info,num_attribute_types); + dynamic_hf_size = num_attribute_types; - for (i = 0; i < num_attribute_types; i++) { + for (guint i = 0; i < dynamic_hf_size; i++) { hf_id = g_new(gint,1); *hf_id = -1; attribute_type = g_strdup(attribute_types[i].attribute_type); - hf[i].p_id = hf_id; - hf[i].hfinfo.name = attribute_type; - hf[i].hfinfo.abbrev = g_strdup_printf("ldap.AttributeValue.%s", attribute_type); - hf[i].hfinfo.type = FT_STRING; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(attribute_types[i].attribute_desc); - HFILL_INIT(hf[i]); + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.name = attribute_type; + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("ldap.AttributeValue.%s", attribute_type); + dynamic_hf[i].hfinfo.type = FT_STRING; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(attribute_types[i].attribute_desc); + HFILL_INIT(dynamic_hf[i]); g_hash_table_insert(attribute_types_hash, attribute_type, hf_id); } - proto_register_field_array(proto_ldap, hf, num_attribute_types); + proto_register_field_array(proto_ldap, dynamic_hf, dynamic_hf_size); } } +static void +attribute_types_reset_cb(void) +{ + deregister_attribute_types(); +} + /* MS-ADTS specification, section 7.3.1.1, NETLOGON_NT_VERSION Options Bits */ static int dissect_mscldap_ntver_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset) { @@ -2204,8 +2222,8 @@ void proto_register_ldap(void) { attribute_types_copy_cb, attribute_types_update_cb, attribute_types_free_cb, - attribute_types_initialize_cb, - NULL, + attribute_types_post_update_cb, + attribute_types_reset_cb, custom_attribute_types_uat_fields); prefs_register_uat_preference(ldap_module, "custom_ldap_attribute_types", diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c index 2adf6e788e..a53f9aa66b 100644 --- a/epan/dissectors/packet-http.c +++ b/epan/dissectors/packet-http.c @@ -159,10 +159,12 @@ typedef struct _header_field_t { gchar* header_desc; } header_field_t; -static header_field_t* header_fields = NULL; -static guint num_header_fields = 0; +static header_field_t* header_fields; +static guint num_header_fields; -static GHashTable* header_fields_hash = NULL; +static GHashTable* header_fields_hash; +static hf_register_info* dynamic_hf; +static guint dynamic_hf_size; static gboolean header_fields_update_cb(void *r, char **err) @@ -2725,54 +2727,69 @@ get_hf_for_header(char* header_name) * */ static void -header_fields_initialize_cb(void) +deregister_header_fields(void) +{ + if (dynamic_hf) { + /* Deregister all fields */ + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field (proto_http, *(dynamic_hf[i].p_id)); + g_free (dynamic_hf[i].p_id); + } + + proto_add_deregistered_data (dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (header_fields_hash) { + g_hash_table_destroy (header_fields_hash); + header_fields_hash = NULL; + } +} + +static void +header_fields_post_update_cb(void) { - static hf_register_info* hf; gint* hf_id; - guint i; gchar* header_name; gchar* header_name_key; - if (header_fields_hash && hf) { - guint hf_size = g_hash_table_size (header_fields_hash); - /* Deregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field (proto_http, *(hf[i].p_id)); - g_free (hf[i].p_id); - } - g_hash_table_destroy (header_fields_hash); - proto_add_deregistered_data (hf); - header_fields_hash = NULL; - } + deregister_header_fields(); if (num_header_fields) { - header_fields_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); - hf = g_new0(hf_register_info, num_header_fields); + header_fields_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + dynamic_hf = g_new0(hf_register_info, num_header_fields); + dynamic_hf_size = num_header_fields; - for (i = 0; i < num_header_fields; i++) { + for (guint i = 0; i < dynamic_hf_size; i++) { hf_id = g_new(gint,1); *hf_id = -1; header_name = g_strdup(header_fields[i].header_name); header_name_key = g_ascii_strdown(header_name, -1); - hf[i].p_id = hf_id; - hf[i].hfinfo.name = header_name; - hf[i].hfinfo.abbrev = g_strdup_printf("http.header.%s", header_name); - hf[i].hfinfo.type = FT_STRING; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(header_fields[i].header_desc); - HFILL_INIT(hf[i]); + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.name = header_name; + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("http.header.%s", header_name); + dynamic_hf[i].hfinfo.type = FT_STRING; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(header_fields[i].header_desc); + HFILL_INIT(dynamic_hf[i]); g_hash_table_insert(header_fields_hash, header_name_key, hf_id); } - proto_register_field_array(proto_http, hf, num_header_fields); + proto_register_field_array(proto_http, dynamic_hf, dynamic_hf_size); } } +static void +header_fields_reset_cb(void) +{ + deregister_header_fields(); +} + /** * Parses the transfer-coding, returning TRUE if everything was fully understood * or FALSE when unknown names were encountered. @@ -3989,8 +4006,8 @@ proto_register_http(void) header_fields_copy_cb, header_fields_update_cb, header_fields_free_cb, - header_fields_initialize_cb, - NULL, + header_fields_post_update_cb, + header_fields_reset_cb, custom_header_uat_fields ); diff --git a/epan/dissectors/packet-imf.c b/epan/dissectors/packet-imf.c index fff3ea5612..b311019ee5 100644 --- a/epan/dissectors/packet-imf.c +++ b/epan/dissectors/packet-imf.c @@ -310,10 +310,12 @@ typedef struct _header_field_t { guint add_to_col_info; } header_field_t; -static header_field_t *header_fields = NULL; -static guint num_header_fields = 0; +static header_field_t *header_fields; +static guint num_header_fields; -static GHashTable *custom_field_table = NULL; +static GHashTable *custom_field_table; +static hf_register_info *dynamic_hf; +static guint dynamic_hf_size; static gboolean header_fields_update_cb(void *r, char **err) @@ -939,44 +941,54 @@ free_imf_field (gpointer data) } static void -header_fields_initialize_cb (void) +deregister_header_fields(void) { - static hf_register_info *hf; - gint *hf_id; - struct imf_field *imffield; - guint i; - gchar *header_name; - - if (custom_field_table && hf) { - guint hf_size = g_hash_table_size (custom_field_table); + if (dynamic_hf) { /* Deregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field (proto_imf, *(hf[i].p_id)); - g_free (hf[i].p_id); + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field (proto_imf, *(dynamic_hf[i].p_id)); + g_free (dynamic_hf[i].p_id); } + + proto_add_deregistered_data (dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (custom_field_table) { g_hash_table_destroy (custom_field_table); - proto_add_deregistered_data (hf); custom_field_table = NULL; } +} + +static void +header_fields_post_update_cb (void) +{ + gint *hf_id; + struct imf_field *imffield; + gchar *header_name; + + deregister_header_fields(); if (num_header_fields) { custom_field_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_imf_field); - hf = (hf_register_info *)g_malloc0 (sizeof (hf_register_info) * num_header_fields); + dynamic_hf = (hf_register_info *)g_malloc0 (sizeof (hf_register_info) * num_header_fields); + dynamic_hf_size = num_header_fields; - for (i = 0; i < num_header_fields; i++) { + for (guint i = 0; i < dynamic_hf_size; i++) { hf_id = (gint *)g_malloc (sizeof (gint)); *hf_id = -1; header_name = g_strdup (header_fields[i].header_name); - hf[i].p_id = hf_id; - hf[i].hfinfo.name = header_name; - hf[i].hfinfo.abbrev = g_strdup_printf ("imf.header.%s", header_name); - hf[i].hfinfo.type = FT_STRING; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup (header_fields[i].description); - HFILL_INIT(hf[i]); + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.name = header_name; + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf ("imf.header.%s", header_name); + dynamic_hf[i].hfinfo.type = FT_STRING; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup (header_fields[i].description); + HFILL_INIT(dynamic_hf[i]); imffield = (struct imf_field *)g_malloc (sizeof (struct imf_field)); imffield->hf_id = hf_id; @@ -998,7 +1010,7 @@ header_fields_initialize_cb (void) imffield->subdissector = dissect_imf_address_list; break; case FORMAT_SIO_LABEL: - hf[i].hfinfo.type = FT_NONE; /* constructed */ + dynamic_hf[i].hfinfo.type = FT_NONE; /* constructed */ imffield->subdissector = dissect_imf_siolabel; break; default: @@ -1010,10 +1022,16 @@ header_fields_initialize_cb (void) g_hash_table_insert (custom_field_table, (gpointer)imffield->name, (gpointer)imffield); } - proto_register_field_array (proto_imf, hf, num_header_fields); + proto_register_field_array (proto_imf, dynamic_hf, dynamic_hf_size); } } +static void +header_fields_reset_cb(void) +{ + deregister_header_fields(); +} + /* Register all the bits needed by the filtering engine */ void @@ -1311,8 +1329,8 @@ proto_register_imf(void) header_fields_copy_cb, header_fields_update_cb, header_fields_free_cb, - header_fields_initialize_cb, - NULL, + header_fields_post_update_cb, + header_fields_reset_cb, attributes_flds); module_t *imf_module; diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c index 515e19fb4f..921f358435 100644 --- a/epan/dissectors/packet-ldap.c +++ b/epan/dissectors/packet-ldap.c @@ -665,10 +665,12 @@ typedef struct _attribute_type_t { gchar* attribute_desc; } attribute_type_t; -static attribute_type_t* attribute_types = NULL; -static guint num_attribute_types = 0; +static attribute_type_t* attribute_types; +static guint num_attribute_types; -static GHashTable* attribute_types_hash = NULL; +static GHashTable* attribute_types_hash; +static hf_register_info* dynamic_hf; +static guint dynamic_hf_size; static gboolean attribute_types_update_cb(void *r, char **err) @@ -745,51 +747,67 @@ get_hf_for_header(char* attribute_type) * */ static void -attribute_types_initialize_cb(void) +deregister_attribute_types(void) { - static hf_register_info* hf; - gint* hf_id; - guint i; - gchar* attribute_type; - - if (attribute_types_hash && hf) { - guint hf_size = g_hash_table_size (attribute_types_hash); + if (dynamic_hf) { /* Deregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field (proto_ldap, *(hf[i].p_id)); - g_free (hf[i].p_id); + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field (proto_ldap, *(dynamic_hf[i].p_id)); + g_free (dynamic_hf[i].p_id); } + + proto_add_deregistered_data (dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (attribute_types_hash) { g_hash_table_destroy (attribute_types_hash); - proto_add_deregistered_data (hf); attribute_types_hash = NULL; } +} + +static void +attribute_types_post_update_cb(void) +{ + gint* hf_id; + gchar* attribute_type; + + deregister_attribute_types(); if (num_attribute_types) { attribute_types_hash = g_hash_table_new(g_str_hash, g_str_equal); - hf = g_new0(hf_register_info,num_attribute_types); + dynamic_hf = g_new0(hf_register_info,num_attribute_types); + dynamic_hf_size = num_attribute_types; - for (i = 0; i < num_attribute_types; i++) { + for (guint i = 0; i < dynamic_hf_size; i++) { hf_id = g_new(gint,1); *hf_id = -1; attribute_type = g_strdup(attribute_types[i].attribute_type); - hf[i].p_id = hf_id; - hf[i].hfinfo.name = attribute_type; - hf[i].hfinfo.abbrev = g_strdup_printf("ldap.AttributeValue.%s", attribute_type); - hf[i].hfinfo.type = FT_STRING; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(attribute_types[i].attribute_desc); - HFILL_INIT(hf[i]); + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.name = attribute_type; + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("ldap.AttributeValue.%s", attribute_type); + dynamic_hf[i].hfinfo.type = FT_STRING; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(attribute_types[i].attribute_desc); + HFILL_INIT(dynamic_hf[i]); g_hash_table_insert(attribute_types_hash, attribute_type, hf_id); } - proto_register_field_array(proto_ldap, hf, num_attribute_types); + proto_register_field_array(proto_ldap, dynamic_hf, dynamic_hf_size); } } +static void +attribute_types_reset_cb(void) +{ + deregister_attribute_types(); +} + /* MS-ADTS specification, section 7.3.1.1, NETLOGON_NT_VERSION Options Bits */ static int dissect_mscldap_ntver_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset) { @@ -3815,7 +3833,7 @@ static int dissect_PasswordPolicyResponseValue_PDU(tvbuff_t *tvb _U_, packet_inf /*--- End of included file: packet-ldap-fn.c ---*/ -#line 901 "./asn1/ldap/packet-ldap-template.c" +#line 919 "./asn1/ldap/packet-ldap-template.c" static int dissect_LDAPMessage_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ldap_conv_info_t *ldap_info) { int offset = 0; @@ -5625,7 +5643,7 @@ void proto_register_ldap(void) { NULL, HFILL }}, /*--- End of included file: packet-ldap-hfarr.c ---*/ -#line 2142 "./asn1/ldap/packet-ldap-template.c" +#line 2160 "./asn1/ldap/packet-ldap-template.c" }; /* List of subtrees */ @@ -5699,7 +5717,7 @@ void proto_register_ldap(void) { &ett_ldap_T_warning, /*--- End of included file: packet-ldap-ettarr.c ---*/ -#line 2156 "./asn1/ldap/packet-ldap-template.c" +#line 2174 "./asn1/ldap/packet-ldap-template.c" }; /* UAT for header fields */ static uat_field_t custom_attribute_types_uat_fields[] = { @@ -5751,8 +5769,8 @@ void proto_register_ldap(void) { attribute_types_copy_cb, attribute_types_update_cb, attribute_types_free_cb, - attribute_types_initialize_cb, - NULL, + attribute_types_post_update_cb, + attribute_types_reset_cb, custom_attribute_types_uat_fields); prefs_register_uat_preference(ldap_module, "custom_ldap_attribute_types", @@ -5887,7 +5905,7 @@ proto_reg_handoff_ldap(void) /*--- End of included file: packet-ldap-dis-tab.c ---*/ -#line 2327 "./asn1/ldap/packet-ldap-template.c" +#line 2345 "./asn1/ldap/packet-ldap-template.c" dissector_add_uint_range_with_preference("tcp.port", TCP_PORT_RANGE_LDAP, ldap_handle); } diff --git a/epan/dissectors/packet-lwm2mtlv.c b/epan/dissectors/packet-lwm2mtlv.c index af2ef43f6a..a6fffd2fc0 100644 --- a/epan/dissectors/packet-lwm2mtlv.c +++ b/epan/dissectors/packet-lwm2mtlv.c @@ -235,6 +235,10 @@ static lwm2m_resource_t lwm2m_oma_resources[] = static lwm2m_resource_t *lwm2m_uat_resources; static guint num_lwm2m_uat_resources; +static hf_register_info *dynamic_hf; +static guint dynamic_hf_size; +static hf_register_info *static_hf; + static gboolean lwm2m_resource_update_cb(void *record, char **error) { lwm2m_resource_t *rec = (lwm2m_resource_t *)record; @@ -352,32 +356,41 @@ static void lwm2m_add_resource(lwm2m_resource_t *resource, hf_register_info *hf) HFILL_INIT(*hf); } +static void deregister_resource_fields(void) +{ + if (dynamic_hf) { + /* Deregister all fields */ + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field(proto_lwm2mtlv, *(dynamic_hf[i].p_id)); + g_free (dynamic_hf[i].p_id); + } + + proto_add_deregistered_data(dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } +} + static void lwm2m_resource_post_update_cb(void) { - static hf_register_info *hf; - static guint hf_size; - - if (hf_size > 0) { - /* Deregister all fields */ - for (guint i = 0; i < hf_size; i++) { - proto_deregister_field(proto_lwm2mtlv, *(hf[i].p_id)); - g_free (hf[i].p_id); - } - proto_add_deregistered_data(hf); - hf_size = 0; - } + deregister_resource_fields(); if (num_lwm2m_uat_resources) { - hf = g_new0(hf_register_info, num_lwm2m_uat_resources); + dynamic_hf = g_new0(hf_register_info, num_lwm2m_uat_resources); for (guint i = 0; i < num_lwm2m_uat_resources; i++) { - lwm2m_add_resource(&lwm2m_uat_resources[i], &hf[hf_size++]); + lwm2m_add_resource(&lwm2m_uat_resources[i], &dynamic_hf[dynamic_hf_size++]); } - proto_register_field_array(proto_lwm2mtlv, hf, hf_size); + proto_register_field_array(proto_lwm2mtlv, dynamic_hf, dynamic_hf_size); } } +static void lwm2m_resource_reset_cb(void) +{ + deregister_resource_fields(); +} + static gint64 decodeVariableInt(tvbuff_t *tvb, const gint offset, const guint length) { @@ -709,6 +722,18 @@ dissect_lwm2mtlv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void * return tvb_captured_length(tvb); } +static void lwm2m_shutdown_routine(void) +{ + /* Deregister all fields */ + for (guint i = 0; i < array_length(lwm2m_oma_resources); i++) { + proto_deregister_field(proto_lwm2mtlv, *(static_hf[i].p_id)); + g_free (static_hf[i].p_id); + } + + proto_add_deregistered_data(static_hf); + static_hf = NULL; +} + void proto_register_lwm2mtlv(void) { static hf_register_info hf[] = { @@ -818,7 +843,7 @@ void proto_register_lwm2mtlv(void) lwm2m_resource_update_cb, lwm2m_resource_free_cb, lwm2m_resource_post_update_cb, - NULL, + lwm2m_resource_reset_cb, lwm2m_resource_flds); module_t *lwm2mtlv_module; @@ -835,6 +860,9 @@ void proto_register_lwm2mtlv(void) register_dissector("lwm2mtlv", dissect_lwm2mtlv, proto_lwm2mtlv); + /* Register the dissector shutdown function */ + register_shutdown_routine(lwm2m_shutdown_routine); + lwm2mtlv_module = prefs_register_protocol(proto_lwm2mtlv, NULL); prefs_register_uat_preference(lwm2mtlv_module, "resource_table", @@ -842,11 +870,11 @@ void proto_register_lwm2mtlv(void) "User Resource Names", resource_uat); - hf_register_info *hf2 = g_new0(hf_register_info, array_length(lwm2m_oma_resources)); + static_hf = g_new0(hf_register_info, array_length(lwm2m_oma_resources)); for (guint i = 0; i < array_length(lwm2m_oma_resources); i++) { - lwm2m_add_resource(&lwm2m_oma_resources[i], &hf2[i]); + lwm2m_add_resource(&lwm2m_oma_resources[i], &static_hf[i]); } - proto_register_field_array(proto_lwm2mtlv, hf2, array_length(lwm2m_oma_resources)); + proto_register_field_array(proto_lwm2mtlv, static_hf, array_length(lwm2m_oma_resources)); } void diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c index 4b90e334ca..3a89875320 100644 --- a/epan/dissectors/packet-sip.c +++ b/epan/dissectors/packet-sip.c @@ -908,9 +908,11 @@ typedef struct _header_field_t { gchar* header_desc; } header_field_t; -static header_field_t* sip_custom_header_fields = NULL; -static guint sip_custom_num_header_fields = 0; -static wmem_map_t *sip_custom_header_fields_hash = NULL; +static header_field_t* sip_custom_header_fields; +static guint sip_custom_num_header_fields; +static GHashTable *sip_custom_header_fields_hash; +static hf_register_info *dynamic_hf; +static guint dynamic_hf_size; static gboolean header_fields_update_cb(void *r, char **err) @@ -964,54 +966,69 @@ header_fields_free_cb(void*r) } static void -header_fields_initialize_cb(void) +deregister_header_fields(void) +{ + if (dynamic_hf) { + /* Deregister all fields */ + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field(proto_sip, *(dynamic_hf[i].p_id)); + g_free(dynamic_hf[i].p_id); + } + + proto_add_deregistered_data(dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (sip_custom_header_fields_hash) { + g_hash_table_destroy(sip_custom_header_fields_hash); + sip_custom_header_fields_hash = NULL; + } +} + +static void +header_fields_post_update_cb(void) { - static hf_register_info* hf; gint* hf_id; - guint i; gchar* header_name; gchar* header_name_key; - if (hf) { - guint hf_size = wmem_map_size(sip_custom_header_fields_hash); - /* Deregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field(proto_sip, *(hf[i].p_id)); - header_name_key = wmem_ascii_strdown(NULL, hf[i].hfinfo.name, -1); - wmem_map_remove(sip_custom_header_fields_hash, header_name_key); - wmem_free(NULL, header_name_key); - wmem_free(wmem_epan_scope(), hf[i].p_id); - } - proto_add_deregistered_data(hf); - hf = NULL; - } + deregister_header_fields(); if (sip_custom_num_header_fields) { - hf = g_new0(hf_register_info, sip_custom_num_header_fields); + sip_custom_header_fields_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + dynamic_hf = g_new0(hf_register_info, sip_custom_num_header_fields); + dynamic_hf_size = sip_custom_num_header_fields; - for (i = 0; i < sip_custom_num_header_fields; i++) { - hf_id = wmem_new(wmem_epan_scope(), gint); + for (guint i = 0; i < dynamic_hf_size; i++) { + hf_id = g_new(gint, 1); *hf_id = -1; header_name = g_strdup(sip_custom_header_fields[i].header_name); - header_name_key = wmem_ascii_strdown(wmem_epan_scope(), header_name, -1); + header_name_key = g_ascii_strdown(header_name, -1); - hf[i].p_id = hf_id; - hf[i].hfinfo.name = header_name; - hf[i].hfinfo.abbrev = g_strdup_printf("sip.%s", header_name); - hf[i].hfinfo.type = FT_STRING; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(sip_custom_header_fields[i].header_desc); - HFILL_INIT(hf[i]); + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.name = header_name; + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("sip.%s", header_name); + dynamic_hf[i].hfinfo.type = FT_STRING; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(sip_custom_header_fields[i].header_desc); + HFILL_INIT(dynamic_hf[i]); - wmem_map_insert(sip_custom_header_fields_hash, header_name_key, hf_id); + g_hash_table_insert(sip_custom_header_fields_hash, header_name_key, hf_id); } - proto_register_field_array(proto_sip, hf, sip_custom_num_header_fields); + proto_register_field_array(proto_sip, dynamic_hf, dynamic_hf_size); } } +static void +header_fields_reset_cb(void) +{ + deregister_header_fields(); +} + UAT_CSTRING_CB_DEF(sip_custom_header_fields, header_name, header_field_t) UAT_CSTRING_CB_DEF(sip_custom_header_fields, header_desc, header_field_t) @@ -3576,7 +3593,10 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info value_len = (gint) (line_end_offset - value_offset); if (hf_index == -1) { - gint *hf_ptr = (gint*)wmem_map_lookup(sip_custom_header_fields_hash, header_name); + gint *hf_ptr = NULL; + if (sip_custom_header_fields_hash) { + hf_ptr = (gint*)g_hash_table_lookup(sip_custom_header_fields_hash, header_name); + } if (hf_ptr) { sip_proto_tree_add_string(hdr_tree, *hf_ptr, tvb, offset, next_offset - offset, value_offset, value_len); @@ -7374,8 +7394,8 @@ void proto_register_sip(void) header_fields_copy_cb, header_fields_update_cb, header_fields_free_cb, - header_fields_initialize_cb, - NULL, + header_fields_post_update_cb, + header_fields_reset_cb, sip_custom_header_uat_fields ); @@ -7420,8 +7440,6 @@ void proto_register_sip(void) register_stat_tap_table_ui(&sip_stat_table); - sip_custom_header_fields_hash = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal); - /* compile patterns */ ws_mempbrk_compile(&pbrk_comma_semi, ",;"); ws_mempbrk_compile(&pbrk_whitespace, " \t\r\n"); diff --git a/epan/dissectors/packet-udp-nm.c b/epan/dissectors/packet-udp-nm.c index c999c19a7d..2cef537b65 100644 --- a/epan/dissectors/packet-udp-nm.c +++ b/epan/dissectors/packet-udp-nm.c @@ -74,10 +74,12 @@ static gboolean g_udp_nm_swap_first_fields = TRUE; /*** stolen from the HTTP disector ;-) ***/ -static user_data_field_t* user_data_fields = NULL; -static guint num_user_data_fields = 0; -static GHashTable* user_data_fields_hash_hf = NULL; -static GHashTable* user_data_fields_hash_ett = NULL; +static user_data_field_t* user_data_fields; +static guint num_user_data_fields; +static GHashTable* user_data_fields_hash_hf; +static hf_register_info* dynamic_hf; +static guint dynamic_hf_size; +static wmem_map_t* user_data_fields_hash_ett; static gboolean user_data_fields_update_cb(void *r, char **err) @@ -210,7 +212,7 @@ get_ett_for_user_data(guint32 offset, guint32 length) guint64 key = calc_ett_key(offset, length); if (user_data_fields_hash_ett) { - ett_id = (gint*)g_hash_table_lookup(user_data_fields_hash_ett, &key); + ett_id = (gint*)wmem_map_lookup(user_data_fields_hash_ett, &key); } else { ett_id = NULL; @@ -222,14 +224,32 @@ get_ett_for_user_data(guint32 offset, guint32 length) /* * */ +static void +deregister_user_data(void) +{ + if (dynamic_hf) { + /* Unregister all fields */ + for (guint i = 0; i < dynamic_hf_size; i++) { + proto_deregister_field(proto_udp_nm, *(dynamic_hf[i].p_id)); + g_free(dynamic_hf[i].p_id); + } + + proto_add_deregistered_data(dynamic_hf); + dynamic_hf = NULL; + dynamic_hf_size = 0; + } + + if (user_data_fields_hash_hf) { + g_hash_table_destroy(user_data_fields_hash_hf); + user_data_fields_hash_hf = NULL; + } +} + static void user_data_post_update_cb(void) { - static hf_register_info* hf; gint* hf_id; - guint i; - //gchar* udf_name; - + gint *ett_id; gchar* tmp = NULL; guint64* key = NULL; @@ -238,53 +258,43 @@ user_data_post_update_cb(void) &ett_dummy, }; - static gint *ett_id; - - if (user_data_fields_hash_hf && hf) { - guint hf_size = g_hash_table_size(user_data_fields_hash_hf); - /* Unregister all fields */ - for (i = 0; i < hf_size; i++) { - proto_deregister_field(proto_udp_nm, *(hf[i].p_id)); - } - g_hash_table_destroy(user_data_fields_hash_hf); - - user_data_fields_hash_hf = NULL; - } + deregister_user_data(); // we cannot unregister ETTs, so we should try to limit the damage of an update if (num_user_data_fields) { - user_data_fields_hash_hf = g_hash_table_new(g_str_hash, g_str_equal); - hf = g_new0(hf_register_info, num_user_data_fields); + user_data_fields_hash_hf = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + dynamic_hf = g_new0(hf_register_info, num_user_data_fields); + dynamic_hf_size = num_user_data_fields; if (user_data_fields_hash_ett == NULL) { - user_data_fields_hash_ett = g_hash_table_new(g_int64_hash, g_int64_equal); + user_data_fields_hash_ett = wmem_map_new(wmem_epan_scope(), g_int64_hash, g_int64_equal); } - for (i = 0; i < num_user_data_fields; i++) { + for (guint i = 0; i < dynamic_hf_size; i++) { hf_id = g_new(gint, 1); *hf_id = -1; - hf[i].p_id = hf_id; - hf[i].hfinfo.strings = NULL; - hf[i].hfinfo.bitmask = user_data_fields[i].udf_mask; - hf[i].hfinfo.same_name_next = NULL; - hf[i].hfinfo.same_name_prev_id = -1; + dynamic_hf[i].p_id = hf_id; + dynamic_hf[i].hfinfo.strings = NULL; + dynamic_hf[i].hfinfo.bitmask = user_data_fields[i].udf_mask; + dynamic_hf[i].hfinfo.same_name_next = NULL; + dynamic_hf[i].hfinfo.same_name_prev_id = -1; if (user_data_fields[i].udf_mask == 0 || user_data_fields[i].udf_length <= 0 || user_data_fields[i].udf_length>4) { - hf[i].hfinfo.name = g_strdup(user_data_fields[i].udf_name); - hf[i].hfinfo.abbrev = g_strdup_printf("nm.user_data.%s", user_data_fields[i].udf_name); - hf[i].hfinfo.type = FT_BYTES; - hf[i].hfinfo.display = BASE_NONE; - hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(user_data_fields[i].udf_desc); + dynamic_hf[i].hfinfo.name = g_strdup(user_data_fields[i].udf_name); + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("nm.user_data.%s", user_data_fields[i].udf_name); + dynamic_hf[i].hfinfo.type = FT_BYTES; + dynamic_hf[i].hfinfo.display = BASE_NONE; + dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(user_data_fields[i].udf_desc); } else { - hf[i].hfinfo.name = g_strdup(user_data_fields[i].udf_value_desc); - hf[i].hfinfo.abbrev = g_strdup_printf("nm.user_data.%s.%s", user_data_fields[i].udf_name, user_data_fields[i].udf_value_desc); - hf[i].hfinfo.type = FT_BOOLEAN; - hf[i].hfinfo.display = 8 * (user_data_fields[i].udf_length); - // hf[i].hfinfo.bitmask = 0; - hf[i].hfinfo.blurb = g_strdup(user_data_fields[i].udf_value_desc); + dynamic_hf[i].hfinfo.name = g_strdup(user_data_fields[i].udf_value_desc); + dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("nm.user_data.%s.%s", user_data_fields[i].udf_name, user_data_fields[i].udf_value_desc); + dynamic_hf[i].hfinfo.type = FT_BOOLEAN; + dynamic_hf[i].hfinfo.display = 8 * (user_data_fields[i].udf_length); + // dynamic_hf[i].hfinfo.bitmask = 0; + dynamic_hf[i].hfinfo.blurb = g_strdup(user_data_fields[i].udf_value_desc); } tmp = calc_hf_key(user_data_fields[i]); @@ -295,20 +305,26 @@ user_data_post_update_cb(void) ett_dummy = -1; proto_register_subtree_array(ett, array_length(ett)); - ett_id = g_new(gint, 1); + ett_id = wmem_new(wmem_epan_scope(), gint); *ett_id = ett_dummy; - key = g_new(guint64, 1); + key = wmem_new(wmem_epan_scope(), guint64); *key = calc_ett_key(user_data_fields[i].udf_offset, user_data_fields[i].udf_length); - g_hash_table_insert(user_data_fields_hash_ett, key, ett_id); + wmem_map_insert(user_data_fields_hash_ett, key, ett_id); } } - proto_register_field_array(proto_udp_nm, hf, num_user_data_fields); + proto_register_field_array(proto_udp_nm, dynamic_hf, dynamic_hf_size); } } +static void +user_data_reset_cb(void) +{ + deregister_user_data(); +} + /********************************** ****** The dissector itself ****** @@ -472,7 +488,7 @@ void proto_register_udp_nm(void) user_data_fields_update_cb, /* update callback */ user_data_fields_free_cb, /* free callback */ user_data_post_update_cb, /* post update callback */ - NULL, /* reset callback */ + user_data_reset_cb, /* reset callback */ user_data_uat_fields); /* UAT field definitions */ prefs_register_uat_preference(udp_nm_module, "udp_nm_user_data_fields", "User Data Field Configuration", diff --git a/epan/epan.c b/epan/epan.c index 3dfcde7c42..fe1f660c94 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -307,13 +307,22 @@ epan_cleanup(void) epan_register_all_handoffs = NULL; dfilter_cleanup(); - proto_cleanup(); - prefs_cleanup(); decode_clear_all(); + + /* + * Note: packet_cleanup() will call registered shutdown routines which + * may be used to deregister dynamically registered protocol fields, + * and prefs_cleanup() will call uat_clear() which also may be used to + * deregister dynamically registered protocol fields. This must be done + * before proto_cleanup() to avoid inconsistency and memory leaks. + */ + packet_cleanup(); + prefs_cleanup(); + proto_cleanup(); + conversation_filters_cleanup(); reassembly_table_cleanup(); tap_cleanup(); - packet_cleanup(); expert_cleanup(); capture_dissector_cleanup(); export_pdu_cleanup(); diff --git a/epan/proto.c b/epan/proto.c index 22b0f4ac88..49960d56e5 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -608,6 +608,7 @@ proto_cleanup_base(void) void proto_cleanup(void) { + proto_free_deregistered_fields(); proto_cleanup_base(); #ifdef HAVE_PLUGINS