diff --git a/capture/capture-pcap-util.c b/capture/capture-pcap-util.c index 8e164b1d72..5f5c38722d 100644 --- a/capture/capture-pcap-util.c +++ b/capture/capture-pcap-util.c @@ -1124,7 +1124,6 @@ static GList* get_pcap_timestamp_types(pcap_t *pch _U_, char **err_str _U_) { GList *list = NULL; -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE int *types; int ntypes = pcap_list_tstamp_types(pch, &types); @@ -1142,11 +1141,9 @@ get_pcap_timestamp_types(pcap_t *pch _U_, char **err_str _U_) } pcap_free_tstamp_types(types); -#endif return list; } -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION /* * Request high-resolution time stamps. * @@ -1174,6 +1171,11 @@ request_high_resolution_timestamp(pcap_t *pcap_h) * call it. We have to, instead, use dlopen() to load * libpcap, and dlsym() to find a pointer to pcap_set_tstamp_precision(), * and if we find the pointer, call it. + * + * XXX - This shouldn't be needed anymore; we don't support running + * on any release older than macOS 11, and starting with macOS 11 the + * system libpcap is based on libpcap 1.5 or later and has + * pcap_set_tstamp_precision(). */ static bool initialized = false; static int (*p_pcap_set_tstamp_precision)(pcap_t *, int); @@ -1243,8 +1245,6 @@ have_high_resolution_timestamp(pcap_t *pcap_h) #endif /* __APPLE__ */ } -#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ - #ifdef HAVE_BONDING static bool is_linux_bonding_device(const char *ifname) @@ -1503,7 +1503,6 @@ open_capture_device_pcap_create( return NULL; } -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION /* * Try to enable nanosecond-resolution capture; any code * that can read pcapng files must be able to handle @@ -1527,9 +1526,7 @@ open_capture_device_pcap_create( pcap_close(pcap_h); return NULL; } -#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE if (interface_opts->timestamp_type) { status = pcap_set_tstamp_type(pcap_h, interface_opts->timestamp_type_id); /* @@ -1543,7 +1540,6 @@ open_capture_device_pcap_create( return NULL; } } -#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ ws_debug("buffersize %d.", interface_opts->buffer_size); if (interface_opts->buffer_size != 0) { @@ -1584,13 +1580,11 @@ open_capture_device_pcap_create( sizeof *open_status_str); break; -#ifdef HAVE_PCAP_ERROR_PROMISC_PERM_DENIED case PCAP_ERROR_PROMISC_PERM_DENIED: *open_status = CAP_DEVICE_OPEN_ERROR_PROMISC_PERM_DENIED; (void) g_strlcpy(*open_status_str, pcap_geterr(pcap_h), sizeof *open_status_str); break; -#endif case PCAP_ERROR_RFMON_NOTSUP: *open_status = CAP_DEVICE_OPEN_ERROR_RFMON_NOTSUP; @@ -1632,13 +1626,11 @@ open_capture_device_pcap_create( sizeof *open_status_str); break; -#ifdef HAVE_PCAP_WARNING_TSTAMP_TYPE_NOTSUP case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: *open_status = CAP_DEVICE_OPEN_WARNING_TSTAMP_TYPE_NOTSUP; (void) g_strlcpy(*open_status_str, pcap_geterr(pcap_h), sizeof *open_status_str); break; -#endif case PCAP_WARNING: *open_status = CAP_DEVICE_OPEN_WARNING_OTHER; diff --git a/capture/capture-pcap-util.h b/capture/capture-pcap-util.h index c96f0d73ab..5b9575bf4a 100644 --- a/capture/capture-pcap-util.h +++ b/capture/capture-pcap-util.h @@ -52,13 +52,11 @@ bool set_pcap_datalink(pcap_t *pcap_h, int datalink, char *name, char *errmsg, size_t errmsg_len, char *secondary_errmsg, size_t secondary_errmsg_len); -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION /* * Return true if the pcap_t in question is set up for high-precision * time stamps, false otherwise. */ bool have_high_resolution_timestamp(pcap_t *pcap_h); -#endif /* HAVE_PCAP_SET_TSTAMP_PRECISION */ /* * Capture device open status values. diff --git a/capture/capture-wpcap.c b/capture/capture-wpcap.c index cf1f1407a4..661be62a81 100644 --- a/capture/capture-wpcap.c +++ b/capture/capture-wpcap.c @@ -100,7 +100,6 @@ static int (*p_pcap_set_buffer_size)(pcap_t *, int); static int (*p_pcap_activate)(pcap_t *); static const char *(*p_pcap_statustostr)(int); -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE static int (*p_pcap_set_tstamp_type)(pcap_t *, int); static int (*p_pcap_set_tstamp_precision)(pcap_t *, int); static int (*p_pcap_get_tstamp_precision)(pcap_t *); @@ -109,7 +108,6 @@ static void (*p_pcap_free_tstamp_types)(int *); static int (*p_pcap_tstamp_type_name_to_val)(const char *); static const char * (*p_pcap_tstamp_type_val_to_name)(int); static const char * (*p_pcap_tstamp_type_val_to_description)(int); -#endif typedef struct { const char *name; @@ -177,7 +175,6 @@ load_wpcap(void) SYM(pcap_can_set_rfmon, false), SYM(pcap_set_rfmon, false), SYM(pcap_statustostr, false), -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE SYM(pcap_set_tstamp_type, true), SYM(pcap_set_tstamp_precision, true), SYM(pcap_get_tstamp_precision, true), @@ -186,7 +183,6 @@ load_wpcap(void) SYM(pcap_tstamp_type_name_to_val, true), SYM(pcap_tstamp_type_val_to_name, true), SYM(pcap_tstamp_type_val_to_description, true), -#endif { NULL, NULL, false } }; @@ -630,7 +626,6 @@ pcap_statustostr(int a) return p_pcap_statustostr(a); } -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE int pcap_set_tstamp_type(pcap_t *a, int b) { ws_assert(has_npcap); @@ -703,7 +698,6 @@ pcap_tstamp_type_val_to_description(int a) { } return NULL; } -#endif int pcap_datalink_name_to_val(const char *name) diff --git a/cmake/modules/FindPCAP.cmake b/cmake/modules/FindPCAP.cmake index 6837b2592b..5efec9079e 100644 --- a/cmake/modules/FindPCAP.cmake +++ b/cmake/modules/FindPCAP.cmake @@ -107,8 +107,6 @@ endif() # # # libpcap 1.5.0 (2013-11-07) # check_symbol_exists(PCAP_ERROR_PROMISC_PERM_DENIED "pcap/pcap.h" HAVE_PCAP_ERROR_PROMISC_PERM_DENIED) -# # libpcap 1.2.1 (2012-01-01) -# check_symbol_exists(PCAP_WARNING_TSTAMP_TYPE_NOTSUP "pcap/pcap.h" HAVE_PCAP_WARNING_TSTAMP_TYPE_NOTSUP) # # if (NOT HAVE_PCAP_ERROR_PROMISC_PERM_DENIED) # set(${validator_result_var} FALSE PARENT_SCOPE) @@ -234,19 +232,18 @@ if(PCAP_FOUND) set(HAVE_PCAP_OPEN TRUE) set(HAVE_PCAP_SETSAMPLING TRUE) set(HAVE_PCAP_SET_TSTAMP_PRECISION TRUE) - set(HAVE_PCAP_SET_TSTAMP_TYPE TRUE) else(WIN32) # - # Make sure we have at least libpcap 1.0, because we require at - # least libpcap 1.0's APIs. + # Make sure we have at least libpcap 1.5, because we require at + # least libpcap 1.5's APIs. # - # We check whether pcap_create is defined in the pcap header, - # using it as a proxy for all the 1.0 API's. if not, we fail. + # We check whether pcap_set_tstamp_precision is defined in the pcap header, + # using it as a proxy for all the 1.5 API's. if not, we fail. # - check_function_exists( "pcap_create" HAVE_PCAP_CREATE ) - if( NOT HAVE_PCAP_CREATE ) - message(FATAL_ERROR "You need libpcap 1.0 or later") - endif( NOT HAVE_PCAP_CREATE ) + check_function_exists( "pcap_set_tstamp_precision" HAVE_PCAP_SET_TSTAMP_PRECISION ) + if( NOT HAVE_PCAP_SET_TSTAMP_PRECISION ) + message(FATAL_ERROR "You need libpcap 1.5 or later") + endif() # # macOS Sonoma's libpcap includes stub versions of the remote- @@ -320,19 +317,15 @@ if(PCAP_FOUND) endif( HAVE_PCAP_OPEN ) endif() - # This function became available in libpcap release 1.5.1. (2013-12-04) - check_function_exists( "pcap_set_tstamp_precision" HAVE_PCAP_SET_TSTAMP_PRECISION ) - # This function became available in libpcap release 1.2.1. (2012-01-01) - check_function_exists( "pcap_set_tstamp_type" HAVE_PCAP_SET_TSTAMP_TYPE ) # Remote pcap checks if( HAVE_PCAP_OPEN ) set( HAVE_PCAP_REMOTE 1 ) endif() - # libpcap 1.5.0 (2013-11-07) check_symbol_exists(PCAP_ERROR_PROMISC_PERM_DENIED "pcap/pcap.h" HAVE_PCAP_ERROR_PROMISC_PERM_DENIED) - # libpcap 1.2.1 (2012-01-01) - check_symbol_exists(PCAP_WARNING_TSTAMP_TYPE_NOTSUP "pcap/pcap.h" HAVE_PCAP_WARNING_TSTAMP_TYPE_NOTSUP) + if( NOT HAVE_PCAP_ERROR_PROMISC_PERM_DENIED ) + message(FATAL_ERROR "You need libpcap 1.5 or later") + endif() cmake_pop_check_state() endif() diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index a9315730b2..fa346a10eb 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -236,18 +236,6 @@ /* Define to 1 if you have the `pcap_setsampling' function. */ #cmakedefine HAVE_PCAP_SETSAMPLING 1 -/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */ -#cmakedefine HAVE_PCAP_SET_TSTAMP_PRECISION 1 - -/* Define to 1 if you have the `pcap_set_tstamp_type' function. */ -#cmakedefine HAVE_PCAP_SET_TSTAMP_TYPE 1 - -/* Define to 1 if you have the `PCAP_ERROR_PROMISC_PERM_DENIED' symbol. */ -#cmakedefine HAVE_PCAP_ERROR_PROMISC_PERM_DENIED 1 - -/* Define to 1 if you have the `PCAP_WARNING_TSTAMP_TYPE_NOTSUP' symbol. */ -#cmakedefine HAVE_PCAP_WARNING_TSTAMP_TYPE_NOTSUP 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_PWD_H 1 @@ -438,10 +426,9 @@ * The Npcap SDK, as of SDK version 1.04, provides them, so this is * only necessary for building with the WinPcap SDK. * - * WinPcap isn't supported at runtime anymore, but it's possible to build - * with the WinPcap SDK and run with Npcap, so long as this is defined. - * That's what currently happens when cross-compiling with Fedora Linux, - * which includes a MinGW WinPcap package. + * Building against the WinPcap SDK isn't supported anymore, nor is running + * with the WinPcap DLL installed, so needing this is very unlikely, though + * libpcap 1.9.0 or later is not yet required. */ #ifdef HAVE_PCAP_REMOTE #define HAVE_REMOTE diff --git a/dumpcap.c b/dumpcap.c index 16236b831c..2582af6d5a 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -3155,10 +3155,8 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld, if (pcap_src->pcap_h != NULL) { /* we've opened "iface" as a network device */ -#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION /* Find out if we're getting nanosecond-precision time stamps */ pcap_src->ts_nsec = have_high_resolution_timestamp(pcap_src->pcap_h); -#endif #if defined(HAVE_PCAP_SETSAMPLING) if (interface_opts->sampling_method != CAPTURE_SAMP_NONE) { @@ -5949,7 +5947,6 @@ main(int argc, char *argv[]) exit_main(status); } -#ifdef HAVE_PCAP_SET_TSTAMP_TYPE for (j = 0; j < global_capture_opts.ifaces->len; j++) { interface_options *interface_opts; @@ -5962,7 +5959,6 @@ main(int argc, char *argv[]) } } } -#endif /* We're supposed to do a capture, or print the BPF code for a filter. */ diff --git a/epan/dissectors/asn1/cms/packet-cms-template.c b/epan/dissectors/asn1/cms/packet-cms-template.c index c1380f57e0..a3fb9e24fd 100644 --- a/epan/dissectors/asn1/cms/packet-cms-template.c +++ b/epan/dissectors/asn1/cms/packet-cms-template.c @@ -209,4 +209,6 @@ void proto_reg_handoff_cms(void) { dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109", content_info_handle); dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109-zlib", content_info_handle); dissector_add_string("media_type", "application/hgp;encap=cms", content_info_handle); + + dissector_add_string("rfc7468.preeb_label", "CMS", content_info_handle); } diff --git a/epan/dissectors/asn1/its/packet-its-template.c b/epan/dissectors/asn1/its/packet-its-template.c index eae29a0e3e..860be2ab39 100644 --- a/epan/dissectors/asn1/its/packet-its-template.c +++ b/epan/dissectors/asn1/its/packet-its-template.c @@ -1080,7 +1080,7 @@ void proto_register_its(void) #define ITS_TIS_TPG_PROT_VER 1 #define ITS_CPM_PROT_VERv1 1 #define ITS_CPM_PROT_VER 2 -#define ITS_VAM_PROT_VER 2 +#define ITS_VAM_PROT_VER 3 #define ITS_IMZM_PROT_VER 2 void proto_reg_handoff_its(void) diff --git a/epan/dissectors/asn1/ngap/packet-ngap-template.c b/epan/dissectors/asn1/ngap/packet-ngap-template.c index d2ce11e3f7..70d037834a 100644 --- a/epan/dissectors/asn1/ngap/packet-ngap-template.c +++ b/epan/dissectors/asn1/ngap/packet-ngap-template.c @@ -194,6 +194,7 @@ static int ett_ngap_successfulPSCellChangeReportContainer; #include "packet-ngap-ett.c" static expert_field ei_ngap_number_pages_le15; +static expert_field ei_ngap_disable_nrppa_encapsulation; enum{ INITIATING_MESSAGE, @@ -566,6 +567,7 @@ static const enum_val_t ngap_lte_container_vals[] = { /* Global variables */ static range_t *gbl_ngapSctpRange; static bool ngap_dissect_container = true; +static bool ngap_disable_nrppa_encapsulation = false; static int ngap_dissect_target_ng_ran_container_as = NGAP_NG_RAN_CONTAINER_AUTOMATIC; static int ngap_dissect_lte_container_as = NGAP_LTE_CONTAINER_AUTOMATIC; @@ -984,12 +986,18 @@ find_n2_info_content(char *json_data, jsmntok_t *token, const char *n2_info_cont if (!str || strcmp(str, content_id)) return false; str = json_get_string(json_data, n2_info_content_token, "ngapIeType"); - if (str) - *subdissector = dissector_get_string_handle(ngap_n2_ie_type_dissector_table, str); - else if (json_get_double(json_data, n2_info_content_token, "ngapMessageType", &ngap_msg_type)) + if (str) { + if (!strcmp(str, "NRPPA_PDU") && ngap_disable_nrppa_encapsulation) { + *subdissector = nrppa_handle; + } else { + *subdissector = dissector_get_string_handle(ngap_n2_ie_type_dissector_table, str); + } + } else if (json_get_double(json_data, n2_info_content_token, + "ngapMessageType", &ngap_msg_type)) { *subdissector = ngap_handle; - else + } else { *subdissector = NULL; + } return true; } @@ -1100,6 +1108,11 @@ dissect_ngap_media_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi if (subdissector != ngap_handle) { ngap_item = proto_tree_add_item(tree, proto_ngap, tvb, 0, -1, ENC_NA); ngap_tree = proto_item_add_subtree(ngap_item, ett_ngap); + if (ngap_disable_nrppa_encapsulation && subdissector == nrppa_handle) { + expert_add_info_format(pinfo, ngap_item, + &ei_ngap_disable_nrppa_encapsulation, + "Encapsulation of NRPPa in NGAP is disabled"); + } } else { ngap_tree = tree; } @@ -1489,7 +1502,10 @@ void proto_register_ngap(void) { }; static ei_register_info ei[] = { - { &ei_ngap_number_pages_le15, { "ngap.number_pages_le15", PI_MALFORMED, PI_ERROR, "Number of pages should be <=15", EXPFILL }} + { &ei_ngap_number_pages_le15, { "ngap.number_pages_le15", PI_MALFORMED, PI_ERROR, "Number of pages should be <=15", EXPFILL }}, + { &ei_ngap_disable_nrppa_encapsulation, + { "ngap.disable_nrppa_encapsulation", PI_PROTOCOL, PI_CHAT, "Encapsulation of NRPPa in NGAP is disabled", EXPFILL } + } }; module_t *ngap_module; @@ -1524,6 +1540,13 @@ void proto_register_ngap(void) { "Dissect TransparentContainer", "Dissect TransparentContainers that are opaque to NGAP", &ngap_dissect_container); + prefs_register_bool_preference(ngap_module, "disable_nrppa_encapsulation", + "Disable encapsulation of NRPPa in NGAP", + "The standard indicates that NRPPa PDU must " + "be encapsulated in ngap.NRPPa-PDU ASN1 type. " + "However, Huawei AMF use the NRPPa ASN1 type " + "directly.", + &ngap_disable_nrppa_encapsulation); prefs_register_enum_preference(ngap_module, "dissect_target_ng_ran_container_as", "Dissect target NG-RAN container as", "Select whether target NG-RAN container should be decoded automatically" diff --git a/epan/dissectors/packet-bpv7.c b/epan/dissectors/packet-bpv7.c index 85cfeb2ca3..19f431eef9 100644 --- a/epan/dissectors/packet-bpv7.c +++ b/epan/dissectors/packet-bpv7.c @@ -18,6 +18,7 @@ #include #include "packet-bpv7.h" +#include "packet-cbor.h" #include "epan/wscbor.h" #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -2253,37 +2253,6 @@ static int dissect_block_hop_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree return offset; } -static bool btsd_heur_cbor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { - int offset = 0; - volatile int count = 0; - - while ((unsigned)offset < tvb_reported_length(tvb)) { - volatile bool valid = false; - TRY { - valid = wscbor_skip_next_item(pinfo->pool, tvb, &offset); - } - CATCH_BOUNDS_AND_DISSECTOR_ERRORS {} - ENDTRY; - if (!valid) { - break; - } - ++count; - } - - // Anything went wrong with any part of the data - if ((count == 0) || ((unsigned)offset != tvb_reported_length(tvb))) { - return false; - } - - if (count == 1) { - call_dissector(handle_cbor, tvb, pinfo, tree); - } - else { - call_dissector(handle_cborseq, tvb, pinfo, tree); - } - return true; -} - /// Clear state when new file scope is entered static void bp_init(void) { bp_history = wmem_new0(wmem_file_scope(), bp_history_t); @@ -2565,7 +2534,7 @@ void proto_register_bpv7(void) { void proto_reg_handoff_bpv7(void) { const int proto_cbor = proto_get_id_by_filter_name("cbor"); - heur_dissector_add("bpv7.btsd", btsd_heur_cbor, "CBOR in Bundle BTSD", "cbor_bpv7", proto_cbor, HEURISTIC_ENABLE); + heur_dissector_add("bpv7.btsd", cbor_heuristic, "CBOR in Bundle BTSD", "cbor_bpv7", proto_cbor, HEURISTIC_ENABLE); handle_cbor = find_dissector("cbor"); handle_cborseq = find_dissector("cborseq"); diff --git a/epan/dissectors/packet-cbor.c b/epan/dissectors/packet-cbor.c index 11fccd928f..1869a15db9 100644 --- a/epan/dissectors/packet-cbor.c +++ b/epan/dissectors/packet-cbor.c @@ -1,7 +1,7 @@ /* packet-cbor.c - * Routines for Concise Binary Object Representation (CBOR) (RFC 7049) dissection + * Routines for Concise Binary Object Representation (CBOR) (STD 94) dissection * References: - * RFC 7049: https://tools.ietf.org/html/rfc7049 + * RFC 8949: https://tools.ietf.org/html/rfc8949 * RFC 8742: https://tools.ietf.org/html/rfc8742 * * Copyright 2015, Hauke Mehrtens @@ -18,14 +18,20 @@ #include +#include "packet-cbor.h" #include +#include #include #include +#include #include void proto_register_cbor(void); void proto_reg_handoff_cbor(void); +// Protocol preferences and defaults +static bool cbor_dissect_embeded_bstr = false; + static int proto_cbor; static int hf_cbor_item_major_type; @@ -53,7 +59,6 @@ static int hf_cbor_type_byte_string; static int hf_cbor_type_byte_string_indef; static int hf_cbor_type_text_string; static int hf_cbor_type_text_string_indef; -static int hf_cbor_type_tag5; static int hf_cbor_type_tag; static int hf_cbor_type_simple_data5; static int hf_cbor_type_simple_data8; @@ -78,6 +83,7 @@ static expert_field ei_cbor_invalid_minor_type; static expert_field ei_cbor_invalid_element; static expert_field ei_cbor_too_long_length; static expert_field ei_cbor_max_recursion_depth_reached; +static expert_field ei_cbor_embedded_bstr; static dissector_handle_t cbor_handle; static dissector_handle_t cborseq_handle; @@ -140,40 +146,6 @@ static const value_string float_simple_type_vals[] = { }; /* see https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml#tags */ -static const value_string tag32_vals[] = { - { 0, "Standard date/time string" }, - { 1, "Epoch-based date/time" }, - { 2, "Positive bignum" }, - { 3, "Negative bignum" }, - { 4, "Decimal fraction" }, - { 5, "Bigfloat" }, - { 21, "Expected conversion to base64url encoding" }, - { 22, "Expected conversion to base64 encoding" }, - { 23, "Expected conversion to base16 encoding" }, - { 24, "Encoded CBOR data item" }, - { 25, "reference the nth previously seen string" }, - { 26, "Serialised Perl object with classname and constructor arguments" }, - { 27, "Serialised language-independent object with type name and constructor arguments" }, - { 28, "mark value as (potentially) shared" }, - { 29, "reference nth marked value" }, - { 30, "Rational number" }, - { 32, "URI" }, - { 33, "base64url" }, - { 34, "base64" }, - { 35, "Regular expression" }, - { 36, "MIME message" }, - { 37, "Binary UUID" }, - { 38, "Language-tagged string" }, - { 39, "Identifier" }, - { 256, "mark value as having string references" }, - { 257, "Binary MIME message" }, - { 264, "Decimal fraction with arbitrary exponent" }, - { 265, "Bigfloat with arbitrary exponent" }, - { 22098, "hint that indicates an additional level of indirection" }, - { 55799, "Self-describe CBOR" }, - { 0, NULL }, -}; - static const val64_string tag64_vals[] = { { 0, "Standard date/time string" }, { 1, "Epoch-based date/time" }, @@ -181,6 +153,10 @@ static const val64_string tag64_vals[] = { { 3, "Negative bignum" }, { 4, "Decimal fraction" }, { 5, "Bigfloat" }, + { 16, "COSE Single Recipient Encrypted Data Object" }, + { 17, "COSE Mac w/o Recipients Object" }, + { 18, "COSE Single Signer Data Object" }, + { 19, "COSE standalone V2 countersignature" }, { 21, "Expected conversion to base64url encoding" }, { 22, "Expected conversion to base64 encoding" }, { 23, "Expected conversion to base16 encoding" }, @@ -199,10 +175,14 @@ static const val64_string tag64_vals[] = { { 37, "Binary UUID" }, { 38, "Language-tagged string" }, { 39, "Identifier" }, + { 61, "CBOR Web Token (CWT)" }, + { 63, "Encoded CBOR Sequence" }, + { 100, "Number of days since the epoch date 1970-01-01" }, { 256, "mark value as having string references" }, { 257, "Binary MIME message" }, { 264, "Decimal fraction with arbitrary exponent" }, { 265, "Bigfloat with arbitrary exponent" }, + { 1004, "RFC 3339 full-date string" }, { 22098, "hint that indicates an additional level of indirection" }, { 55799, "Self-describe CBOR" }, { 0, NULL }, @@ -421,12 +401,20 @@ dissect_cbor_byte_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *cbor_tre return false; } - proto_tree_add_item(subtree, hf_cbor_type_byte_string, tvb, *offset, (int)length, ENC_BIG_ENDIAN|ENC_NA); + proto_item *item_data = proto_tree_add_item(subtree, hf_cbor_type_byte_string, tvb, *offset, (int)length, ENC_BIG_ENDIAN|ENC_NA); *offset += (int)length; proto_item_append_text(item, ": (%" PRIu64 " byte%s)", length, plurality(length, "", "s")); proto_item_set_end(item, tvb, *offset); + if (cbor_dissect_embeded_bstr && length) { + tvbuff_t *sub_tvb = tvb_new_subset_length(tvb, *offset - (int)length, (int)length); + bool valid = cbor_heuristic(sub_tvb, pinfo, subtree, NULL); + if (valid) { + expert_add_info(pinfo, item_data, &ei_cbor_embedded_bstr); + } + } + return true; } @@ -697,8 +685,8 @@ dissect_cbor_tag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *cbor_tree, int * proto_tree_add_item(subtree, hf_cbor_item_major_type, tvb, *offset, 1, ENC_BIG_ENDIAN); if (type_minor <= 0x17) { - proto_tree_add_item(subtree, hf_cbor_type_tag5, tvb, *offset, 1, ENC_BIG_ENDIAN); tag = type_minor; + proto_tree_add_uint64(subtree, hf_cbor_type_tag, tvb, *offset, 1, tag); } else { proto_tree_add_item(subtree, hf_cbor_item_integer_size, tvb, *offset, 1, ENC_BIG_ENDIAN); } @@ -926,6 +914,37 @@ dissect_cborseq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void return offset; } +bool cbor_heuristic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { + int offset = 0; + volatile int count = 0; + + while ((unsigned)offset < tvb_reported_length(tvb)) { + volatile bool valid = false; + TRY { + valid = wscbor_skip_next_item(pinfo->pool, tvb, &offset); + } + CATCH_BOUNDS_AND_DISSECTOR_ERRORS {} + ENDTRY; + if (!valid) { + break; + } + ++count; + } + + // Anything went wrong with any part of the data + if ((count == 0) || ((unsigned)offset != tvb_reported_length(tvb))) { + return false; + } + + if (count == 1) { + call_dissector(cbor_handle, tvb, pinfo, tree); + } + else { + call_dissector(cborseq_handle, tvb, pinfo, tree); + } + return true; +} + void proto_register_cbor(void) { @@ -1055,11 +1074,6 @@ proto_register_cbor(void) FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, - { &hf_cbor_type_tag5, - { "Tag", "cbor.type.tag", - FT_UINT8, BASE_DEC, VALS(tag32_vals), 0x1f, - NULL, HFILL } - }, { &hf_cbor_type_tag, { "Tag", "cbor.type.tag", FT_UINT64, BASE_DEC|BASE_VAL64_STRING, VALS64(tag64_vals), 0x00, @@ -1116,6 +1130,8 @@ proto_register_cbor(void) { "cbor.too_long_length", PI_MALFORMED, PI_WARN, "Too long length", EXPFILL }}, { &ei_cbor_max_recursion_depth_reached, { "cbor.max_recursion_depth_reached", PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached. Dissection stopped.", EXPFILL }}, + { &ei_cbor_embedded_bstr, + { "cbor.embedded_bstr", PI_COMMENTS_GROUP, PI_COMMENT, "Heuristic dissection of CBOR embedded in a byte string", EXPFILL }}, }; expert_module_t *expert_cbor; @@ -1128,18 +1144,28 @@ proto_register_cbor(void) cbor_handle = register_dissector("cbor", dissect_cbor, proto_cbor); cborseq_handle = register_dissector_with_description("cborseq", "CBOR Sequence", dissect_cborseq, proto_cbor); + + module_t *module_cbor = prefs_register_protocol(proto_cbor, NULL); + prefs_register_bool_preference( + module_cbor, + "dissect_embeded_bstr", + "Dissect bstr-embedded CBOR", + "If enabled, a heuristic dissection of byte strings as embedded " + "CBOR/sequence is performed.", + &cbor_dissect_embeded_bstr + ); + } void proto_reg_handoff_cbor(void) { - dissector_add_string("media_type", "application/cbor", cbor_handle); /* RFC 7049 */ - dissector_add_string("media_type", "application/senml+cbor", cbor_handle); /* RFC 8428 */ - dissector_add_string("media_type", "application/sensml+cbor", cbor_handle); /* RFC 8428 */ + dissector_add_string("media_type", "application/cbor", cbor_handle); /* RFC 8949 */ + dissector_add_string("media_type", "application/cwt", cbor_handle); /* RFC 8392 */ dissector_add_string("media_type", "application/cbor-seq", cborseq_handle); /* RFC 8742 */ - dissector_add_string("media_type.suffix", "cbor", cbor_handle); - dissector_add_string("media_type.suffix", "cbor-seq", cborseq_handle); + dissector_add_string("media_type.suffix", "cbor", cbor_handle); /* RFC 8949 */ + dissector_add_string("media_type.suffix", "cbor-seq", cborseq_handle); /* RFC 8742 */ } /* diff --git a/epan/dissectors/packet-cbor.h b/epan/dissectors/packet-cbor.h new file mode 100644 index 0000000000..de208d5a52 --- /dev/null +++ b/epan/dissectors/packet-cbor.h @@ -0,0 +1,38 @@ +/* packet-cbor.h + * + * Routines for Concise Binary Object Representation (CBOR) (STD 94) + * References: + * RFC 8949: https://tools.ietf.org/html/rfc8949 + * RFC 8742: https://tools.ietf.org/html/rfc8742 + * + * Copyright 2025, Brian Sipos + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef PACKET_CBOR_H +#define PACKET_CBOR_H + +#include +#include +#include + +/** + * A dissector function which checks whether the entire data is composed of + * one or more CBOR items (a "CBOR sequence"). + * This meets the signature of ::heur_dissector_t to allow it to be used + * by other protocols directly as a heuristic. + * + * @param[in] tvb the tvbuff with the (remaining) packet data + * @param pinfo the packet info of this packet (additional info) + * @param tree the protocol tree to be build or NULL + * @param[in] data Unused user data pointer + * @return true if the entire TVB contains cbor item(s) and nothing more + */ +bool cbor_heuristic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data); + +#endif /* PACKET_CBOR_H */ diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c index f7c5a73d15..c97bd31641 100644 --- a/epan/dissectors/packet-cip.c +++ b/epan/dissectors/packet-cip.c @@ -137,6 +137,7 @@ static int hf_cip_cm_to_rpi; static int hf_cip_cm_to_timeout; static int hf_cip_safety_nte_ms; +static int hf_cipsafety_protocol; static int hf_cip_cm_to_net_params32; static int hf_cip_cm_to_net_params16; @@ -295,6 +296,7 @@ static int hf_cip_port; static int hf_cip_port_extended; static int hf_cip_link_address_size; static int hf_cip_link_address_byte; +static int hf_cip_slot; static int hf_cip_link_address_string; static int hf_cip_logical_seg_type; static int hf_cip_logical_seg_format; @@ -5540,10 +5542,16 @@ static int dissect_segment_port(tvbuff_t* tvb, int offset, bool generate, uint8_t link_address_byte = tvb_get_uint8(tvb, offset + offset_link_address); proto_item* it = proto_tree_add_uint(path_seg_tree, hf_cip_link_address_byte, tvb, 0, 0, link_address_byte); proto_item_set_generated(it); + + proto_item* slot_it = proto_tree_add_uint(path_seg_tree, hf_cip_slot, tvb, 0, 0, link_address_byte); + proto_item_set_hidden(slot_it); } else { proto_tree_add_item(path_seg_tree, hf_cip_link_address_byte, tvb, offset + offset_link_address, 1, ENC_LITTLE_ENDIAN); + + proto_item* slot_it = proto_tree_add_item(path_seg_tree, hf_cip_slot, tvb, offset + offset_link_address, 1, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(slot_it); } proto_item_append_text(epath_item, ", Address: %d", tvb_get_uint8(tvb, offset + offset_link_address)); @@ -5574,6 +5582,12 @@ static int dissect_segment_port(tvbuff_t* tvb, int offset, bool generate, static int dissect_segment_safety(packet_info* pinfo, tvbuff_t* tvb, int offset, bool generate, proto_tree* net_tree, cip_safety_epath_info_t* safety, cip_simple_request_info_t* req_data) { + // Allow 'cipsafety' to match all parts of the safety protocol. This will: + // 1. Match the I/O format from packet-cipsafety + // 2. Match the FwdOpen,FwdClose here + proto_item* pi = proto_tree_add_item(net_tree, hf_cipsafety_protocol, tvb, 0, 0, ENC_NA); + proto_item_set_hidden(pi); + uint16_t seg_size = tvb_get_uint8(tvb, offset + 1) * 2; int segment_len = seg_size + 2; @@ -7836,6 +7850,11 @@ static int dissect_cip_cc_hop(packet_info* pinfo, tvbuff_t* tvb, int offset, pro case 0: // Link addresses { proto_tree_add_item(hop_tree, hf_ext_net_seg_link_address, tvb, offset + parsed, 1, ENC_LITTLE_ENDIAN); + + uint8_t slot_number = tvb_get_uint8(tvb, offset + parsed); + proto_item* slot_it = proto_tree_add_uint(hop_tree, hf_cip_slot, tvb, 0, 0, slot_number); + proto_item_set_hidden(slot_it); + parsed++; break; } @@ -10014,6 +10033,7 @@ proto_register_cip(void) { &hf_cip_port, { "Port", "cip.port", FT_UINT8, BASE_DEC, VALS(cip_port_number_vals), CI_PORT_SEG_PORT_ID_MASK, "Port Identifier", HFILL } }, { &hf_cip_port_extended,{ "Port Extended", "cip.port", FT_UINT16, BASE_HEX, NULL, 0, "Port Identifier Extended", HFILL } }, { &hf_cip_link_address_byte, { "Link Address", "cip.linkaddress.byte", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_slot, { "Slot", "cip.slot", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_cip_link_address_size, { "Link Address Size", "cip.linkaddress_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, { &hf_cip_link_address_string, { "Link Address", "cip.linkaddress.string", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, { &hf_cip_logical_seg_type, { "Logical Segment Type", "cip.logical_segment.type", FT_UINT8, BASE_DEC, VALS(cip_logical_segment_type_vals), CI_LOGICAL_SEG_TYPE_MASK, NULL, HFILL }}, @@ -10329,6 +10349,7 @@ proto_register_cip(void) { &hf_cip_cm_to_timeout, { "T->O Timeout Threshold", "cip.cm.to_timeout", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0, NULL, HFILL }}, { &hf_cip_safety_nte_ms, { "Network Time Expectation (Produce Timeout)", "cip.safety.nte", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_milliseconds), 0, NULL, HFILL }}, + { &hf_cipsafety_protocol, { "CIP Safety", "cipsafety", FT_PROTOCOL, BASE_NONE, NULL, 0, NULL, HFILL }}, { &hf_cip_cm_to_net_params32, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, { &hf_cip_cm_to_net_params16, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h index 9168a6a2c8..965c83d71a 100644 --- a/epan/dissectors/packet-cip.h +++ b/epan/dissectors/packet-cip.h @@ -511,6 +511,9 @@ typedef struct cip_connID_info { // Actual Packet Interval in microseconds. uint32_t api; + + // These are used to track the previous timestamps for each direction. These are only used during a first pass calculation. + nstime_t timestamp; } cip_connID_info_t; enum cip_safety_format_type {CIP_SAFETY_BASE_FORMAT, CIP_SAFETY_EXTENDED_FORMAT}; diff --git a/epan/dissectors/packet-cms.c b/epan/dissectors/packet-cms.c index 56a1830839..371c3469da 100644 --- a/epan/dissectors/packet-cms.c +++ b/epan/dissectors/packet-cms.c @@ -3608,4 +3608,6 @@ void proto_reg_handoff_cms(void) { dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109", content_info_handle); dissector_add_string("media_type", "application/vnd.de-dke-k461-ic1+xml; encap=cms-tr03109-zlib", content_info_handle); dissector_add_string("media_type", "application/hgp;encap=cms", content_info_handle); + + dissector_add_string("rfc7468.preeb_label", "CMS", content_info_handle); } diff --git a/epan/dissectors/packet-enip.c b/epan/dissectors/packet-enip.c index baa7e5fa1a..409c5db6a2 100644 --- a/epan/dissectors/packet-enip.c +++ b/epan/dissectors/packet-enip.c @@ -154,6 +154,7 @@ static int hf_enip_cpf_length; static int hf_cip_sequence_count; static int hf_cip_cm_ot_api; static int hf_cip_cm_to_api; +static int hf_cip_data_direction; static int hf_enip_cpf_cai_connid; static int hf_enip_cpf_sai_connid; static int hf_cip_connid; @@ -168,6 +169,7 @@ static int hf_enip_cpf_data; static int hf_enip_response_in; static int hf_enip_response_to; static int hf_enip_time; +static int hf_cip_connected_data_time_delta; static int hf_enip_fwd_open_in; static int hf_cip_connection; static int hf_cip_io_data; @@ -843,6 +845,14 @@ static const value_string dlr_flush_learning_update_vals[] = { { 0, NULL } }; +static const value_string cip_data_direction[] = { + { ECIDT_UNKNOWN, "Unknown" }, + { ECIDT_O2T, "O->T" }, + { ECIDT_T2O, "T->O" }, + + { 0, NULL } +}; + static const true_false_string dlr_lnknbrstatus_frame_type_vals = { "Neighbor_Status Frame", "Link_Status Frame" @@ -1275,6 +1285,8 @@ static void enip_open_cip_connection( packet_info *pinfo, cip_conn_info_t* connI *conn_val = *connInfo; // These values are not copies from the Forward Open Request. Initialize these separately. + conn_val->O2T.timestamp = pinfo->abs_ts; + conn_val->T2O.timestamp = pinfo->abs_ts; conn_val->open_reply_frame = pinfo->num; conn_val->connid = enip_unique_connid++; conn_val->is_concurrent_connection = (service == SC_CM_CONCURRENT_FWD_OPEN); @@ -2830,6 +2842,30 @@ void display_fwd_open_connection_path(cip_conn_info_t* conn_info, proto_tree* tr } } +// Calculate the timing information for a single direction. +static void enip_calculate_timing_information_direction(packet_info* pinfo, cip_connID_info_t* connid_info) +{ + struct enip_per_packet_data_t* enipd = wmem_new(wmem_file_scope(), struct enip_per_packet_data_t); + p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_DATA_RATE_INFO, enipd); + + nstime_delta(&enipd->ts_delta, &pinfo->abs_ts, &connid_info->timestamp); + + // Save current information for the next frame. + connid_info->timestamp = pinfo->abs_ts; +} + +static void enip_calculate_timing_information(packet_info* pinfo, cip_conn_info_t* conn_info, enum enip_connid_type connid_type) +{ + if (connid_type == ECIDT_O2T) + { + enip_calculate_timing_information_direction(pinfo, &conn_info->O2T); + } + else if (connid_type == ECIDT_T2O) + { + enip_calculate_timing_information_direction(pinfo, &conn_info->T2O); + } +} + // returns true if this is a likely Heartbeat message // Note: item_length include the CIP Sequence Count, if applicable. static bool cip_io_is_likely_heartbeat(const cip_conn_info_t* conn_info, enum enip_connid_type connid_type, uint32_t item_length) @@ -2868,28 +2904,39 @@ static void display_connection_information(packet_info* pinfo, tvbuff_t* tvb, pr proto_tree* conn_info_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_connection_info, &conn_info_item, "Connection Information"); proto_item_set_generated(conn_info_item); + proto_item* pi = proto_tree_add_uint(conn_info_tree, hf_cip_connection, tvb, 0, 0, conn_info->connid); + proto_item_set_generated(pi); + + display_fwd_open_connection_path(conn_info, conn_info_tree, tvb, pinfo); + + pi = proto_tree_add_uint(conn_info_tree, hf_enip_fwd_open_in, tvb, 0, 0, conn_info->open_req_frame); + proto_item_set_generated(pi); + + pi = proto_tree_add_uint(conn_info_tree, hf_cip_data_direction, tvb, 0, 0, connid_type); + proto_item_set_generated(pi); + if (connid_type == ECIDT_O2T) { proto_item_append_text(conn_info_item, ": O->T"); + + pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_ot_api, tvb, 0, 0, conn_info->O2T.api); + proto_item_set_generated(pi); } else if (connid_type == ECIDT_T2O) { proto_item_append_text(conn_info_item, ": T->O"); - } - - display_fwd_open_connection_path(conn_info, conn_info_tree, tvb, pinfo); - - proto_item* pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_ot_api, tvb, 0, 0, conn_info->O2T.api); - proto_item_set_generated(pi); - pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_to_api, tvb, 0, 0, conn_info->T2O.api); - proto_item_set_generated(pi); - - pi = proto_tree_add_uint(conn_info_tree, hf_cip_connection, tvb, 0, 0, conn_info->connid); - proto_item_set_generated(pi); + pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_to_api, tvb, 0, 0, conn_info->T2O.api); + proto_item_set_generated(pi); + } - pi = proto_tree_add_uint(conn_info_tree, hf_enip_fwd_open_in, tvb, 0, 0, conn_info->open_req_frame); - proto_item_set_generated(pi); + // Information about previous data in the same direction. + struct enip_per_packet_data_t* enipd = (struct enip_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_DATA_RATE_INFO); + if (enipd) + { + proto_item* item = proto_tree_add_time(conn_info_tree, hf_cip_connected_data_time_delta, tvb, 0, 0, &enipd->ts_delta); + proto_item_set_generated(item); + } if (cip_io_is_likely_heartbeat(conn_info, connid_type, item_length)) { @@ -3324,6 +3371,7 @@ dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb, if (!pinfo->fd->visited && conn_info) { p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO, conn_info); + enip_calculate_timing_information(pinfo, conn_info, connid_type); } if (command == SEND_UNIT_DATA) // Class 2/3 over TCP. @@ -4185,10 +4233,16 @@ proto_register_enip(void) { "Forward Open Request In", "enip.fwd_open_in", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } }, + { &hf_cip_connected_data_time_delta, + { "Time since last data", "cip.data_time_delta", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + NULL, HFILL } }, // Generated API data. { &hf_cip_cm_ot_api, { "O->T API", "cip.cm.otapi", FT_UINT32, BASE_CUSTOM, CF_FUNC(cip_rpi_api_fmt), 0, NULL, HFILL } }, { &hf_cip_cm_to_api, { "T->O API", "cip.cm.toapi", FT_UINT32, BASE_CUSTOM, CF_FUNC(cip_rpi_api_fmt), 0, NULL, HFILL } }, + { &hf_cip_data_direction, { "Data Direction", "cip.data_direction", FT_UINT8, BASE_DEC, VALS(cip_data_direction), 0, NULL, HFILL } }, + { &hf_cip_connection, { "CIP Connection Index", "cip.connection", FT_UINT32, BASE_DEC, NULL, 0x0, diff --git a/epan/dissectors/packet-enip.h b/epan/dissectors/packet-enip.h index afcd8bdfc0..01121f1423 100644 --- a/epan/dissectors/packet-enip.h +++ b/epan/dissectors/packet-enip.h @@ -94,16 +94,26 @@ typedef struct { } enip_request_info_t; // This represents the data direction for connected data. -enum enip_connid_type {ECIDT_UNKNOWN, ECIDT_O2T, ECIDT_T2O}; +enum enip_connid_type { + ECIDT_UNKNOWN = 0, + ECIDT_O2T = 1, + ECIDT_T2O = 2 +}; typedef struct cip_io_data_input { cip_conn_info_t* conn_info; enum enip_connid_type connid_type; } cip_io_data_input; +// Per packet data for: ENIP_DATA_RATE_INFO +struct enip_per_packet_data_t { + // Time difference between this message and the previous message in the same connection direction. + nstime_t ts_delta; +}; /* proto_data types */ #define ENIP_REQUEST_INFO 0 #define ENIP_CONNECTION_INFO 1 +#define ENIP_DATA_RATE_INFO 2 void display_fwd_open_connection_path(cip_conn_info_t* conn_info, proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo); void enip_close_cip_connection(packet_info *pinfo, const cip_connection_triad_t* triad); diff --git a/epan/dissectors/packet-its.c b/epan/dissectors/packet-its.c index 2c84a50abb..bc227cd4b3 100644 --- a/epan/dissectors/packet-its.c +++ b/epan/dissectors/packet-its.c @@ -32127,7 +32127,7 @@ void proto_register_its(void) #define ITS_TIS_TPG_PROT_VER 1 #define ITS_CPM_PROT_VERv1 1 #define ITS_CPM_PROT_VER 2 -#define ITS_VAM_PROT_VER 2 +#define ITS_VAM_PROT_VER 3 #define ITS_IMZM_PROT_VER 2 void proto_reg_handoff_its(void) diff --git a/epan/dissectors/packet-ngap.c b/epan/dissectors/packet-ngap.c index 9ad09bf180..2808fbcbc9 100644 --- a/epan/dissectors/packet-ngap.c +++ b/epan/dissectors/packet-ngap.c @@ -3339,6 +3339,7 @@ static int ett_ngap_SuccessfulOutcome; static int ett_ngap_UnsuccessfulOutcome; static expert_field ei_ngap_number_pages_le15; +static expert_field ei_ngap_disable_nrppa_encapsulation; enum{ INITIATING_MESSAGE, @@ -3711,6 +3712,7 @@ static const enum_val_t ngap_lte_container_vals[] = { /* Global variables */ static range_t *gbl_ngapSctpRange; static bool ngap_dissect_container = true; +static bool ngap_disable_nrppa_encapsulation = false; static int ngap_dissect_target_ng_ran_container_as = NGAP_NG_RAN_CONTAINER_AUTOMATIC; static int ngap_dissect_lte_container_as = NGAP_LTE_CONTAINER_AUTOMATIC; @@ -31143,12 +31145,18 @@ find_n2_info_content(char *json_data, jsmntok_t *token, const char *n2_info_cont if (!str || strcmp(str, content_id)) return false; str = json_get_string(json_data, n2_info_content_token, "ngapIeType"); - if (str) - *subdissector = dissector_get_string_handle(ngap_n2_ie_type_dissector_table, str); - else if (json_get_double(json_data, n2_info_content_token, "ngapMessageType", &ngap_msg_type)) + if (str) { + if (!strcmp(str, "NRPPA_PDU") && ngap_disable_nrppa_encapsulation) { + *subdissector = nrppa_handle; + } else { + *subdissector = dissector_get_string_handle(ngap_n2_ie_type_dissector_table, str); + } + } else if (json_get_double(json_data, n2_info_content_token, + "ngapMessageType", &ngap_msg_type)) { *subdissector = ngap_handle; - else + } else { *subdissector = NULL; + } return true; } @@ -31259,6 +31267,11 @@ dissect_ngap_media_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi if (subdissector != ngap_handle) { ngap_item = proto_tree_add_item(tree, proto_ngap, tvb, 0, -1, ENC_NA); ngap_tree = proto_item_add_subtree(ngap_item, ett_ngap); + if (ngap_disable_nrppa_encapsulation && subdissector == nrppa_handle) { + expert_add_info_format(pinfo, ngap_item, + &ei_ngap_disable_nrppa_encapsulation, + "Encapsulation of NRPPa in NGAP is disabled"); + } } else { ngap_tree = tree; } @@ -39608,7 +39621,10 @@ void proto_register_ngap(void) { }; static ei_register_info ei[] = { - { &ei_ngap_number_pages_le15, { "ngap.number_pages_le15", PI_MALFORMED, PI_ERROR, "Number of pages should be <=15", EXPFILL }} + { &ei_ngap_number_pages_le15, { "ngap.number_pages_le15", PI_MALFORMED, PI_ERROR, "Number of pages should be <=15", EXPFILL }}, + { &ei_ngap_disable_nrppa_encapsulation, + { "ngap.disable_nrppa_encapsulation", PI_PROTOCOL, PI_CHAT, "Encapsulation of NRPPa in NGAP is disabled", EXPFILL } + } }; module_t *ngap_module; @@ -39643,6 +39659,13 @@ void proto_register_ngap(void) { "Dissect TransparentContainer", "Dissect TransparentContainers that are opaque to NGAP", &ngap_dissect_container); + prefs_register_bool_preference(ngap_module, "disable_nrppa_encapsulation", + "Disable encapsulation of NRPPa in NGAP", + "The standard indicates that NRPPa PDU must " + "be encapsulated in ngap.NRPPa-PDU ASN1 type. " + "However, Huawei AMF use the NRPPa ASN1 type " + "directly.", + &ngap_disable_nrppa_encapsulation); prefs_register_enum_preference(ngap_module, "dissect_target_ng_ran_container_as", "Dissect target NG-RAN container as", "Select whether target NG-RAN container should be decoded automatically" diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index a71a98d6e7..65120cd629 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -2196,11 +2196,19 @@ uint32_t get_mptcp_stream_count(void) /* Calculate the timestamps relative to this conversation */ static void -tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd, - struct tcp_per_packet_data_t *tcppd) +tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd) { + struct tcp_per_packet_data_t *tcppd; + tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num); + /* XXX - This is the only place this per packet data struct is + * created, but the TCP sequence manual analysis is stored here. + * It's confusing as the preference description doesn't mention + * this (and leads to having to do a lot of NULL checks.) However, + * it is useful to be able to disable the per packet persistent + * storage, particularly in single pass mode tshark. + */ if( !tcppd ) { - tcppd = wmem_new(wmem_file_scope(), struct tcp_per_packet_data_t); + tcppd = wmem_new0(wmem_file_scope(), struct tcp_per_packet_data_t); p_add_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num, tcppd); } @@ -2211,7 +2219,6 @@ tcp_calculate_timestamps(packet_info *pinfo, struct tcp_analysis *tcpd, tcppd->pnum = ++tcpd->pnum; nstime_delta(&tcppd->ts_del, &pinfo->abs_ts, &tcpd->ts_prev); - tcppd->tcp_snd_manual_analysis = 0; tcpd->ts_prev.secs=pinfo->abs_ts.secs; tcpd->ts_prev.nsecs=pinfo->abs_ts.nsecs; @@ -8426,10 +8433,8 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) /* Do we need to calculate timestamps relative to the tcp-stream? */ if (tcp_calculate_ts) { - tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num); - /* Calculate the timestamps relative to this conversation */ - tcp_calculate_timestamps(pinfo, tcpd, tcppd); + tcp_calculate_timestamps(pinfo, tcpd); } } @@ -8438,9 +8443,12 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) proto_item_set_generated(item); tcpinfo.stream = tcpd->stream; - if (tcppd) { - item = proto_tree_add_uint(tcp_tree, hf_tcp_stream_pnum, tvb, offset, 0, tcppd->pnum); - proto_item_set_generated(item); + if (tcp_calculate_ts) { + tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num); + if (tcppd) { + item = proto_tree_add_uint(tcp_tree, hf_tcp_stream_pnum, tvb, offset, 0, tcppd->pnum); + proto_item_set_generated(item); + } } /* Display the completeness of this TCP conversation */ @@ -8482,6 +8490,10 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) /* is there any manual analysis waiting ? */ if(pinfo->fd->tcp_snd_manual_analysis > 0) { tcppd = (struct tcp_per_packet_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num); + if (!tcppd) { + tcppd = wmem_new0(wmem_file_scope(), struct tcp_per_packet_data_t); + p_add_proto_data(wmem_file_scope(), pinfo, proto_tcp, pinfo->curr_layer_num, tcppd); + } tcppd->tcp_snd_manual_analysis = pinfo->fd->tcp_snd_manual_analysis; } diff --git a/packaging/debian/control b/packaging/debian/control index 62dc0ad4a3..1c406bb7ae 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -88,9 +88,11 @@ Depends: ${shlibs:Depends}, libqt6svg6, qt6-qpa-plugins Recommends: libqt6multimedia6 -Breaks: wireshark-qt, +Breaks: libwireshark-data (<< 4.4.3-2~), + wireshark-qt, wireshark-gtk (<< 3.0.0~) -Replaces: wireshark-qt, +Replaces: libwireshark-data (<< 4.4.3-2~), + wireshark-qt, wireshark-gtk (<< 3.0.0~) Description: network traffic analyzer - graphical interface Wireshark is a network "sniffer" - a tool that captures and analyzes diff --git a/packaging/debian/stratoshark.install b/packaging/debian/stratoshark.install index 39992fcb96..ece2007a8d 100644 --- a/packaging/debian/stratoshark.install +++ b/packaging/debian/stratoshark.install @@ -2,3 +2,4 @@ usr/bin/stratoshark usr/lib/*/stratoshark/extcap usr/share/stratoshark/* usr/share/applications/org.wireshark.Stratoshark.desktop +usr/share/metainfo/org.wireshark.Stratoshark.metainfo.xml diff --git a/packaging/debian/wireshark.install b/packaging/debian/wireshark.install index a31db40ac9..94a74ab6a9 100644 --- a/packaging/debian/wireshark.install +++ b/packaging/debian/wireshark.install @@ -1,2 +1,3 @@ usr/bin/wireshark usr/share/applications/org.wireshark.Wireshark.desktop +usr/share/metainfo/org.wireshark.Wireshark.metainfo.xml