From 5ec061bf0c152ff07820a351b5e09506c3fe5282 Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Mon, 1 Oct 2012 19:51:07 +0000 Subject: Add options to dissect MCCH from LTE MAC/RLC dissectors svn path=/trunk/; revision=45239 --- epan/dissectors/packet-mac-lte.c | 46 ++++++---- epan/dissectors/packet-rlc-lte.c | 176 +++++++++++++++++++++++---------------- epan/dissectors/packet-rlc-lte.h | 1 + 3 files changed, 138 insertions(+), 85 deletions(-) diff --git a/epan/dissectors/packet-mac-lte.c b/epan/dissectors/packet-mac-lte.c index de914919bf..89dfc805d4 100644 --- a/epan/dissectors/packet-mac-lte.c +++ b/epan/dissectors/packet-mac-lte.c @@ -801,6 +801,9 @@ static gboolean global_mac_lte_dissect_crc_failures = FALSE; /* Whether should attempt to decode lcid 1&2 SDUs as srb1/2 (i.e. AM RLC) */ static gboolean global_mac_lte_attempt_srb_decode = TRUE; +/* Whether should attempt to decode MCH LCID 0 as MCCH */ +static gboolean global_mac_lte_attempt_mcch_decode = FALSE; + /* Where to take LCID -> DRB mappings from */ enum lcid_drb_source { FromStaticTable, FromConfigurationProtocol @@ -1869,7 +1872,7 @@ static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr guint8 UMSequenceNumberLength, guint8 priority) { - tvbuff_t *srb_tvb = tvb_new_subset(tvb, offset, data_length, data_length); + tvbuff_t *rb_tvb = tvb_new_subset(tvb, offset, data_length, data_length); struct rlc_lte_info *p_rlc_lte_info; /* Get RLC dissector handle */ @@ -1912,7 +1915,7 @@ static void call_rlc_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr s_number_of_rlc_pdus_shown++; /* Call it (catch exceptions so that stats will be updated) */ - call_with_catch_all(protocol_handle, srb_tvb, pinfo, tree); + call_with_catch_all(protocol_handle, rb_tvb, pinfo, tree); /* Let columns be written to again */ col_set_writable(pinfo->cinfo, TRUE); @@ -4059,21 +4062,29 @@ static void dissect_mch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pro tvb_length_remaining(tvb, offset) : pdu_lengths[n]; - /* Dissect SDU as raw bytes */ - sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n], - NULL, "SDU (%s, length=%u bytes): ", - val_to_str_const(lcids[n], mch_lcid_vals, "Unknown"), - data_length); - /* Show bytes too. There must be a nicer way of doing this! */ - pdu_data = tvb_get_ptr(tvb, offset, pdu_lengths[n]); - for (i=0; i < data_length; i++) { - g_snprintf(buff+(i*2), 3, "%02x", pdu_data[i]); - if (i >= 30) { - g_snprintf(buff+(i*2), 4, "..."); - break; + if ((lcids[n] == 0) && global_mac_lte_attempt_mcch_decode) { + /* Call RLC dissector */ + call_rlc_dissector(tvb, pinfo, tree, pdu_ti, offset, data_length, + RLC_UM_MODE, DIRECTION_DOWNLINK, 0, + CHANNEL_TYPE_MCCH, 0, 5, 0); + } else { + /* Dissect SDU as raw bytes */ + sdu_ti = proto_tree_add_bytes_format(tree, hf_mac_lte_mch_sdu, tvb, offset, pdu_lengths[n], + NULL, "SDU (%s, length=%u bytes): ", + val_to_str_const(lcids[n], mch_lcid_vals, "Unknown"), + data_length); + + /* Show bytes too. There must be a nicer way of doing this! */ + pdu_data = tvb_get_ptr(tvb, offset, pdu_lengths[n]); + for (i=0; i < data_length; i++) { + g_snprintf(buff+(i*2), 3, "%02x", pdu_data[i]); + if (i >= 30) { + g_snprintf(buff+(i*2), 4, "..."); + break; + } } + proto_item_append_text(sdu_ti, "%s", buff); } - proto_item_append_text(sdu_ti, "%s", buff); offset += data_length; } @@ -5701,6 +5712,11 @@ void proto_register_mac_lte(void) "Will call LTE RLC dissector with standard settings as per RRC spec", &global_mac_lte_attempt_srb_decode); + prefs_register_bool_preference(mac_lte_module, "attempt_to_dissect_mcch", + "Attempt to dissect MCH LCID 0 as MCCH", + "Will call LTE RLC dissector for MCH LCID 0", + &global_mac_lte_attempt_mcch_decode); + prefs_register_enum_preference(mac_lte_module, "lcid_to_drb_mapping_source", "Source of LCID -> drb channel settings", "Set whether LCID -> drb Table is taken from static table (below) or from " diff --git a/epan/dissectors/packet-rlc-lte.c b/epan/dissectors/packet-rlc-lte.c index 547507028f..9317e7cb60 100644 --- a/epan/dissectors/packet-rlc-lte.c +++ b/epan/dissectors/packet-rlc-lte.c @@ -75,7 +75,8 @@ static enum_val_t pdcp_drb_col_vals[] = { static gint global_rlc_lte_call_pdcp_for_drb = (gint)PDCP_drb_off; static gint signalled_pdcp_sn_bits = 12; -static gboolean global_rlc_lte_call_rrc = FALSE; +static gboolean global_rlc_lte_call_rrc_for_ccch = FALSE; +static gboolean global_rlc_lte_call_rrc_for_mcch = FALSE; /* Preference to expect RLC headers without payloads */ static gboolean global_rlc_lte_headers_expected = FALSE; @@ -223,6 +224,7 @@ static const value_string rlc_channel_type_vals[] = { CHANNEL_TYPE_SRB, "SRB"}, { CHANNEL_TYPE_DRB, "DRB"}, { CHANNEL_TYPE_BCCH_DL_SCH, "BCCH_DL_SCH"}, + { CHANNEL_TYPE_MCCH, "MCCH"}, { 0, NULL } }; @@ -708,7 +710,7 @@ static void show_PDU_in_info(packet_info *pinfo, } -/* Show an SDU. If configured, pass to PDCP dissector */ +/* Show an SDU. If configured, pass to PDCP/RRC dissector */ static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, rlc_lte_info *rlc_info, gboolean whole_pdu, rlc_channel_reassembly_info *reassembly_info, sequence_analysis_state state) @@ -720,83 +722,111 @@ static void show_PDU_in_tree(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb hf_rlc_lte_um_data, tvb, offset, length, ENC_NA); - /* Send whole PDU to PDCP */ - if ((whole_pdu || (reassembly_info != NULL)) && - (((global_rlc_lte_call_pdcp_for_srb) && (rlc_info->channelType == CHANNEL_TYPE_SRB)) || - ((global_rlc_lte_call_pdcp_for_drb != PDCP_drb_off) && (rlc_info->channelType == CHANNEL_TYPE_DRB)))) { + if (whole_pdu || (reassembly_info != NULL)) { + if (((global_rlc_lte_call_pdcp_for_srb) && (rlc_info->channelType == CHANNEL_TYPE_SRB)) || + ((global_rlc_lte_call_pdcp_for_drb != PDCP_drb_off) && (rlc_info->channelType == CHANNEL_TYPE_DRB))) { + /* Send whole PDU to PDCP */ - /* TODO: made static to avoid compiler warning... */ - static tvbuff_t *pdcp_tvb = NULL; - volatile dissector_handle_t protocol_handle; - struct pdcp_lte_info *p_pdcp_lte_info; + /* TODO: made static to avoid compiler warning... */ + static tvbuff_t *pdcp_tvb = NULL; + volatile dissector_handle_t protocol_handle; + struct pdcp_lte_info *p_pdcp_lte_info; - /* Get tvb for passing to LTE PDCP dissector */ - if (reassembly_info == NULL) { - pdcp_tvb = tvb_new_subset(tvb, offset, length, length); - } - else { - /* Get combined tvb. */ - pdcp_tvb = reassembly_get_reassembled_tvb(reassembly_info, tvb, pinfo); - reassembly_show_source(reassembly_info, tree, tvb, offset); - } + /* Get tvb for passing to LTE PDCP dissector */ + if (reassembly_info == NULL) { + pdcp_tvb = tvb_new_subset(tvb, offset, length, length); + } + else { + /* Get combined tvb. */ + pdcp_tvb = reassembly_get_reassembled_tvb(reassembly_info, tvb, pinfo); + reassembly_show_source(reassembly_info, tree, tvb, offset); + } - /* Reuse or allocate struct */ - p_pdcp_lte_info = p_get_proto_data(pinfo->fd, proto_pdcp_lte); - if (p_pdcp_lte_info == NULL) { - p_pdcp_lte_info = se_alloc0(sizeof(struct pdcp_lte_info)); - /* Store info in packet */ - p_add_proto_data(pinfo->fd, proto_pdcp_lte, p_pdcp_lte_info); - } + /* Reuse or allocate struct */ + p_pdcp_lte_info = p_get_proto_data(pinfo->fd, proto_pdcp_lte); + if (p_pdcp_lte_info == NULL) { + p_pdcp_lte_info = se_alloc0(sizeof(struct pdcp_lte_info)); + /* Store info in packet */ + p_add_proto_data(pinfo->fd, proto_pdcp_lte, p_pdcp_lte_info); + } - p_pdcp_lte_info->ueid = rlc_info->ueid; - p_pdcp_lte_info->channelType = Channel_DCCH; - p_pdcp_lte_info->channelId = rlc_info->channelId; - p_pdcp_lte_info->direction = rlc_info->direction; - p_pdcp_lte_info->is_retx = (state != SN_OK); - - /* Set plane and sequnce number length */ - p_pdcp_lte_info->no_header_pdu = FALSE; - if (rlc_info->channelType == CHANNEL_TYPE_SRB) { - p_pdcp_lte_info->plane = SIGNALING_PLANE; - p_pdcp_lte_info->seqnum_length = 5; - } - else { - p_pdcp_lte_info->plane = USER_PLANE; - switch (global_rlc_lte_call_pdcp_for_drb) { - case PDCP_drb_SN_7: - p_pdcp_lte_info->seqnum_length = 7; - break; - case PDCP_drb_SN_12: - p_pdcp_lte_info->seqnum_length = 12; - break; - case PDCP_drb_SN_15: - p_pdcp_lte_info->seqnum_length = 15; - break; - case PDCP_drb_SN_signalled: - /* Use whatever was signalled (e.g. in RRC) */ - p_pdcp_lte_info->seqnum_length = signalled_pdcp_sn_bits; - break; + p_pdcp_lte_info->ueid = rlc_info->ueid; + p_pdcp_lte_info->channelType = Channel_DCCH; + p_pdcp_lte_info->channelId = rlc_info->channelId; + p_pdcp_lte_info->direction = rlc_info->direction; + p_pdcp_lte_info->is_retx = (state != SN_OK); - default: - DISSECTOR_ASSERT(FALSE); - break; + /* Set plane and sequence number length */ + p_pdcp_lte_info->no_header_pdu = FALSE; + if (rlc_info->channelType == CHANNEL_TYPE_SRB) { + p_pdcp_lte_info->plane = SIGNALING_PLANE; + p_pdcp_lte_info->seqnum_length = 5; } - } + else { + p_pdcp_lte_info->plane = USER_PLANE; + switch (global_rlc_lte_call_pdcp_for_drb) { + case PDCP_drb_SN_7: + p_pdcp_lte_info->seqnum_length = 7; + break; + case PDCP_drb_SN_12: + p_pdcp_lte_info->seqnum_length = 12; + break; + case PDCP_drb_SN_15: + p_pdcp_lte_info->seqnum_length = 15; + break; + case PDCP_drb_SN_signalled: + /* Use whatever was signalled (e.g. in RRC) */ + p_pdcp_lte_info->seqnum_length = signalled_pdcp_sn_bits; + break; - p_pdcp_lte_info->rohc_compression = FALSE; + default: + DISSECTOR_ASSERT(FALSE); + break; + } + } + p_pdcp_lte_info->rohc_compression = FALSE; - /* Get dissector handle */ - protocol_handle = find_dissector("pdcp-lte"); - TRY { - call_dissector_only(protocol_handle, pdcp_tvb, pinfo, tree, NULL); - } - CATCH_ALL { + /* Get dissector handle */ + protocol_handle = find_dissector("pdcp-lte"); + + TRY { + call_dissector_only(protocol_handle, pdcp_tvb, pinfo, tree, NULL); + } + CATCH_ALL { + } + ENDTRY + + PROTO_ITEM_SET_HIDDEN(data_ti); } - ENDTRY + else if (global_rlc_lte_call_rrc_for_mcch && (rlc_info->channelType == CHANNEL_TYPE_MCCH)) { + /* Send whole PDU to RRC */ + static tvbuff_t *rrc_tvb = NULL; + volatile dissector_handle_t protocol_handle; + + /* Get tvb for passing to LTE RRC dissector */ + if (reassembly_info == NULL) { + rrc_tvb = tvb_new_subset(tvb, offset, length, length); + } + else { + /* Get combined tvb. */ + rrc_tvb = reassembly_get_reassembled_tvb(reassembly_info, tvb, pinfo); + reassembly_show_source(reassembly_info, tree, tvb, offset); + } + + /* Get dissector handle */ + protocol_handle = find_dissector("lte_rrc.mcch"); - PROTO_ITEM_SET_HIDDEN(data_ti); + TRY { + call_dissector_only(protocol_handle, rrc_tvb, pinfo, tree, NULL); + } + CATCH_ALL { + } + ENDTRY + + PROTO_ITEM_SET_HIDDEN(data_ti); + } } } @@ -1816,12 +1846,12 @@ static void dissect_rlc_lte_tm(tvbuff_t *tvb, packet_info *pinfo, /* Remaining bytes are all data */ raw_tm_ti = proto_tree_add_item(tree, hf_rlc_lte_tm_data, tvb, offset, -1, ENC_NA); - if (!global_rlc_lte_call_rrc) { + if (!global_rlc_lte_call_rrc_for_ccch) { write_pdu_label_and_info(top_ti, NULL, pinfo, " [%u-bytes]", tvb_length_remaining(tvb, offset)); } - if (global_rlc_lte_call_rrc) { + if (global_rlc_lte_call_rrc_for_ccch) { tvbuff_t *rrc_tvb = tvb_new_subset(tvb, offset, -1, tvb_length_remaining(tvb, offset)); volatile dissector_handle_t protocol_handle = 0; @@ -1847,6 +1877,7 @@ static void dissect_rlc_lte_tm(tvbuff_t *tvb, packet_info *pinfo, case CHANNEL_TYPE_SRB: case CHANNEL_TYPE_DRB: + case CHANNEL_TYPE_MCCH: default: /* Shouldn't happen, just return... */ @@ -3273,7 +3304,12 @@ void proto_register_rlc_lte(void) prefs_register_bool_preference(rlc_lte_module, "call_rrc_for_ccch", "Call RRC dissector for CCCH PDUs", "Call RRC dissector for CCCH PDUs", - &global_rlc_lte_call_rrc); + &global_rlc_lte_call_rrc_for_ccch); + + prefs_register_bool_preference(rlc_lte_module, "call_rrc_for_mcch", + "Call RRC dissector for MCCH PDUs", + "Call RRC dissector for MCCH PDUs", + &global_rlc_lte_call_rrc_for_mcch); prefs_register_bool_preference(rlc_lte_module, "heuristic_rlc_lte_over_udp", "Try Heuristic LTE-RLC over UDP framing", diff --git a/epan/dissectors/packet-rlc-lte.h b/epan/dissectors/packet-rlc-lte.h index d91e862b39..6d13fd0a83 100644 --- a/epan/dissectors/packet-rlc-lte.h +++ b/epan/dissectors/packet-rlc-lte.h @@ -41,6 +41,7 @@ #define CHANNEL_TYPE_SRB 4 #define CHANNEL_TYPE_DRB 5 #define CHANNEL_TYPE_BCCH_DL_SCH 6 +#define CHANNEL_TYPE_MCCH 7 /* UMSequenceNumberLength */ #define UM_SN_LENGTH_5_BITS 5 -- cgit v1.2.3