aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2012-10-01 19:51:07 +0000
committerPascal Quantin <pascal.quantin@gmail.com>2012-10-01 19:51:07 +0000
commit5ec061bf0c152ff07820a351b5e09506c3fe5282 (patch)
treeec0f0cce4b4f9e30994decde6ff91adc4b4b8550
parent0836b3b16b78615045a2ac0d88c1b27668ff182e (diff)
Add options to dissect MCCH from LTE MAC/RLC dissectors
svn path=/trunk/; revision=45239
-rw-r--r--epan/dissectors/packet-mac-lte.c46
-rw-r--r--epan/dissectors/packet-rlc-lte.c176
-rw-r--r--epan/dissectors/packet-rlc-lte.h1
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