diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:53 +0000 |
commit | a86c5f7cae7ec9a3398300555a0b644689d946a1 (patch) | |
tree | 39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /epan/dissectors/packet-gsmtap.c | |
parent | Releasing progress-linux version 4.2.6-1~progress7.99u1. (diff) | |
download | wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.tar.xz wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.zip |
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-gsmtap.c')
-rw-r--r-- | epan/dissectors/packet-gsmtap.c | 204 |
1 files changed, 120 insertions, 84 deletions
diff --git a/epan/dissectors/packet-gsmtap.c b/epan/dissectors/packet-gsmtap.c index 7845f002..fca98dca 100644 --- a/epan/dissectors/packet-gsmtap.c +++ b/epan/dissectors/packet-gsmtap.c @@ -34,7 +34,10 @@ #include "config.h" #include <epan/packet.h> +#include <epan/expert.h> #include <epan/conversation.h> +#include <epan/tfs.h> +#include <epan/unit_strings.h> #include "packet-gsm_rlcmac.h" #include <wiretap/wtap.h> @@ -47,40 +50,42 @@ void proto_reg_handoff_gsmtap(void); static dissector_handle_t gsmtap_handle; -static int proto_gsmtap = -1; - -static int hf_gsmtap_version = -1; -static int hf_gsmtap_hdrlen = -1; -static int hf_gsmtap_type = -1; -static int hf_gsmtap_timeslot = -1; -static int hf_gsmtap_subslot = -1; -static int hf_gsmtap_arfcn = -1; -static int hf_gsmtap_uplink = -1; -static int hf_gsmtap_pcs = -1; -static int hf_gsmtap_signal_dbm = -1; -static int hf_gsmtap_snr_db = -1; -static int hf_gsmtap_frame_nr = -1; -static int hf_gsmtap_burst_type = -1; -static int hf_gsmtap_channel_type = -1; -static int hf_gsmtap_tetra_channel_type = -1; -static int hf_gsmtap_gmr1_channel_type = -1; -static int hf_gsmtap_rrc_sub_type = -1; -static int hf_gsmtap_e1t1_sub_type = -1; -static int hf_gsmtap_antenna = -1; - -static int hf_sacch_l1h_power_lev = -1; -static int hf_sacch_l1h_fpc = -1; -static int hf_sacch_l1h_sro_srr = -1; -static int hf_sacch_l1h_ta = -1; - -static int hf_ptcch_spare = -1; -static int hf_ptcch_ta_idx = -1; -static int hf_ptcch_ta_val = -1; -static int hf_ptcch_padding = -1; - -static int hf_um_voice_type = -1; - -static gint ett_gsmtap = -1; +static int proto_gsmtap; + +static int hf_gsmtap_version; +static int hf_gsmtap_hdrlen; +static int hf_gsmtap_type; +static int hf_gsmtap_timeslot; +static int hf_gsmtap_subslot; +static int hf_gsmtap_arfcn; +static int hf_gsmtap_uplink; +static int hf_gsmtap_pcs; +static int hf_gsmtap_signal_dbm; +static int hf_gsmtap_snr_db; +static int hf_gsmtap_frame_nr; +static int hf_gsmtap_burst_type; +static int hf_gsmtap_channel_type; +static int hf_gsmtap_tetra_channel_type; +static int hf_gsmtap_gmr1_channel_type; +static int hf_gsmtap_rrc_sub_type; +static int hf_gsmtap_e1t1_sub_type; +static int hf_gsmtap_antenna; + +static int hf_sacch_l1h_power_lev; +static int hf_sacch_l1h_fpc; +static int hf_sacch_l1h_sro_srr; +static int hf_sacch_l1h_ta; + +static int hf_ptcch_spare; +static int hf_ptcch_ta_idx; +static int hf_ptcch_ta_val; +static int hf_ptcch_padding; + +static int hf_um_voice_type; + +static int ett_gsmtap; + +static expert_field ei_gsmtap_unknown_gsmtap_version; enum { GSMTAP_SUB_DATA = 0, @@ -497,8 +502,8 @@ dissect_sacch_l1h(tvbuff_t *tvb, proto_tree *tree) ti = proto_tree_add_protocol_format(tree, proto_gsmtap, tvb, 0, 2, "SACCH L1 Header, Power Level: %u, Timing Advance: %u", - tvb_get_guint8(tvb, 0) & 0x1f, - tvb_get_guint8(tvb, 1)); + tvb_get_uint8(tvb, 0) & 0x1f, + tvb_get_uint8(tvb, 1)); l1h_tree = proto_item_add_subtree(ti, ett_gsmtap); /* Power Level */ proto_tree_add_item(l1h_tree, hf_sacch_l1h_power_lev, tvb, 0, 1, ENC_BIG_ENDIAN); @@ -506,7 +511,7 @@ dissect_sacch_l1h(tvbuff_t *tvb, proto_tree *tree) proto_tree_add_item(l1h_tree, hf_sacch_l1h_fpc, tvb, 0, 1, ENC_BIG_ENDIAN); /* SRO/SRR (SACCH Repetition) bit */ proto_tree_add_item(l1h_tree, hf_sacch_l1h_sro_srr, tvb, 0, 1, ENC_BIG_ENDIAN); - /* Acutal Timing Advance */ + /* Actual Timing Advance */ proto_tree_add_item(l1h_tree, hf_sacch_l1h_ta, tvb, 1, 1, ENC_BIG_ENDIAN); } @@ -549,7 +554,7 @@ dissect_ptcch_dl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } static void -handle_lapdm(guint8 sub_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +handle_lapdm(uint8_t sub_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { lapdm_data_t ld; @@ -560,7 +565,7 @@ handle_lapdm(guint8 sub_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre static void handle_rach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - guint8 channel_type = GSMTAP_CHANNEL_RACH; + uint8_t channel_type = GSMTAP_CHANNEL_RACH; call_dissector_with_data(sub_handles[GSMTAP_SUB_UM], tvb, pinfo, tree, &channel_type); } @@ -568,7 +573,7 @@ static void dissect_um_voice(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *payload_tvb; - guint8 vtype = tvb_get_guint8(tvb, 0); + uint8_t vtype = tvb_get_uint8(tvb, 0); col_add_fstr(pinfo->cinfo, COL_INFO, "GSM CS User Plane (Voice/CSD): %s", val_to_str(vtype, gsmtap_um_voice_types, "Unknown %d")); @@ -594,7 +599,7 @@ handle_tetra(int channel, tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree } /* length of an EGPRS RLC data block for given MCS */ -static const guint data_block_len_by_mcs[] = { +static const unsigned data_block_len_by_mcs[] = { 0, /* MCS0 */ 22, /* MCS1 */ 28, @@ -610,10 +615,10 @@ static const guint data_block_len_by_mcs[] = { /* determine the number of rlc data blocks and their size / offsets */ static void -setup_rlc_mac_priv(RlcMacPrivateData_t *rm, gboolean is_uplink, - guint *n_calls, guint *data_block_bits, guint *data_block_offsets) +setup_rlc_mac_priv(RlcMacPrivateData_t *rm, bool is_uplink, + unsigned *n_calls, unsigned *data_block_bits, unsigned *data_block_offsets) { - guint nc, dbl = 0, dbo[2] = {0,0}; + unsigned nc, dbl = 0, dbo[2] = {0,0}; dbl = data_block_len_by_mcs[rm->mcs]; @@ -645,15 +650,15 @@ setup_rlc_mac_priv(RlcMacPrivateData_t *rm, gboolean is_uplink, /* bit-shift the entire 'src' of length 'length_bytes' by 'offset_bits' * and store the reuslt to caller-allocated 'buffer'. The shifting is * done lsb-first, unlike tvb_new_octet_aligned() */ -static void clone_aligned_buffer_lsbf(guint offset_bits, guint length_bytes, - const guint8 *src, guint8 *buffer) +static void clone_aligned_buffer_lsbf(unsigned offset_bits, unsigned length_bytes, + const uint8_t *src, uint8_t *buffer) { - guint hdr_bytes; - guint extra_bits; - guint i; + unsigned hdr_bytes; + unsigned extra_bits; + unsigned i; - guint8 c, last_c; - guint8 *dst; + uint8_t c, last_c; + uint8_t *dst; hdr_bytes = offset_bits / 8; extra_bits = offset_bits % 8; @@ -677,18 +682,18 @@ static void clone_aligned_buffer_lsbf(guint offset_bits, guint length_bytes, /* obtain an (aligned) EGPRS data block with given bit-offset and * bit-length from the parent TVB */ -static tvbuff_t *get_egprs_data_block(tvbuff_t *tvb, guint offset_bits, - guint length_bits, packet_info *pinfo) +static tvbuff_t *get_egprs_data_block(tvbuff_t *tvb, unsigned offset_bits, + unsigned length_bits, packet_info *pinfo) { tvbuff_t *aligned_tvb; - const guint initial_spare_bits = 6; - guint8 *aligned_buf; - guint min_src_length_bytes = (offset_bits + length_bits + 7) / 8; - guint length_bytes = (initial_spare_bits + length_bits + 7) / 8; + const unsigned initial_spare_bits = 6; + uint8_t *aligned_buf; + unsigned min_src_length_bytes = (offset_bits + length_bits + 7) / 8; + unsigned length_bytes = (initial_spare_bits + length_bits + 7) / 8; tvb_ensure_bytes_exist(tvb, 0, min_src_length_bytes); - aligned_buf = (guint8 *) wmem_alloc(pinfo->pool, length_bytes); + aligned_buf = (uint8_t *) wmem_alloc(pinfo->pool, length_bytes); /* Copy the data out of the tvb to an aligned buffer */ clone_aligned_buffer_lsbf( @@ -706,7 +711,7 @@ static tvbuff_t *get_egprs_data_block(tvbuff_t *tvb, guint offset_bits, return aligned_tvb; } -static void tvb_len_get_mcs_and_fmt(guint len, gboolean is_uplink, guint *frm, guint8 *mcs) +static void tvb_len_get_mcs_and_fmt(unsigned len, bool is_uplink, unsigned *frm, uint8_t *mcs) { if (len <= 5 && is_uplink) { /* Assume random access burst */ @@ -740,15 +745,15 @@ static void tvb_len_get_mcs_and_fmt(guint len, gboolean is_uplink, guint *frm, g } static void -handle_rlcmac(guint32 frame_nr, tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree) +handle_rlcmac(uint32_t frame_nr, tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree) { int sub_handle; RlcMacPrivateData_t rlcmac_data = {0}; tvbuff_t *data_tvb; - guint data_block_bits, data_block_offsets[2]; - guint num_calls; - gboolean is_uplink; + unsigned data_block_bits, data_block_offsets[2]; + unsigned num_calls; + bool is_uplink; if (pinfo->p2p_dir == P2P_DIR_SENT) { is_uplink = 1; @@ -762,8 +767,8 @@ handle_rlcmac(guint32 frame_nr, tvbuff_t *payload_tvb, packet_info *pinfo, proto rlcmac_data.frame_number = frame_nr; tvb_len_get_mcs_and_fmt(tvb_reported_length(payload_tvb), is_uplink, - (guint *) &rlcmac_data.block_format, - (guint8 *) &rlcmac_data.mcs); + (unsigned *) &rlcmac_data.block_format, + (uint8_t *) &rlcmac_data.mcs); switch (rlcmac_data.block_format) { case RLCMAC_HDR_TYPE_1: @@ -803,27 +808,27 @@ handle_rlcmac(guint32 frame_nr, tvbuff_t *payload_tvb, packet_info *pinfo, proto } } -/* dissect a GSMTAP header and hand payload off to respective dissector */ +/* dissect a GSMTAP v2 header and hand payload off to respective dissector */ static int -dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +dissect_gsmtap_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { int sub_handle, sub_handle_idx = 0, len, offset = 0; proto_item *ti; proto_tree *gsmtap_tree = NULL; tvbuff_t *payload_tvb, *l1h_tvb = NULL; - guint8 hdr_len, type, sub_type, timeslot, subslot; - guint16 arfcn; - guint32 frame_nr; + uint8_t hdr_len, type, sub_type, timeslot, subslot; + uint16_t arfcn; + uint32_t frame_nr; len = tvb_reported_length(tvb); - hdr_len = tvb_get_guint8(tvb, offset + 1) <<2; - type = tvb_get_guint8(tvb, offset + 2); - timeslot = tvb_get_guint8(tvb, offset + 3); + hdr_len = tvb_get_uint8(tvb, offset + 1) <<2; + type = tvb_get_uint8(tvb, offset + 2); + timeslot = tvb_get_uint8(tvb, offset + 3); arfcn = tvb_get_ntohs(tvb, offset + 4); frame_nr = tvb_get_ntohl(tvb, offset + 8); - sub_type = tvb_get_guint8(tvb, offset + 12); - subslot = tvb_get_guint8(tvb, offset + 14); + sub_type = tvb_get_uint8(tvb, offset + 12); + subslot = tvb_get_uint8(tvb, offset + 14); /* In case of a SACCH, there is a two-byte L1 header in front * of the packet (see TS 04.04) */ @@ -876,9 +881,9 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _ conversation_set_elements_by_id(pinfo, CONVERSATION_GSMTAP, (timeslot << 3) | subslot); if (tree) { - guint8 channel; + uint8_t channel; const char *channel_str; - channel = tvb_get_guint8(tvb, offset+12); + channel = tvb_get_uint8(tvb, offset+12); if (type == GSMTAP_TYPE_TETRA_I1) channel_str = val_to_str(channel, gsmtap_tetra_channels, "Unknown: %d"); else if (type == GSMTAP_TYPE_GMR1_UM) @@ -890,9 +895,9 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _ "GSM TAP Header, ARFCN: %u (%s), TS: %u, Channel: %s (%u)", arfcn & GSMTAP_ARFCN_MASK, arfcn & GSMTAP_ARFCN_F_UPLINK ? "Uplink" : "Downlink", - tvb_get_guint8(tvb, offset+3), + tvb_get_uint8(tvb, offset+3), channel_str, - tvb_get_guint8(tvb, offset+14)); + tvb_get_uint8(tvb, offset+14)); gsmtap_tree = proto_item_add_subtree(ti, ett_gsmtap); proto_tree_add_item(gsmtap_tree, hf_gsmtap_version, tvb, offset, 1, ENC_BIG_ENDIAN); @@ -1041,7 +1046,7 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _ sub_handle = GSMTAP_SUB_SNDCP; break; case GSMTAP_TYPE_TETRA_I1: - handle_tetra(tvb_get_guint8(tvb, offset+12), payload_tvb, pinfo, tree); + handle_tetra(tvb_get_uint8(tvb, offset+12), payload_tvb, pinfo, tree); return tvb_captured_length(tvb); case GSMTAP_TYPE_WMX_BURST: switch (sub_type) { @@ -1177,6 +1182,30 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _ return tvb_captured_length(tvb); } +static int +dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + uint8_t version; + proto_tree *gsmtap_tree; + proto_item *ti, *tf; + + version = tvb_get_uint8(tvb, 0); + + if (version == 2) { + return dissect_gsmtap_v2(tvb, pinfo, tree, data); + } + + /* Unknown GSMTAP version */ + ti = proto_tree_add_protocol_format(tree, proto_gsmtap, tvb, 0, 1, "GSMTAP, unknown version (%u)", version); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSMTAP"); + col_clear(pinfo->cinfo, COL_INFO); + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown GSMTAP version (%u)", version); + gsmtap_tree = proto_item_add_subtree(ti, ett_gsmtap); + tf = proto_tree_add_item(gsmtap_tree, hf_gsmtap_version, tvb, 0, 1, ENC_BIG_ENDIAN); + expert_add_info(pinfo, tf, &ei_gsmtap_unknown_gsmtap_version); + return 1; +} + void proto_register_gsmtap(void) { @@ -1184,7 +1213,7 @@ proto_register_gsmtap(void) { &hf_gsmtap_version, { "Version", "gsmtap.version", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_gsmtap_hdrlen, { "Header Length", "gsmtap.hdr_len", - FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_byte_bytes, 0, NULL, HFILL } }, + FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0, NULL, HFILL } }, { &hf_gsmtap_type, { "Payload Type", "gsmtap.type", FT_UINT8, BASE_DEC, VALS(gsmtap_types), 0, NULL, HFILL } }, { &hf_gsmtap_timeslot, { "Time Slot", "gsmtap.ts", @@ -1196,9 +1225,9 @@ proto_register_gsmtap(void) { &hf_gsmtap_pcs, { "PCS band indicator", "gsmtap.pcs_band", FT_UINT16, BASE_DEC, NULL, GSMTAP_ARFCN_F_PCS, NULL, HFILL } }, { &hf_gsmtap_signal_dbm, { "Signal Level", "gsmtap.signal_dbm", - FT_INT8, BASE_DEC | BASE_UNIT_STRING, &units_dbm, 0, NULL, HFILL } }, + FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_dbm), 0, NULL, HFILL } }, { &hf_gsmtap_snr_db, { "Signal/Noise Ratio", "gsmtap.snr_db", - FT_INT8, BASE_DEC | BASE_UNIT_STRING, &units_decibels, 0, NULL, HFILL } }, + FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_decibels), 0, NULL, HFILL } }, { &hf_gsmtap_frame_nr, { "GSM Frame Number", "gsmtap.frame_nr", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_gsmtap_burst_type, { "Burst Type", "gsmtap.burst_type", @@ -1239,13 +1268,20 @@ proto_register_gsmtap(void) { &hf_ptcch_padding, { "Spare Padding", "gsmtap.ptcch.padding", FT_BYTES, SEP_SPACE, NULL, 0, NULL, HFILL } }, }; - static gint *ett[] = { + static int *ett[] = { &ett_gsmtap }; + static ei_register_info ei[] = { + { &ei_gsmtap_unknown_gsmtap_version, { "gsmtap.version.invalid", PI_PROTOCOL, PI_WARN, "Unknown protocol version", EXPFILL }}, + }; + + expert_module_t* expert_gsmtap; proto_gsmtap = proto_register_protocol("GSM Radiotap", "GSMTAP", "gsmtap"); proto_register_field_array(proto_gsmtap, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + expert_gsmtap = expert_register_protocol(proto_gsmtap); + expert_register_field_array(expert_gsmtap, ei, array_length(ei)); gsmtap_dissector_table = register_dissector_table("gsmtap.type", "GSMTAP type", proto_gsmtap, FT_UINT8, BASE_HEX); |