* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
static int hf_catapult_dct2000_sctpprim_addr_v6 = -1;
static int hf_catapult_dct2000_sctpprim_dst_port = -1;
-static int hf_catapult_dct2000_lte_ueid = -1;
-static int hf_catapult_dct2000_lte_srbid = -1;
-static int hf_catapult_dct2000_lte_drbid = -1;
-static int hf_catapult_dct2000_lte_cellid = -1;
-static int hf_catapult_dct2000_lte_bcch_transport = -1;
-static int hf_catapult_dct2000_lte_rlc_op = -1;
-static int hf_catapult_dct2000_lte_rlc_channel_type = -1;
-static int hf_catapult_dct2000_lte_rlc_mui = -1;
-static int hf_catapult_dct2000_lte_rlc_cnf = -1;
-static int hf_catapult_dct2000_lte_rlc_discard_req = -1;
+static int hf_catapult_dct2000_ueid = -1;
+static int hf_catapult_dct2000_srbid = -1;
+static int hf_catapult_dct2000_drbid = -1;
+static int hf_catapult_dct2000_cellid = -1;
+static int hf_catapult_dct2000_bcch_transport = -1;
+static int hf_catapult_dct2000_rlc_op = -1;
+static int hf_catapult_dct2000_rlc_channel_type = -1;
+static int hf_catapult_dct2000_rlc_mui = -1;
+static int hf_catapult_dct2000_rlc_cnf = -1;
+static int hf_catapult_dct2000_rlc_discard_req = -1;
static int hf_catapult_dct2000_lte_ccpri_opcode = -1;
static int hf_catapult_dct2000_lte_ccpri_status = -1;
static int hf_catapult_dct2000_lte_nas_rrc_priority = -1;
static int hf_catapult_dct2000_lte_nas_rrc_release_cause = -1;
+static int hf_catapult_dct2000_nr_nas_s1ap_opcode = -1;
/* UMTS RLC fields */
-static int hf_catapult_dct2000_ueid = -1;
static int hf_catapult_dct2000_rbid = -1;
static int hf_catapult_dct2000_ccch_id = -1;
static int hf_catapult_dct2000_no_crc_error = -1;
static gboolean catapult_dct2000_try_ipprim_heuristic = TRUE;
static gboolean catapult_dct2000_try_sctpprim_heuristic = TRUE;
static gboolean catapult_dct2000_dissect_lte_rrc = TRUE;
-static gboolean catapult_dct2000_dissect_lte_s1ap = TRUE;
static gboolean catapult_dct2000_dissect_mac_lte_oob_messages = TRUE;
+static gboolean catapult_dct2000_dissect_old_protocol_names = FALSE;
/* Protocol subtree. */
static int ett_catapult_dct2000 = -1;
};
+#define NAS_S1AP_DATA_REQ 0x00
+#define NAS_S1AP_DATA_IND 0x01
+
+static const value_string nas_s1ap_opcode_vals[] = {
+ { NAS_S1AP_DATA_REQ, "Data-Req"},
+ { NAS_S1AP_DATA_IND, "Data-Ind"},
+ { 0, NULL}
+};
+
+
+/* Distinguish between similar 4G or 5G protocols */
+enum LTE_or_NR {
+ LTE,
+ NR
+};
+
#define MAX_OUTHDR_VALUES 32
+
/* Return the number of bytes used to encode the length field
(we're not interested in the length value itself) */
static int skipASNLength(guint8 value)
switch (tag) {
case 0x72: /* UE Id */
ueid = tvb_get_ntohl(tvb, offset);
- proto_tree_add_item(tree, hf_catapult_dct2000_ueid, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
+ offset += 2;
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
ueid_set = TRUE;
break;
case 0xa2: /* RBID */
-/* Dissect an RRC LTE frame by first parsing the header entries then passing
- the data to the RRC dissector, according to direction and channel type.
- TODO: factor out common code between this function and dissect_pdcp_lte() */
-static void dissect_rrc_lte(tvbuff_t *tvb, gint offset,
- packet_info *pinfo, proto_tree *tree)
+/* Dissect an RRC LTE or NR frame by first parsing the header entries then passing
+ the data to the RRC dissector, according to direction and channel type. */
+static void dissect_rrc_lte_nr(tvbuff_t *tvb, gint offset,
+ packet_info *pinfo, proto_tree *tree,
+ enum LTE_or_NR lte_or_nr)
{
- guint8 tag;
+ guint8 opcode, tag;
dissector_handle_t protocol_handle = 0;
gboolean isUplink = FALSE;
LogicalChannelType logicalChannelType;
tvbuff_t *rrc_tvb;
/* Top-level opcode */
- tag = tvb_get_guint8(tvb, offset++);
- switch (tag) {
+ opcode = tvb_get_guint8(tvb, offset++);
+ switch (opcode) {
case 0x00: /* Data_Req_UE */
+ case 0x05: /* Data_Req_UE_SM */
case 0x04: /* Data_Ind_eNodeB */
isUplink = TRUE;
break;
case 0x02: /* Data_Req_eNodeB */
case 0x03: /* Data_Ind_UE */
+ case 0x07: /* Data_Ind_UE_SM */
isUplink = FALSE;
break;
tag = tvb_get_guint8(tvb, offset++);
switch (tag) {
case 0x12: /* UE_Id_LCId */
-
+ {
/* Dedicated channel info */
/* Length will fit in one byte here */
- offset++;
+ guint len = tvb_get_guint8(tvb, offset++);
+ guint len_offset = offset;
logicalChannelType = Channel_DCCH;
/* UEId */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Get tag of channel type */
offset++;
col_append_fstr(pinfo->cinfo, COL_INFO, " SRB:%u",
tvb_get_guint8(tvb, offset));
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_srbid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_srbid,
tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
break;
offset++;
col_append_fstr(pinfo->cinfo, COL_INFO, " DRB:%u",
tvb_get_guint8(tvb, offset));
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_drbid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_drbid,
tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
break;
/* Unexpected channel type */
return;
}
+
+ /* Optional Carrier Type */
+ if (((offset-len_offset) < len) && tvb_get_guint8(tvb, offset)==0x20) {
+ offset++;
+ /* TODO: could show in tree, but for now skip */
+ offset += (1+tvb_get_guint8(tvb, offset));
+ }
+
break;
+ }
case 0x1a: /* Cell_LCId */
offset++;
/* Cell-id */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_cellid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_cellid,
tvb, offset, 2, ENC_BIG_ENDIAN);
cell_id = tvb_get_ntohs(tvb, offset);
offset += 2;
/* Logical channel type */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_channel_type,
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_channel_type,
tvb, offset, 1, ENC_BIG_ENDIAN);
logicalChannelType = (LogicalChannelType)tvb_get_guint8(tvb, offset);
offset++;
/* Transport channel type */
bcch_transport = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_bcch_transport,
+ proto_tree_add_item(tree, hf_catapult_dct2000_bcch_transport,
tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
break;
offset++;
/* UEId */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
return;
}
- /* Data tag should follow */
+ if (opcode == 0x07) {
+ /* Data_Ind_UE_SM - 1 byte MAC */
+ offset++;
+ }
+ else if (opcode == 0x05) {
+ /* Data_Req_UE_SM - skip SecurityMode Params */
+ offset++; /* tag */
+ guint8 len = tvb_get_guint8(tvb, offset); /* length */
+ offset += len;
+ }
+
+ /* Optional data tag may follow */
+ if (!tvb_reported_length_remaining(tvb, offset)) {
+ return;
+ }
tag = tvb_get_guint8(tvb, offset++);
if (tag != 0xaa) {
return;
/* Uplink channel types */
switch (logicalChannelType) {
case Channel_DCCH:
- protocol_handle = find_dissector("lte_rrc.ul_dcch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.ul_dcch");
+ }
+ else {
+ protocol_handle = find_dissector("nr-rrc.ul.dcch");
+ }
break;
case Channel_CCCH:
- protocol_handle = find_dissector("lte_rrc.ul_ccch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.ul_ccch");
+ }
break;
default:
/* Downlink channel types */
switch (logicalChannelType) {
case Channel_DCCH:
- protocol_handle = find_dissector("lte_rrc.dl_dcch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.dl_dcch");
+ }
+ else {
+ protocol_handle = find_dissector("nr-rrc.dl.dcch");
+ }
break;
case Channel_CCCH:
- protocol_handle = find_dissector("lte_rrc.dl_ccch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.dl_ccch");
+ }
break;
case Channel_PCCH:
- protocol_handle = find_dissector("lte_rrc.pcch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.pcch");
+ }
break;
case Channel_BCCH:
if (bcch_transport == 1) {
- protocol_handle = find_dissector("lte_rrc.bcch_bch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.bcch_bch");
+ }
+ else {
+ protocol_handle = find_dissector("nr-rrc.bcch.bch");
+ }
}
else {
- protocol_handle = find_dissector("lte_rrc.bcch_dl_sch");
+ if (lte_or_nr == LTE) {
+ protocol_handle = find_dissector("lte_rrc.bcch_dl_sch");
+ }
}
break;
offset += 2;
/* Cell-id */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_cellid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_cellid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Top-level opcode */
opcode = tvb_get_guint8(tvb, offset);
if (tree) {
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_op, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_op, tvb, offset, 1, ENC_BIG_ENDIAN);
}
offset++;
/* UEId */
ueid = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid, tvb, offset, 2, ENC_BIG_ENDIAN);
col_append_fstr(pinfo->cinfo, COL_INFO,
" UEId=%u", ueid);
p_pdcp_lte_info->ueid = ueid;
channelId = tvb_get_guint8(tvb, offset);
col_append_fstr(pinfo->cinfo, COL_INFO, " SRB:%u",
channelId);
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_srbid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_srbid,
tvb, offset++, 1, ENC_BIG_ENDIAN);
p_pdcp_lte_info->channelId = channelId;
break;
channelId = tvb_get_guint8(tvb, offset);
col_append_fstr(pinfo->cinfo, COL_INFO, " DRB:%u",
channelId);
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_drbid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_drbid,
tvb, offset++, 1, ENC_BIG_ENDIAN);
p_pdcp_lte_info->channelId = channelId;
break;
offset++;
/* Cell-id */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_cellid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_cellid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Logical channel type */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_channel_type,
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_channel_type,
tvb, offset, 1, ENC_BIG_ENDIAN);
p_pdcp_lte_info->channelType = (LogicalChannelType)tvb_get_guint8(tvb, offset++);
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
/* Transport channel type */
p_pdcp_lte_info->BCCHTransport = (BCCHTransportType)tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_bcch_transport,
+ proto_tree_add_item(tree, hf_catapult_dct2000_bcch_transport,
tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
break;
offset++;
/* UEId */
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
tvb, offset, 2, ENC_BIG_ENDIAN);
ueid = tvb_get_ntohs(tvb, offset);
offset += 2;
if (tag == 0x35) {
/* This is MUI */
offset++;
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_mui,
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_mui,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* CNF follows MUI in AM */
if ((opcode == RLC_AM_DATA_REQ) || (opcode == RLC_AM_DATA_IND)) {
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_cnf,
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_cnf,
tvb, offset, 1, ENC_NA);
offset++;
}
else if (tag == 0x45) {
/* Discard Req */
offset++;
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_rlc_discard_req,
+ proto_tree_add_item(tree, hf_catapult_dct2000_rlc_discard_req,
tvb, offset, 1, ENC_NA);
offset++;
}
This includes exact matches and prefixes (e.g. "diameter_rx" -> "diameter") */
static dissector_handle_t look_for_dissector(const char *protocol_name)
{
- /* Use known aliases and protocol name prefixes */
- if (strcmp(protocol_name, "tbcp") == 0) {
- return find_dissector("rtcp");
- }
- else
if (strncmp(protocol_name, "diameter", strlen("diameter")) == 0) {
return find_dissector("diameter");
}
else
- if ((strcmp(protocol_name, "xcap_caps") == 0) ||
- (strcmp(protocol_name, "soap") == 0) ||
- (strcmp(protocol_name, "mm1") == 0) ||
- (strcmp(protocol_name, "mm3") == 0) ||
- (strcmp(protocol_name, "mm7") == 0)) {
-
- return find_dissector("http");
- }
- else
- if ((strncmp(protocol_name, "fp_r", 4) == 0) ||
- (strcmp(protocol_name, "fpiur_r5") == 0)) {
-
- return find_dissector("fp");
- }
- else
- if (strncmp(protocol_name, "iuup_rtp_r", strlen("iuup_rtp_r")) == 0) {
- return find_dissector("rtp");
- }
- else
- if (strcmp(protocol_name, "sipt") == 0) {
- return find_dissector("sip");
- }
- else
- if (strncmp(protocol_name, "nbap_sctp", strlen("nbap_sctp")) == 0) {
- return find_dissector("nbap");
- }
- else
- if (strncmp(protocol_name, "gtp", strlen("gtp")) == 0) {
- return find_dissector("gtp");
- }
- else
- if (strcmp(protocol_name, "dhcpv4") == 0) {
- return find_dissector("bootp");
- }
- else
- if (strcmp(protocol_name, "wimax") == 0) {
- return find_dissector("wimaxasncp");
- }
- else
- if (strncmp(protocol_name, "sabp", strlen("sabp")) == 0) {
- return find_dissector("sabp");
- }
- else
- if (strcmp(protocol_name, "wtp") == 0) {
- return find_dissector("wtp-udp");
+ if (strncmp(protocol_name, "gtpv2_r", 7) == 0) {
+ return find_dissector("gtpv2");
}
else
- /* Only match with s1ap if preference turned on */
- if (catapult_dct2000_dissect_lte_s1ap &&
- strncmp(protocol_name, "s1ap", strlen("s1ap")) == 0) {
-
+ if (strncmp(protocol_name, "s1ap", 4) == 0) {
return find_dissector("s1ap");
}
else
- /* Always try lookup for now */
- if ((strncmp(protocol_name, "x2ap_r8_lte", strlen("x2ap_r8_lte")) == 0) ||
- (strncmp(protocol_name, "x2ap_r9_lte", strlen("x2ap_r9_lte")) == 0)) {
-
+ if (strncmp(protocol_name, "x2ap_r", 6) == 0) {
return find_dissector("x2ap");
}
- else
- if ((strcmp(protocol_name, "gtpv2_r8_lte") == 0) ||
- (strcmp(protocol_name, "gtpv2_r9_lte") == 0)) {
- return find_dissector("gtpv2");
- }
+ /* Only check really old names to convert if preference is checked */
+ else if (catapult_dct2000_dissect_old_protocol_names) {
+ /* Use known aliases and protocol name prefixes */
+ if (strcmp(protocol_name, "tbcp") == 0) {
+ return find_dissector("rtcp");
+ }
+ else
+ if ((strcmp(protocol_name, "xcap_caps") == 0) ||
+ (strcmp(protocol_name, "soap") == 0) ||
+ (strcmp(protocol_name, "mm1") == 0) ||
+ (strcmp(protocol_name, "mm3") == 0) ||
+ (strcmp(protocol_name, "mm7") == 0)) {
- /* Try for an exact match */
- else {
- return find_dissector(protocol_name);
+ return find_dissector("http");
+ }
+ else
+ if ((strncmp(protocol_name, "fp_r", 4) == 0) ||
+ (strcmp(protocol_name, "fpiur_r5") == 0)) {
+
+ return find_dissector("fp");
+ }
+ else
+ if (strncmp(protocol_name, "iuup_rtp_r", strlen("iuup_rtp_r")) == 0) {
+ return find_dissector("rtp");
+ }
+ else
+ if (strcmp(protocol_name, "sipt") == 0) {
+ return find_dissector("sip");
+ }
+ else
+ if (strncmp(protocol_name, "nbap_sctp", strlen("nbap_sctp")) == 0) {
+ return find_dissector("nbap");
+ }
+ else
+ if (strcmp(protocol_name, "dhcpv4") == 0) {
+ return find_dissector("dhcp");
+ }
+ else
+ if (strcmp(protocol_name, "wimax") == 0) {
+ return find_dissector("wimaxasncp");
+ }
+ else
+ if (strncmp(protocol_name, "sabp", strlen("sabp")) == 0) {
+ return find_dissector("sabp");
+ }
+ else
+ if (strcmp(protocol_name, "wtp") == 0) {
+ return find_dissector("wtp-udp");
+ }
+ else
+ if (strncmp(protocol_name, "gtp", strlen("gtp")) == 0) {
+ return find_dissector("gtp");
+ }
}
+
+ /* Try for an exact match */
+ return find_dissector(protocol_name);
}
/* Populate the struct from outhdr values */
p_mac_lte_info->crcStatusValid = FALSE; /* not set yet */
- p_mac_lte_info->radioType = outhdr_values[i++] + 1;
- p_mac_lte_info->rntiType = outhdr_values[i++];
- p_mac_lte_info->direction = outhdr_values[i++];
+ p_mac_lte_info->radioType = outhdr_values[i++] + 1; // 1
+ p_mac_lte_info->rntiType = outhdr_values[i++]; // 2
+ p_mac_lte_info->direction = outhdr_values[i++]; // 3
/* Set these extra PHY present flags to FALSE by default */
if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
p_mac_lte_info->detailed_phy_info.ul_info.present = FALSE;
p_mac_lte_info->detailed_phy_info.dl_info.present = FALSE;
}
- p_mac_lte_info->subframeNumber = outhdr_values[i++];
- p_mac_lte_info->isPredefinedData = outhdr_values[i++];
- p_mac_lte_info->rnti = outhdr_values[i++];
- p_mac_lte_info->ueid = outhdr_values[i++];
- p_mac_lte_info->length = outhdr_values[i++];
+ p_mac_lte_info->sfnSfInfoPresent = TRUE;
+ p_mac_lte_info->subframeNumber = outhdr_values[i++]; // 4
+ p_mac_lte_info->isPredefinedData = outhdr_values[i++]; // 5
+ p_mac_lte_info->rnti = outhdr_values[i++]; // 6
+ p_mac_lte_info->ueid = outhdr_values[i++]; // 7
+ p_mac_lte_info->length = outhdr_values[i++]; // 8
if (outhdr_values_found > 8) {
- p_mac_lte_info->reTxCount = outhdr_values[i++];
+ p_mac_lte_info->reTxCount = outhdr_values[i++]; // 9
}
+ /* TODO: delete if won't see this special case anymore? */
if (outhdr_values_found == 10) {
/* CRC only valid for Downlink */
if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
p_mac_lte_info->crcStatusValid = TRUE;
- p_mac_lte_info->crcStatus = (mac_lte_crc_status)outhdr_values[i++];
+ p_mac_lte_info->crcStatus = (mac_lte_crc_status)outhdr_values[i++]; // 10
}
else {
- i++;
+ i++; // 10 (ignoring for UL)
}
}
if (outhdr_values_found > 10) {
/* Extra PHY parameters */
if (p_mac_lte_info->direction == DIRECTION_DOWNLINK) {
- p_mac_lte_info->detailed_phy_info.dl_info.present = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.dci_format = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.mcs_index = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index = outhdr_values[i++];
- if (outhdr_values[i++]) {
- p_mac_lte_info->dl_retx = dl_retx_yes;
- }
- else {
- p_mac_lte_info->dl_retx = dl_retx_no;
- }
- p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length = outhdr_values[i++];
- p_mac_lte_info->crcStatusValid = TRUE;
+ p_mac_lte_info->detailed_phy_info.dl_info.present = outhdr_values[i++]; // 10
+ p_mac_lte_info->detailed_phy_info.dl_info.dci_format = outhdr_values[i++]; // 11
+ p_mac_lte_info->detailed_phy_info.dl_info.resource_allocation_type = outhdr_values[i++]; // 12
+ p_mac_lte_info->detailed_phy_info.dl_info.aggregation_level = outhdr_values[i++]; // 13
+ p_mac_lte_info->detailed_phy_info.dl_info.mcs_index = outhdr_values[i++]; // 14
+ p_mac_lte_info->detailed_phy_info.dl_info.redundancy_version_index = outhdr_values[i++]; // 15
+ p_mac_lte_info->dl_retx = (outhdr_values[i++]) ? dl_retx_yes : dl_retx_no; // 16
+
+ p_mac_lte_info->detailed_phy_info.dl_info.resource_block_length = outhdr_values[i++]; // 17
+ p_mac_lte_info->crcStatusValid = TRUE; // 18
p_mac_lte_info->crcStatus = (mac_lte_crc_status)outhdr_values[i++];
if (outhdr_values_found > 18) {
- p_mac_lte_info->detailed_phy_info.dl_info.harq_id = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.dl_info.ndi = outhdr_values[i++];
+ p_mac_lte_info->detailed_phy_info.dl_info.harq_id = outhdr_values[i++]; // 19
+ p_mac_lte_info->detailed_phy_info.dl_info.ndi = outhdr_values[i++]; // 20
}
if (outhdr_values_found > 20) {
- p_mac_lte_info->detailed_phy_info.dl_info.transport_block = outhdr_values[i++];
+ p_mac_lte_info->detailed_phy_info.dl_info.transport_block = outhdr_values[i++]; // 21
}
}
else {
/* Uplink */
- p_mac_lte_info->detailed_phy_info.ul_info.present = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.ul_info.modulation_type = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.ul_info.tbs_index = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start = outhdr_values[i++];
+ p_mac_lte_info->detailed_phy_info.ul_info.present = outhdr_values[i++]; // 10
+ p_mac_lte_info->detailed_phy_info.ul_info.modulation_type = outhdr_values[i++]; // 11
+ p_mac_lte_info->detailed_phy_info.ul_info.tbs_index = outhdr_values[i++]; // 12
+ p_mac_lte_info->detailed_phy_info.ul_info.resource_block_length = outhdr_values[i++]; // 13
+ p_mac_lte_info->detailed_phy_info.ul_info.resource_block_start = outhdr_values[i++]; // 14
/* Skip retx flag */
- i++;
+ i++; // 15
+ /* TODO: delete if won't see this special case anymore? */
if (outhdr_values_found == 16) {
p_mac_lte_info->subframeNumberOfGrantPresent = TRUE;
- p_mac_lte_info->subframeNumberOfGrant = outhdr_values[i++];
+ p_mac_lte_info->subframeNumberOfGrant = outhdr_values[i++]; // 16
}
if (outhdr_values_found > 16) {
- p_mac_lte_info->detailed_phy_info.ul_info.harq_id = outhdr_values[i++];
- p_mac_lte_info->detailed_phy_info.ul_info.ndi = outhdr_values[i++];
+ p_mac_lte_info->detailed_phy_info.ul_info.harq_id = outhdr_values[i++]; // 16
+ p_mac_lte_info->detailed_phy_info.ul_info.ndi = outhdr_values[i++]; // 17
p_mac_lte_info->subframeNumberOfGrantPresent = TRUE;
- p_mac_lte_info->subframeNumberOfGrant = outhdr_values[i++];
+ p_mac_lte_info->subframeNumberOfGrant = outhdr_values[i++]; // 18
}
}
}
if ((p_mac_lte_info->direction == DIRECTION_UPLINK) &&
(i < outhdr_values_found)) {
- p_mac_lte_info->isPHICHNACK = outhdr_values[i];
+ p_mac_lte_info->isPHICHNACK = outhdr_values[i++];
}
if (p_mac_lte_info->direction == DIRECTION_UPLINK) {
p_mac_lte_info->isExtendedBSRSizes = FALSE;
}
+ if (i < outhdr_values_found) {
+ /* Carrier ID */
+ p_mac_lte_info->carrierId = (mac_lte_carrier_id)outhdr_values[i++];
+ }
+
+ /* Remaining fields not (yet?) supported in
+ the mac-lte dissector. */
+ if (i++ < outhdr_values_found) {
+ /* Serving cell index */
+ }
+ if (i < outhdr_values_found) {
+ /* UE Type */
+ }
+
/* Store info in packet */
set_mac_lte_proto_data(pinfo, p_mac_lte_info);
}
struct mac_lte_info *p_mac_lte_info;
guint16 n;
- /* Look for strings matching expected formats */
- if (sscanf(string, ">> RACH Preamble Request[UE = %u] [RAPID = %u] [Attempt = %u]",
- &ueids[0], &rapid, &rach_attempt_number) == 3) {
+ /* Current strings of interest begin with ">> ", so if don't see, avoid sscanf() calls. */
+ if (strncmp(string, ">> ", 3) != 0) {
+ return;
+ }
+
+ /*********************************************/
+ /* Look for strings matching formats */
+
+ /* RACH Preamble request */
+ if (sscanf(string, ">> RACH Preamble Request [CarrierId=%u] [LTE UE = %u] [RAPID = %u] [Attempt = %u",
+ &temp, &ueids[0], &rapid, &rach_attempt_number) == 4) {
oob_event = ltemac_send_preamble;
}
- else
- if (sscanf(string, ">> Schedule Requests (%u) [UE=%u][RNTI=%u]",
- &number_of_ues, &ueids[0], &rntis[0]) == 3) {
+
+ /* Scheduling Requests */
+ else if (sscanf(string, ">> Schedule Requests (%u) [CarrierId=%u][UE=%u][RNTI=%u]",
+ &number_of_ues, &temp, &ueids[0], &rntis[0]) == 4) {
const char *current_position;
/* Newer, multi-UE format */
}
}
}
- else
- /* Support both old and new formats of SR failure */
- if ((sscanf(string, ">> INFO (inst %u) MAC: [UE = %u] SR failed (CRNTI=%u)",
- &temp, &ueids[0], &rntis[0]) == 3) ||
- (sscanf(string, ">> INFO MAC: SR failed for UE %u (CRNTI=%u",
- &ueids[0], &rntis[0]) == 2))
- {
+
+ /* SR failures */
+ else if (sscanf(string, ">> INFO (inst %u) MAC: [UE = %u] SR failed (CRNTI=%u)",
+ &temp, &ueids[0], &rntis[0]) == 3) {
oob_event = ltemac_sr_failure;
}
- else {
- /* No events found */
- return;
- }
- /* We have an event */
- /* Only need to set info once per session. */
- p_mac_lte_info = get_mac_lte_proto_data(pinfo);
- if (p_mac_lte_info == NULL) {
+ /* No events found */
+ else return;
- /* Allocate & zero struct */
- p_mac_lte_info = wmem_new0(wmem_file_scope(), mac_lte_info);
- /* This indicates to MAC dissector that it has an oob event */
- p_mac_lte_info->length = 0;
+ /********************************************/
+ /* We have an event. Allocate & zero struct */
+ p_mac_lte_info = wmem_new0(wmem_file_scope(), mac_lte_info);
- switch (oob_event) {
- case ltemac_send_preamble:
- p_mac_lte_info->ueid = ueids[0];
- p_mac_lte_info->rapid = rapid;
- p_mac_lte_info->rach_attempt_number = rach_attempt_number;
- p_mac_lte_info->direction = DIRECTION_UPLINK;
- break;
- case ltemac_send_sr:
- for (n=0; n < number_of_ues; n++) {
- p_mac_lte_info->oob_ueid[n] = ueids[n];
- p_mac_lte_info->oob_rnti[n] = rntis[n];
- }
- p_mac_lte_info->number_of_srs = number_of_ues;
- p_mac_lte_info->direction = DIRECTION_UPLINK;
- break;
- case ltemac_sr_failure:
- p_mac_lte_info->rnti = rntis[0];
- p_mac_lte_info->ueid = ueids[0];
- p_mac_lte_info->direction = DIRECTION_DOWNLINK;
- break;
- }
-
- p_mac_lte_info->radioType = FDD_RADIO; /* TODO: will be the same as rest of log... */
- p_mac_lte_info->oob_event = oob_event;
+ /* This indicates to MAC dissector that it has an oob event */
+ p_mac_lte_info->length = 0;
- /* Store info in packet */
- set_mac_lte_proto_data(pinfo, p_mac_lte_info);
+ switch (oob_event) {
+ case ltemac_send_preamble:
+ p_mac_lte_info->ueid = ueids[0];
+ p_mac_lte_info->rapid = rapid;
+ p_mac_lte_info->rach_attempt_number = rach_attempt_number;
+ p_mac_lte_info->direction = DIRECTION_UPLINK;
+ break;
+ case ltemac_send_sr:
+ for (n=0; n < number_of_ues; n++) {
+ p_mac_lte_info->oob_ueid[n] = ueids[n];
+ p_mac_lte_info->oob_rnti[n] = rntis[n];
+ }
+ p_mac_lte_info->number_of_srs = number_of_ues;
+ p_mac_lte_info->direction = DIRECTION_UPLINK;
+ break;
+ case ltemac_sr_failure:
+ p_mac_lte_info->rnti = rntis[0];
+ p_mac_lte_info->ueid = ueids[0];
+ p_mac_lte_info->direction = DIRECTION_DOWNLINK;
+ break;
}
+ p_mac_lte_info->radioType = FDD_RADIO; /* TODO: will be the same as rest of log... */
+ p_mac_lte_info->sfnSfInfoPresent = FALSE; /* We don't have this */
+ p_mac_lte_info->oob_event = oob_event;
+
+ /* Store info in packet */
+ set_mac_lte_proto_data(pinfo, p_mac_lte_info);
+
/* Call MAC dissector */
call_dissector_only(mac_lte_handle, tvb, pinfo, tree, NULL);
}
attach_pdcp_lte_info(pinfo, outhdr_values, outhdr_values_found);
}
-
else if ((strcmp(protocol_name, "nas_rrc_r8_lte") == 0) ||
(strcmp(protocol_name, "nas_rrc_r9_lte") == 0) ||
- (strcmp(protocol_name, "nas_rrc_r10_lte") == 0)) {
+ (strcmp(protocol_name, "nas_rrc_r10_lte") == 0) ||
+ (strcmp(protocol_name, "nas_rrc_r13_lte") == 0) ||
+ (strcmp(protocol_name, "nas_rrc_r15_5gnr") == 0)) {
gboolean nas_body_found = TRUE;
guint8 opcode = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_catapult_dct2000_lte_nas_rrc_opcode,
/* UEId */
offset++; /* tag */
offset += 2; /* 2 wasted bytes of UEId*/
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
/* UEId */
offset++; /* tag */
offset += 2; /* 2 wasted bytes of UEId*/
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* UEId */
offset++; /* tag */
offset += 2; /* 2 wasted bytes of UEId*/
- proto_tree_add_item(tree, hf_catapult_dct2000_lte_ueid,
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
}
- /* Look up dissector if if looks right */
+ /* Look up dissector if it looks right */
if (nas_body_found) {
offset += 2; /* L3 tag + len */
- protocol_handle = find_dissector("nas-eps");
+ if (strcmp(protocol_name, "nas_rrc_r15_5gnr") == 0) {
+ protocol_handle = find_dissector("nas-5gs");
+ }
+ else {
+ protocol_handle = find_dissector("nas-eps");
+ }
}
}
+ /* NR NAS for S1AP */
+ else if (strcmp(protocol_name, "nas_s1ap_r15_5gnr") == 0) {
+ guint8 opcode = tvb_get_guint8(tvb, offset);
+ if (opcode <= NAS_S1AP_DATA_IND) {
+ /* Opcode tag (only interested in ones that carry NAS PDU) */
+ proto_tree_add_item(tree, hf_catapult_dct2000_nr_nas_s1ap_opcode,
+ tvb, offset++, 1, ENC_BIG_ENDIAN);
+
+ /* Skip overall length */
+ offset += skipASNLength(tvb_get_guint8(tvb, offset));
+
+ /* UE Id. Skip tag and fixed length */
+ offset += 2;
+ proto_tree_add_item(tree, hf_catapult_dct2000_ueid,
+ tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ /* NAS PDU tag is 2 bytes */
+ guint16 data_tag = tvb_get_ntohs(tvb, offset);
+ if (data_tag == 0x0021) {
+ offset += 2;
+ /* Also skip length */
+ offset += 2;
+ protocol_handle = find_dissector("nas-5gs");
+
+ /* N.B. Ignoring some optional fields after the NAS PDU */
+ }
+ }
+ }
+
+
/* Note that the first item of pinfo->pseudo_header->dct2000 will contain
the pseudo-header needed (in some cases) by the Wireshark dissector that
this packet data will be handed off to. */
return tvb_captured_length(tvb);
}
-
+ /* RRC (LTE or NR).
+ Dissect proprietary header, then pass remainder
+ to RRC dissector (depending upon direction and channel type) */
else
if (catapult_dct2000_dissect_lte_rrc &&
((strcmp(protocol_name, "rrc_r8_lte") == 0) ||
(strcmp(protocol_name, "rrcpdcpprim_r8_lte") == 0) ||
(strcmp(protocol_name, "rrc_r9_lte") == 0) ||
(strcmp(protocol_name, "rrcpdcpprim_r9_lte") == 0) ||
- (strcmp(protocol_name, "rrc_r10_lte") == 0))) {
+ (strcmp(protocol_name, "rrc_r10_lte") == 0) ||
+ (strcmp(protocol_name, "rrc_r11_lte") == 0) ||
+ (strcmp(protocol_name, "rrc_r12_lte") == 0) ||
+ (strcmp(protocol_name, "rrc_r13_lte") == 0) ||
+ (strcmp(protocol_name, "rrc_r15_lte") == 0))) {
- /* Dissect proprietary header, then pass remainder
- to RRC (depending upon direction and channel type) */
- dissect_rrc_lte(tvb, offset, pinfo, tree);
+ dissect_rrc_lte_nr(tvb, offset, pinfo, tree, LTE);
+ return tvb_captured_length(tvb);
+ }
+ else if (strcmp(protocol_name, "rrc_r15_5g") == 0) {
+
+ dissect_rrc_lte_nr(tvb, offset, pinfo, tree, NR);
return tvb_captured_length(tvb);
}
}
},
- { &hf_catapult_dct2000_lte_ueid,
+ { &hf_catapult_dct2000_ueid,
{ "UE Id",
- "dct2000.lte.ueid", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "dct2000.ueid", FT_UINT16, BASE_DEC, NULL, 0x0,
"User Equipment Identifier", HFILL
}
},
- { &hf_catapult_dct2000_lte_srbid,
+ { &hf_catapult_dct2000_srbid,
{ "srbid",
- "dct2000.lte.srbid", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "dct2000.srbid", FT_UINT8, BASE_DEC, NULL, 0x0,
"Signalling Radio Bearer Identifier", HFILL
}
},
- { &hf_catapult_dct2000_lte_drbid,
+ { &hf_catapult_dct2000_drbid,
{ "drbid",
- "dct2000.lte.drbid", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "dct2000.drbid", FT_UINT8, BASE_DEC, NULL, 0x0,
"Data Radio Bearer Identifier", HFILL
}
},
- { &hf_catapult_dct2000_lte_cellid,
+ { &hf_catapult_dct2000_cellid,
{ "Cell-Id",
- "dct2000.lte.cellid", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "dct2000.cellid", FT_UINT16, BASE_DEC, NULL, 0x0,
"Cell Identifier", HFILL
}
},
- { &hf_catapult_dct2000_lte_bcch_transport,
+ { &hf_catapult_dct2000_bcch_transport,
{ "BCCH Transport",
- "dct2000.lte.bcch-transport", FT_UINT16, BASE_DEC, VALS(bcch_transport_vals), 0x0,
+ "dct2000.bcch-transport", FT_UINT16, BASE_DEC, VALS(bcch_transport_vals), 0x0,
"BCCH Transport Channel", HFILL
}
},
- { &hf_catapult_dct2000_lte_rlc_op,
+ { &hf_catapult_dct2000_rlc_op,
{ "RLC Op",
- "dct2000.lte.rlc-op", FT_UINT8, BASE_DEC, VALS(rlc_op_vals), 0x0,
+ "dct2000.rlc-op", FT_UINT8, BASE_DEC, VALS(rlc_op_vals), 0x0,
"RLC top-level op", HFILL
}
},
- { &hf_catapult_dct2000_lte_rlc_channel_type,
+ { &hf_catapult_dct2000_rlc_channel_type,
{ "RLC Logical Channel Type",
- "dct2000.lte.rlc-logchan-type", FT_UINT8, BASE_DEC, VALS(rlc_logical_channel_vals), 0x0,
+ "dct2000.rlc-logchan-type", FT_UINT8, BASE_DEC, VALS(rlc_logical_channel_vals), 0x0,
NULL, HFILL
}
},
- { &hf_catapult_dct2000_lte_rlc_mui,
+ { &hf_catapult_dct2000_rlc_mui,
{ "MUI",
- "dct2000.lte.rlc-mui", FT_UINT16, BASE_DEC, NULL, 0x0,
+ "dct2000.rlc-mui", FT_UINT16, BASE_DEC, NULL, 0x0,
"RLC MUI", HFILL
}
},
- { &hf_catapult_dct2000_lte_rlc_cnf,
+ { &hf_catapult_dct2000_rlc_cnf,
{ "CNF",
- "dct2000.lte.rlc-cnf", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
+ "dct2000.rlc-cnf", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
"RLC CNF", HFILL
}
},
- { &hf_catapult_dct2000_lte_rlc_discard_req,
+ { &hf_catapult_dct2000_rlc_discard_req,
{ "Discard Req",
- "dct2000.lte.rlc-discard-req", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
+ "dct2000.rlc-discard-req", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
"RLC Discard Req", HFILL
}
},
NULL, HFILL
}
},
-
-
- { &hf_catapult_dct2000_ueid,
- { "UE Id",
- "dct2000.ueid", FT_UINT32, BASE_DEC, NULL, 0x0,
- "User Equipment Identifier", HFILL
+ { &hf_catapult_dct2000_nr_nas_s1ap_opcode,
+ { "NAS S1AP Opcode",
+ "dct2000.nas-s1ap.opcode", FT_UINT8, BASE_DEC, VALS(nas_s1ap_opcode_vals), 0x0,
+ NULL, HFILL
}
},
+
{ &hf_catapult_dct2000_rbid,
{ "Channel",
"dct2000.rbid", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &rlc_rbid_vals_ext, 0x0,
/* This preference no longer supported (introduces linkage dependency between
dissectors and wiretap) */
prefs_register_obsolete_preference(catapult_dct2000_module, "board_ports_only");
+ prefs_register_obsolete_preference(catapult_dct2000_module, "decode_lte_s1ap");
/* Determines whether for not-handled protocols we should try to parse it if:
- it looks like it's embedded in an ipprim message, AND
"that also call the LTE RRC dissector",
&catapult_dct2000_dissect_lte_rrc);
- /* Determines whether LTE S1AP messages should be dissected */
- prefs_register_bool_preference(catapult_dct2000_module, "decode_lte_s1ap",
- "Attempt to decode LTE S1AP frames",
- "When set, attempt to decode LTE S1AP frames. "
- "Note that this won't affect other protocols "
- "that also call the LTE S1AP dissector",
- &catapult_dct2000_dissect_lte_s1ap);
-
/* Determines whether out-of-band messages should dissected */
prefs_register_bool_preference(catapult_dct2000_module, "decode_mac_lte_oob_messages",
"Look for out-of-band LTE MAC events messages in comments",
"specific events. This may be quite slow, so should "
"be disabled if LTE MAC is not being analysed",
&catapult_dct2000_dissect_mac_lte_oob_messages);
+
+ /* Whether old protocol names conversions should be checked */
+ prefs_register_bool_preference(catapult_dct2000_module, "convert_old_protocol_names",
+ "Convert old protocol names to wireshark dissector names",
+ "When set, look for some older protocol names so that"
+ "they may be matched with wireshark dissectors.",
+ &catapult_dct2000_dissect_old_protocol_names);
}
/*