diff --git a/epan/capture_dissectors.c b/epan/capture_dissectors.c index ed529476db..a5e2920abc 100644 --- a/epan/capture_dissectors.c +++ b/epan/capture_dissectors.c @@ -125,9 +125,7 @@ void capture_dissector_add_uint(const char *name, const uint32_t pattern, captur /* Make sure table exists */ sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name ); if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: Subdissector \"%s\" not found in capture_dissector_tables\n", name); - if (wireshark_abort_on_dissector_bug) - abort(); + ws_dissector_oops("Subdissector \"%s\" not found in capture_dissector_tables\n", name); return; } diff --git a/epan/conversation.c b/epan/conversation.c index ea85a30ea9..3604dc1685 100644 --- a/epan/conversation.c +++ b/epan/conversation.c @@ -92,7 +92,9 @@ enum { DEINTD_ENDP_EXACT_IDX, DEINTD_EXACT_IDX_COUNT, DEINTD_ADDRS_IDX_COUNT = DEINTD_PORT2_IDX, - DEINTD_ENDP_NO_PORTS_IDX = DEINTD_PORT1_IDX + DEINTD_ENDP_NO_PORTS_IDX = DEINTD_PORT1_IDX, + DEINTD_NO_PORT2_IDX_COUNT = DEINTD_EXACT_IDX_COUNT, + DEINTD_NO_ADDR2_PORT2_IDX_COUNT = DEINTD_ENDP_EXACT_IDX }; /* Names for conversation_element_type values. */ @@ -153,6 +155,16 @@ static wmem_map_t *conversation_hashtable_exact_addr_port_anc = NULL; */ static wmem_map_t *conversation_hashtable_exact_addr_anc = NULL; +/* + * Hash table for conversations with one wildcard port, and an anchor + */ +static wmem_map_t *conversation_hashtable_no_port2_anc = NULL; + +/* + * Hash table for conversations with one wildcard address and port, and an anchor. + */ +static wmem_map_t *conversation_hashtable_no_addr2_or_port2_anc; + /* * Hash table for deinterlacing conversations (typically L1 or L2) */ @@ -689,6 +701,33 @@ conversation_init(void) wmem_map_insert(conversation_hashtable_element_list, wmem_strdup(wmem_epan_scope(), addrs_anc_map_key), conversation_hashtable_exact_addr_anc); + conversation_element_t no_port2_elements_anc[DEINTD_NO_PORT2_IDX_COUNT] = { + { CE_ADDRESS, .addr_val = ADDRESS_INIT_NONE }, + { CE_ADDRESS, .addr_val = ADDRESS_INIT_NONE }, + { CE_PORT, .port_val = 0 }, + { CE_UINT, .uint_val = 0 }, + { CE_CONVERSATION_TYPE, .conversation_type_val = CONVERSATION_NONE } + }; + char *no_port2_anc_map_key = conversation_element_list_name(wmem_epan_scope(), no_port2_elements_anc); + conversation_hashtable_no_port2_anc = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), + conversation_hash_element_list, + conversation_match_element_list); + wmem_map_insert(conversation_hashtable_element_list, wmem_strdup(wmem_epan_scope(), no_port2_anc_map_key), + conversation_hashtable_no_port2_anc); + + conversation_element_t no_addr2_or_port2_elements_anc[DEINTD_NO_ADDR2_PORT2_IDX_COUNT] = { + { CE_ADDRESS, .addr_val = ADDRESS_INIT_NONE }, + { CE_PORT, .port_val = 0 }, + { CE_UINT, .uint_val = 0 }, + { CE_CONVERSATION_TYPE, .conversation_type_val = CONVERSATION_NONE } + }; + char *no_addr2_or_port2_anc_map_key = conversation_element_list_name(wmem_epan_scope(), no_addr2_or_port2_elements_anc); + conversation_hashtable_no_addr2_or_port2_anc = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), + conversation_hash_element_list, + conversation_match_element_list); + wmem_map_insert(conversation_hashtable_element_list, wmem_strdup(wmem_epan_scope(), no_addr2_or_port2_anc_map_key), + conversation_hashtable_no_addr2_or_port2_anc); + } /** @@ -1192,6 +1231,44 @@ conversation_new_deinterlaced(const uint32_t setup_frame, const address *addr1, return conversation; } + else if (options & NO_PORT2) { + conversation_element_t *new_key = wmem_alloc(wmem_file_scope(), sizeof(conversation_element_t) * (DEINTD_EXACT_IDX_COUNT+1)); + + new_key[DEINTD_ADDR1_IDX].type = CE_ADDRESS; + if (addr1 != NULL) { + copy_address_wmem(wmem_file_scope(), &new_key[DEINTD_ADDR1_IDX].addr_val, addr1); + } + else { + clear_address(&new_key[DEINTD_ADDR1_IDX].addr_val); + } + + new_key[DEINTD_ADDR2_IDX].type = CE_ADDRESS; + if (addr2 != NULL) { + copy_address_wmem(wmem_file_scope(), &new_key[DEINTD_ADDR2_IDX].addr_val, addr2); + } + else { + clear_address(&new_key[DEINTD_ADDR2_IDX].addr_val); + } + + new_key[DEINTD_PORT1_IDX].type = CE_PORT; + new_key[DEINTD_PORT1_IDX].port_val = port1; + + new_key[DEINTD_PORT1_IDX + 1].type = CE_UINT; + new_key[DEINTD_PORT1_IDX + 1].uint_val = anchor; + + new_key[DEINTD_PORT1_IDX + 2].type = CE_CONVERSATION_TYPE; + new_key[DEINTD_PORT1_IDX + 2].conversation_type_val = ctype; + + // set the options and key pointer + conversation->options = options; + conversation->key_ptr = new_key; + + new_index++; + + conversation_insert_into_hashtable(conversation_hashtable_exact_addr_port_anc, conversation); + + return conversation; + } else { conversation_element_t *new_key = wmem_alloc(wmem_file_scope(), sizeof(conversation_element_t) * (DEINTD_EXACT_IDX_COUNT+2)); @@ -1503,6 +1580,25 @@ conversation_lookup_no_anc_anc(const uint32_t frame_num, const address *addr1, return conversation_lookup_hashtable(conversation_hashtable_exact_addr_anc, frame_num, key); } +/* + * Search a particular hash table for a conversation with the specified + * {addr1, port1, addr2, anchor} and set up before frame_num. + */ +static conversation_t * +conversation_lookup_no_port2_anc(const uint32_t frame_num, const address *addr1, const uint32_t port1, + const address *addr2, const conversation_type ctype, + const uint32_t anchor) +{ + conversation_element_t key[DEINTD_NO_PORT2_IDX_COUNT] = { + { CE_ADDRESS, .addr_val = *addr1 }, + { CE_ADDRESS, .addr_val = *addr2 }, + { CE_PORT, .port_val = port1 }, + { CE_UINT, .uint_val = anchor }, + { CE_CONVERSATION_TYPE, .conversation_type_val = ctype }, + }; + return conversation_lookup_hashtable(conversation_hashtable_exact_addr_port_anc, frame_num, key); +} + /* * Search a particular hash table for a conversation with the specified * {addr1, addr2, key1, key2, key3} and set up before frame_num. @@ -1963,6 +2059,20 @@ find_conversation_deinterlaced(const uint32_t frame_num, const address *addr_a, } } + else if(options & NO_PORT_B) { /* typically : protocols over UDP */ + conversation = conversation_lookup_no_port2_anc(frame_num, addr_a, port_a, addr_b, ctype, anchor); + other_conv = conversation_lookup_no_port2_anc(frame_num, addr_b, port_b, addr_a, ctype, anchor); + if (other_conv != NULL) { + if (conversation != NULL) { + if(other_conv->conv_index > conversation->conv_index) { + conversation = other_conv; + } + } + else { + conversation = other_conv; + } + } + } else { /* typically : IP protocols */ if (!(options & NO_ANC)) { conversation = conversation_lookup_no_ports_anc(frame_num, addr_a, addr_b, ctype, anchor); @@ -2253,7 +2363,6 @@ conversation_t * find_conversation_strat(const packet_info *pinfo, const conversation_type ctype, const unsigned options) { conversation_t *conv=NULL; - /* deinterlacing is only supported for the Ethernet wtap for now */ if( (pinfo->pseudo_header != NULL) && (pinfo->rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_ETHERNET) @@ -2266,7 +2375,6 @@ find_conversation_strat(const packet_info *pinfo, const conversation_type ctype, else { conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, ctype, pinfo->srcport, pinfo->destport, options); } - return conv; } diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index 935d5590a7..9a521ed035 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -6616,6 +6616,9 @@ static int hf_ieee80211_rsn_cap_mfpr; static int hf_ieee80211_rsn_cap_mfpc; static int hf_ieee80211_rsn_cap_jmr; static int hf_ieee80211_rsn_cap_peerkey; +static int hf_ieee80211_rsn_cap_spp_amsdu_cap; +static int hf_ieee80211_rsn_cap_spp_amsdu_req; +static int hf_ieee80211_rsn_cap_pbac; static int hf_ieee80211_rsn_cap_extended_key_id_iaf; static int hf_ieee80211_rsn_cap_ocvc; static int hf_ieee80211_rsn_pmkid_count; @@ -22054,6 +22057,9 @@ dissect_rsn_ie(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, &hf_ieee80211_rsn_cap_mfpc, &hf_ieee80211_rsn_cap_jmr, &hf_ieee80211_rsn_cap_peerkey, + &hf_ieee80211_rsn_cap_spp_amsdu_cap, + &hf_ieee80211_rsn_cap_spp_amsdu_req, + &hf_ieee80211_rsn_cap_pbac, &hf_ieee80211_rsn_cap_extended_key_id_iaf, &hf_ieee80211_rsn_cap_ocvc, NULL @@ -48933,22 +48939,37 @@ proto_register_ieee80211(void) {&hf_ieee80211_rsn_cap_mfpr, {"Management Frame Protection Required", "wlan.rsn.capabilities.mfpr", - FT_BOOLEAN, 16, NULL, 0x0040, + FT_BOOLEAN, 16, TFS(&tfs_required_not_required), 0x0040, NULL, HFILL }}, {&hf_ieee80211_rsn_cap_mfpc, {"Management Frame Protection Capable", "wlan.rsn.capabilities.mfpc", - FT_BOOLEAN, 16, NULL, 0x0080, + FT_BOOLEAN, 16, TFS(&tfs_capable_not_capable), 0x0080, NULL, HFILL }}, {&hf_ieee80211_rsn_cap_jmr, {"Joint Multi-band RSNA", "wlan.rsn.capabilities.jmr", - FT_BOOLEAN, 16, NULL, 0x0100, + FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0100, NULL, HFILL }}, {&hf_ieee80211_rsn_cap_peerkey, {"PeerKey Enabled", "wlan.rsn.capabilities.peerkey", - FT_BOOLEAN, 16, NULL, 0x0200, + FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0200, + NULL, HFILL }}, + + {&hf_ieee80211_rsn_cap_spp_amsdu_cap, + {"SPP A-MSDU Capable", "wlan.rsn.capabilities.spp_amsdu_cap", + FT_BOOLEAN, 16, TFS(&tfs_capable_not_capable), 0x0400, + NULL, HFILL }}, + + {&hf_ieee80211_rsn_cap_spp_amsdu_req, + {"SPP A-MSDU Required", "wlan.rsn.capabilities.spp_amsdu_req", + FT_BOOLEAN, 16, TFS(&tfs_required_not_required), 0x0800, + NULL, HFILL }}, + + {&hf_ieee80211_rsn_cap_pbac, + {"PBAC (protected block ack agreement capable)", "wlan.rsn.capabilities.pbac", + FT_BOOLEAN, 16, TFS(&tfs_capable_not_capable), 0x1000, NULL, HFILL }}, {&hf_ieee80211_rsn_cap_extended_key_id_iaf, @@ -48958,7 +48979,7 @@ proto_register_ieee80211(void) {&hf_ieee80211_rsn_cap_ocvc, {"OCVC", "wlan.rsn.capabilities.ocvc", - FT_BOOLEAN, 16, NULL, 0x4000, + FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x4000, NULL, HFILL }}, {&hf_ieee80211_rsn_pmkid_count, diff --git a/epan/dissectors/packet-oran.c b/epan/dissectors/packet-oran.c index d5af410c8a..76a3266a61 100644 --- a/epan/dissectors/packet-oran.c +++ b/epan/dissectors/packet-oran.c @@ -1,6 +1,8 @@ /* packet-oran.c * Routines for O-RAN fronthaul UC-plane dissection * Copyright 2020, Jan Schiefer, Keysight Technologies, Inc. + * Copyright 2020- Martin Mathieson + * * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -868,8 +870,6 @@ static AllowedCTs_t ext_cts[HIGHEST_EXTTYPE] = { { false, false, false, true, false, false, false }, // SE 25 (5) { false, false, false, true, false, false, false }, // SE 26 (5) { false, false, false, true, false, false, false }, // SE 27 (5) - - }; static bool se_allowed_in_st(unsigned se, unsigned ct) @@ -896,6 +896,7 @@ static bool se_allowed_in_st(unsigned se, unsigned ct) /************************************************************************************/ +/* Table 7.7.1.2-2 */ static const value_string bfw_comp_headers_iq_width[] = { {0, "I and Q are 16 bits wide"}, {1, "I and Q are 1 bit wide"}, @@ -1008,6 +1009,7 @@ static const value_string lbtTrafficClass_vals[] = { {0, NULL} }; +/* 7.5.3.22 */ static const value_string lbtPdschRes_vals[] = { {0, "not sensing – indicates that the O-RU is transmitting data"}, {1, "currently sensing – indicates the O-RU has not yet acquired the channel"}, @@ -1016,12 +1018,14 @@ static const value_string lbtPdschRes_vals[] = { {0, NULL} }; +/* Table 7.5.2.15-3 */ static const value_string ci_comp_opt_vals[] = { {0, "compression per UE, one ciCompParam exists before the I/Q value of each UE"}, {1, "compression per PRB, one ciCompParam exists before the I/Q value of each PRB"}, {0, NULL} }; +/* 7.5.2.17 */ static const range_string cmd_scope_vals[] = { {0, 0, "ARRAY-COMMAND"}, {1, 1, "CARRIER-COMMAND"}, @@ -1088,6 +1092,7 @@ static const value_string prg_size_st5_vals[] = { { 0, NULL} }; +/* 7.7.21.3.2 */ static const value_string prg_size_st6_vals[] = { { 0, "if ciPrbGroupSize is 2 or 4, then ciPrbGroupSize, else WIDEBAND"}, { 1, "Precoding resource block group size as WIDEBAND"}, @@ -1096,12 +1101,14 @@ static const value_string prg_size_st6_vals[] = { { 0, NULL} }; +/* 7.7.24.4 */ static const value_string alpn_per_sym_vals[] = { { 0, "report one allocated IPN value per all allocated symbols with DMRS"}, { 1, "report one allocated IPN value per group of consecutive DMRS symbols"}, { 0, NULL} }; +/* 7.7.24.5 */ static const value_string ant_dmrs_snr_vals[] = { { 0, "O-RU shall not report the MEAS_ANT_DMRS_SNR"}, { 1, "O-RU shall report the MEAS_ANT_DMRS_SNR"}, diff --git a/epan/dissectors/packet-signal-pdu.c b/epan/dissectors/packet-signal-pdu.c index 0d5dba57fc..539566a80b 100644 --- a/epan/dissectors/packet-signal-pdu.c +++ b/epan/dissectors/packet-signal-pdu.c @@ -47,6 +47,7 @@ #define SPDU_NAME "Signal PDU" #define SPDU_NAME_LONG "Signal PDU" #define SPDU_NAME_FILTER "signal_pdu" +#define SPDU_NAME_SIGNAL_PREFIX "signal_pdu.signals" /*** Configuration ***/ @@ -848,21 +849,25 @@ deregister_user_data_hfarray(hf_register_info **hf_array, unsigned *number_of_en hf_register_info *dynamic_hf = *hf_array; if (dynamic_hf != NULL) { - /* Unregister all fields */ + for (unsigned i = 0; i < dynamic_hf_size; i++) { + if (dynamic_hf[i].p_id != NULL && dynamic_hf[i].hfinfo.strings != NULL) { + /* Workaround: do not let proto_free_field_strings (proto.c) free the hfinfo.strings as this fails. */ + /* Since not all value_names might be used for an hf, we need to free ourselves anyhow. */ + dynamic_hf[i].hfinfo.strings = NULL; + } + } + + proto_deregister_all_fields_with_prefix(proto_signal_pdu, SPDU_NAME_SIGNAL_PREFIX); + proto_free_deregistered_fields(); + for (unsigned i = 0; i < dynamic_hf_size; i++) { if (dynamic_hf[i].p_id != NULL) { - if (*(dynamic_hf[i].p_id) > 0) { - proto_deregister_field(proto_signal_pdu, *(dynamic_hf[i].p_id)); - } g_free(dynamic_hf[i].p_id); dynamic_hf[i].p_id = NULL; - - /* workaround since the proto.c proto_free_field_strings would double free this... */ - dynamic_hf[i].hfinfo.strings = NULL; } } + g_free(dynamic_hf); - proto_add_deregistered_data(dynamic_hf); *hf_array = NULL; *number_of_entries = 0; } @@ -896,34 +901,34 @@ create_hf_entry(hf_register_info *dynamic_hf, unsigned i, uint32_t id, uint32_t switch (hf_type) { case HF_TYPE_RAW: dynamic_hf[i].hfinfo.name = ws_strdup_printf("%s_raw", name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_raw", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_raw", SPDU_NAME_SIGNAL_PREFIX, filter_string); break; case HF_TYPE_AGG_SUM: dynamic_hf[i].hfinfo.name = ws_strdup_printf("%s_sum", name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_sum", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_sum", SPDU_NAME_SIGNAL_PREFIX, filter_string); break; case HF_TYPE_AGG_AVG: dynamic_hf[i].hfinfo.name = ws_strdup_printf("%s_avg", name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_avg", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_avg", SPDU_NAME_SIGNAL_PREFIX, filter_string); break; case HF_TYPE_AGG_INT: dynamic_hf[i].hfinfo.name = ws_strdup_printf("%s_int", name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_int", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_int", SPDU_NAME_SIGNAL_PREFIX, filter_string); break; case HF_TYPE_BASE: dynamic_hf[i].hfinfo.name = ws_strdup(name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s", SPDU_NAME_SIGNAL_PREFIX, filter_string); break; case HF_TYPE_NONE: default: /* we bail out but have set hf_id to 0 before */ dynamic_hf[i].hfinfo.name = ws_strdup_printf("%s_none", name); - dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_none", SPDU_NAME_FILTER, filter_string); + dynamic_hf[i].hfinfo.abbrev = ws_strdup_printf("%s.%s_none", SPDU_NAME_SIGNAL_PREFIX, filter_string); return hf_id; } dynamic_hf[i].hfinfo.bitmask = 0; diff --git a/epan/dissectors/packet-socketcan.c b/epan/dissectors/packet-socketcan.c index 30d1ba7072..70893424fb 100644 --- a/epan/dissectors/packet-socketcan.c +++ b/epan/dissectors/packet-socketcan.c @@ -584,26 +584,25 @@ dissect_socketcan_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, un /* CAN XL: check for min/max data length */ if (tvb_reported_length(tvb) >= 13 && tvb_reported_length(tvb) <= 2060) { can_packet_type = PACKET_TYPE_CAN_XL; + } else { + /* invalid CAN XL frame (expert info) */ + return tvb_captured_length(tvb); } - } - else if (tvb_reported_length(tvb) >= 8) { + } else { /* CAN CC/FD */ - if ((canfd_flags & CANFD_FDF) || tvb_reported_length(tvb) > 16) { - /* CAN FD: check for max data length - * - * XXX - There's no "correct" way to detect a CAN-FD SocketCAN packet. - * The FD Flag, contrary to the XL Flag, is not always set, so we have - * to implement a heuristic. If the length is too big for a Classical - * CAN packet, we arbitrarly decide it's CAN-FD. This will not detect - * CAN-FD packets with DLC 0 through 8, but also misdetect any Classical - * CAN packet with extra payload as CAN-FD. - */ - if (tvb_reported_length(tvb) <= 72) { + if (tvb_reported_length(tvb) == 72 || (canfd_flags & CANFD_FDF)) { + /* CAN FD: check for min/max data length */ + if (tvb_reported_length(tvb) >= 8 && tvb_reported_length(tvb) <= 72) { can_packet_type = PACKET_TYPE_CAN_FD; + } else { + /* invalid CAN FD frame (expert info) */ + return tvb_captured_length(tvb); } - } - else { + } else if (tvb_reported_length(tvb) >= 8 && tvb_reported_length(tvb) <= 16) { can_packet_type = PACKET_TYPE_CAN; + } else { + /* invalid CAN CC frame (expert info) */ + return tvb_captured_length(tvb); } } } diff --git a/epan/dissectors/packet-someip.c b/epan/dissectors/packet-someip.c index 6cbb2e5a52..c2aca53c32 100644 --- a/epan/dissectors/packet-someip.c +++ b/epan/dissectors/packet-someip.c @@ -50,7 +50,7 @@ #define SOMEIP_NAME "SOME/IP" #define SOMEIP_NAME_LONG "SOME/IP Protocol" #define SOMEIP_NAME_FILTER "someip" -#define SOMEIP_NAME_PREFIX "someip.payload" +#define SOMEIP_NAME_PREFIX "someip.payload.data" #define SOMEIP_NAME_LONG_MULTIPLE "SOME/IP Protocol (Multiple Payloads)" #define SOMEIP_NAME_LONG_BROKEN "SOME/IP: Incomplete headers!" @@ -2246,15 +2246,15 @@ post_update_someip_parameter_typedef_list_cb(void) { static void deregister_dynamic_hf_data(hf_register_info **hf_array, unsigned *hf_size) { if (*hf_array) { - /* Unregister all fields used before */ + proto_deregister_all_fields_with_prefix(proto_someip, SOMEIP_NAME_PREFIX); + proto_free_deregistered_fields(); for (unsigned i = 0; i < *hf_size; i++) { if ((*hf_array)[i].p_id != NULL) { - proto_deregister_field(proto_someip, *((*hf_array)[i].p_id)); g_free((*hf_array)[i].p_id); (*hf_array)[i].p_id = NULL; } } - proto_add_deregistered_data(*hf_array); + g_free(*hf_array); *hf_array = NULL; *hf_size = 0; } diff --git a/epan/epan.c b/epan/epan.c index e710c478c6..5fe75b7dbf 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -11,6 +11,8 @@ #include "epan.h" #include +#include +#include #include @@ -118,6 +120,19 @@ static wmem_allocator_t *pinfo_pool_cache; bool wireshark_abort_on_dissector_bug; bool wireshark_abort_on_too_many_items; +void +ws_dissector_bug(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + + if (wireshark_abort_on_dissector_bug) + abort(); +} + #ifdef HAVE_PLUGINS /* Used for bookkeeping, includes all libwireshark plugin types (dissector, tap, epan). */ static plugins_t *libwireshark_plugins; diff --git a/epan/epan.h b/epan/epan.h index be9f5df238..96f615f27b 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -27,6 +27,17 @@ extern "C" { extern bool wireshark_abort_on_dissector_bug; extern bool wireshark_abort_on_too_many_items; +/** Report a dissector bug (and optionally abort). + @param format printf like format string + @param ... printf like parameters */ +WS_DLL_PUBLIC void ws_dissector_bug(const char *format, ...) + G_GNUC_PRINTF(1,2); + +/** Report a dissector OOPS (and optionally abort). + @param format printf like format string *literal* + @param ... printf like parameters */ +#define ws_dissector_oops(_fmt, ...) ws_dissector_bug("OOPS: " _fmt, __VA_ARGS__) + typedef struct epan_dissect epan_dissect_t; struct epan_dfilter; diff --git a/epan/packet.c b/epan/packet.c index c9ead50204..7ba8ea2151 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -1207,35 +1207,41 @@ dissector_add_uint_sanity_check(const char *name, uint32_t pattern, dissector_ha } #endif -/* Add an entry to a uint dissector table. */ -void -dissector_add_uint(const char *name, const uint32_t pattern, dissector_handle_t handle) +/* Get and check subdissector table and handle + * @return true if subdissector and handle exist */ +static bool +dissector_get_table_checked(const char *name, dissector_handle_t handle, dissector_table_t *sub_dissectors) { - dissector_table_t sub_dissectors; - dtbl_entry_t *dtbl_entry; - - sub_dissectors = find_dissector_table(name); + *sub_dissectors = find_dissector_table(name); /* * Make sure the handle and the dissector table exist. */ if (handle == NULL) { - fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n", + ws_dissector_oops("handle to register \"%s\" to doesn't exist\n", name); - if (wireshark_abort_on_dissector_bug) - abort(); - return; + return false; } - if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n", - name); - fprintf(stderr, "Protocol being registered is \"%s\"\n", - proto_get_protocol_long_name(handle->protocol)); - if (wireshark_abort_on_dissector_bug) - abort(); - return; + if (*sub_dissectors == NULL) { + ws_dissector_oops("dissector table \"%s\" doesn't exist\n" + "Protocol being registered is \"%s\"\n", + name, proto_get_protocol_long_name(handle->protocol)); + return false; } + return true; +} + +/* Add an entry to a uint dissector table. */ +void +dissector_add_uint(const char *name, const uint32_t pattern, dissector_handle_t handle) +{ + dissector_table_t sub_dissectors; + dtbl_entry_t *dtbl_entry; + + if (!dissector_get_table_checked(name, handle, &sub_dissectors)) + return; + switch (sub_dissectors->type) { case FT_UINT8: @@ -1746,29 +1752,12 @@ void dissector_add_string(const char *name, const char *pattern, dissector_handle_t handle) { - dissector_table_t sub_dissectors = find_dissector_table(name); + dissector_table_t sub_dissectors; dtbl_entry_t *dtbl_entry; char *key; - /* - * Make sure the handle and the dissector table exist. - */ - if (handle == NULL) { - fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n", - name); - if (wireshark_abort_on_dissector_bug) - abort(); - return; - } - if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n", - name); - fprintf(stderr, "Protocol being registered is \"%s\"\n", - proto_get_protocol_long_name(handle->protocol)); - if (wireshark_abort_on_dissector_bug) - abort(); + if (!dissector_get_table_checked(name, handle, &sub_dissectors)) return; - } switch (sub_dissectors->type) { @@ -2028,28 +2017,11 @@ dissector_get_default_string_handle(const char *name, const char *string) /* Add an entry to a "custom" dissector table. */ void dissector_add_custom_table_handle(const char *name, void *pattern, dissector_handle_t handle) { - dissector_table_t sub_dissectors = find_dissector_table(name); + dissector_table_t sub_dissectors; dtbl_entry_t *dtbl_entry; - /* - * Make sure the handle and the dissector table exist. - */ - if (handle == NULL) { - fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n", - name); - if (wireshark_abort_on_dissector_bug) - abort(); - return; - } - if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n", - name); - fprintf(stderr, "Protocol being registered is \"%s\"\n", - proto_get_protocol_long_name(handle->protocol)); - if (wireshark_abort_on_dissector_bug) - abort(); + if (!dissector_get_table_checked(name, handle, &sub_dissectors)) return; - } ws_assert(sub_dissectors->type == FT_BYTES); @@ -2085,27 +2057,8 @@ void dissector_add_guid(const char *name, guid_key* guid_val, dissector_handle_t dissector_table_t sub_dissectors; dtbl_entry_t *dtbl_entry; - sub_dissectors = find_dissector_table(name); - - /* - * Make sure the handle and the dissector table exist. - */ - if (handle == NULL) { - fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n", - name); - if (wireshark_abort_on_dissector_bug) - abort(); - return; - } - if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n", - name); - fprintf(stderr, "Protocol being registered is \"%s\"\n", - proto_get_protocol_long_name(handle->protocol)); - if (wireshark_abort_on_dissector_bug) - abort(); + if (!dissector_get_table_checked(name, handle, &sub_dissectors)) return; - } if (sub_dissectors->type != FT_GUID) { ws_assert_not_reached(); @@ -2278,22 +2231,12 @@ packet_all_tables_sort_handles(void) void dissector_add_for_decode_as(const char *name, dissector_handle_t handle) { - dissector_table_t sub_dissectors = find_dissector_table(name); + dissector_table_t sub_dissectors; GSList *entry; dissector_handle_t dup_handle; - /* - * Make sure the dissector table exists. - */ - if (sub_dissectors == NULL) { - fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n", - name); - fprintf(stderr, "Protocol being registered is \"%s\"\n", - proto_get_protocol_long_name(handle->protocol)); - if (wireshark_abort_on_dissector_bug) - abort(); + if (!dissector_get_table_checked(name, handle, &sub_dissectors)) return; - } /* * Make sure it supports Decode As. @@ -2304,12 +2247,10 @@ dissector_add_for_decode_as(const char *name, dissector_handle_t handle) dissector_name = dissector_handle_get_dissector_name(handle); if (dissector_name == NULL) dissector_name = "(anonymous)"; - fprintf(stderr, "Registering dissector %s for protocol %s in dissector table %s, which doesn't support Decode As\n", + ws_dissector_bug("Registering dissector %s for protocol %s in dissector table %s, which doesn't support Decode As\n", dissector_name, proto_get_protocol_short_name(handle->protocol), name); - if (wireshark_abort_on_dissector_bug) - abort(); return; } @@ -2356,12 +2297,10 @@ dissector_add_for_decode_as(const char *name, dissector_handle_t handle) dup_dissector_name = dissector_handle_get_dissector_name(dup_handle); if (dup_dissector_name == NULL) dup_dissector_name = "(anonymous)"; - fprintf(stderr, "Dissectors %s and %s in dissector table %s have the same description %s\n", + ws_dissector_bug("Dissectors %s and %s in dissector table %s have the same description %s\n", dissector_name ? dissector_name : "(anonymous)", dup_dissector_name, name, handle->description); - if (wireshark_abort_on_dissector_bug) - abort(); } } } @@ -2387,12 +2326,10 @@ dissector_add_for_decode_as(const char *name, dissector_handle_t handle) dup_dissector_name = "(anonymous)"; fprintf(stderr, "Dissector for %s is anonymous", proto_get_protocol_short_name(dup_handle->protocol)); } - fprintf(stderr, "Dissectors %s and %s in dissector table %s would have the same Decode As preference\n", + ws_dissector_bug("Dissectors %s and %s in dissector table %s would have the same Decode As preference\n", dissector_name ? dissector_name : "(anonymous)", dup_dissector_name, name); - if (wireshark_abort_on_dissector_bug) - abort(); } } } @@ -3700,9 +3637,7 @@ call_dissector_with_data(dissector_handle_t handle, tvbuff_t *tvb, * The protocol was disabled, or the dissector rejected * it. Just dissect this packet as data. */ - DISSECTOR_ASSERT(data_handle->protocol != NULL); - call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL); - return tvb_captured_length(tvb); + return call_data_dissector(tvb, pinfo, tree); } return ret; } @@ -3717,6 +3652,7 @@ call_dissector(dissector_handle_t handle, tvbuff_t *tvb, int call_data_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + DISSECTOR_ASSERT(data_handle->protocol != NULL); return call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL); } diff --git a/epan/packet.h b/epan/packet.h index ed6247d642..dcab598859 100644 --- a/epan/packet.h +++ b/epan/packet.h @@ -42,7 +42,7 @@ extern "C" { ((unsigned)(offset) + (unsigned)(len) > (unsigned)(offset) && \ (unsigned)(offset) + (unsigned)(len) <= (unsigned)(captured_len)) -/* 0 is case insensitive for backwards compatibility with tables that +/* 0 is case sensitive for backwards compatibility with tables that * used false or BASE_NONE for case sensitive, which was the default. */ #define STRING_CASE_SENSITIVE 0 diff --git a/epan/proto.c b/epan/proto.c index 5e282a8f05..e797828ea6 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -8887,6 +8887,33 @@ proto_deregister_field (const int parent, int hf_id) } } +/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */ +void +proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix) +{ + header_field_info *hfinfo; + protocol_t *proto; + + g_free(last_field_name); + last_field_name = NULL; + + proto = find_protocol_by_id(parent); + if (proto && proto->fields && proto->fields->len > 0) { + guint i = proto->fields->len; + do { + i--; + + hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i); + if (g_str_has_prefix(hfinfo->abbrev, prefix)) { + hfinfo_remove_from_gpa_name_map(hfinfo); + expert_deregister_expertinfo(hfinfo->abbrev); + g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]); + g_ptr_array_remove_index_fast(proto->fields, i); + } + } while (i > 0); + } +} + void proto_add_deregistered_data (void *data) { diff --git a/epan/proto.h b/epan/proto.h index 0d2a27ee86..88d1a5643a 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -2655,6 +2655,13 @@ proto_deregister_field (const int parent, int hf_id); WS_DLL_PUBLIC void proto_add_deregistered_data (void *data); +/** Deregister all registered fields of a protocol that match a prefix. + @param parent the protocol handle from proto_register_protocol() + @prefix a prefix to select which fields to deregister +*/ +WS_DLL_PUBLIC void +proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix); + /** Add a memory slice to be freed when deregistered fields are freed. @param block_size the size of the block @param mem_block a pointer to the block to free */ diff --git a/ui/qt/endpoint_dialog.cpp b/ui/qt/endpoint_dialog.cpp index 16e0bd8d53..8cd254299c 100644 --- a/ui/qt/endpoint_dialog.cpp +++ b/ui/qt/endpoint_dialog.cpp @@ -209,7 +209,20 @@ void EndpointDialog::aggregationToggled(bool checked) return; } - ATapDataModel * atdm = trafficTab()->dataModelForTabIndex(1); + // Defaults to 0 but we can't reach this place if IPv4 is not selected anyway + int protoTabIndex = 0; + + // Identify which tab number corresponds to IPv4 + QList _enabledProtocols = trafficList()->protocols(true); + for (int i=0; i< _enabledProtocols.size(); i++) { + QString protoname = proto_get_protocol_short_name(find_protocol_by_id(_enabledProtocols.at(i))) ; + if("IPv4" == protoname) { + protoTabIndex = i; + break; + } + } + + ATapDataModel * atdm = trafficTab()->dataModelForTabIndex(protoTabIndex); if(atdm) { atdm->updateFlags(checked); } diff --git a/ui/qt/traffic_table_dialog.cpp b/ui/qt/traffic_table_dialog.cpp index 085a73c8de..2c280abbbd 100644 --- a/ui/qt/traffic_table_dialog.cpp +++ b/ui/qt/traffic_table_dialog.cpp @@ -135,7 +135,20 @@ void TrafficTableDialog::aggregationSummaryOnlyCheckBoxToggled(bool checked) return; } - ATapDataModel * atdm = trafficTab()->dataModelForTabIndex(1); + // Defaults to 0 but we can't reach this place if IPv4 is not selected anyway + int protoTabIndex = 0; + + // Identify which tab number corresponds to IPv4 + QList _enabledProtocols = trafficList()->protocols(true); + for (int i=0; i< _enabledProtocols.size(); i++) { + QString protoname = proto_get_protocol_short_name(find_protocol_by_id(_enabledProtocols.at(i))) ; + if("IPv4" == protoname) { + protoTabIndex = i; + break; + } + } + + ATapDataModel * atdm = trafficTab()->dataModelForTabIndex(protoTabIndex); if(atdm) { atdm->updateFlags(checked); }