From ffae0f912d46278e408eb9e8ccd4386e1a3722bb Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Sat, 16 Apr 2011 12:22:16 +0000 Subject: [PATCH] From Neil Piercy: Adds BMC protocol, including adding support for MAC and RLC CTCH channels to carry it. From me: Removed hf blurbs = def and removed check_col added tp CMakeList. svn path=/trunk/; revision=36662 --- epan/CMakeLists.txt | 1 + epan/dissectors/Makefile.common | 1 + epan/dissectors/packet-bmc.c | 350 ++++++++++++++++++++++++++++++ epan/dissectors/packet-rlc.c | 83 ++++--- epan/dissectors/packet-umts_mac.c | 12 +- 5 files changed, 412 insertions(+), 35 deletions(-) create mode 100644 epan/dissectors/packet-bmc.c diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index a29cf73aac..617ac67f3e 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -363,6 +363,7 @@ set(DISSECTOR_SRC dissectors/packet-bgp.c dissectors/packet-bittorrent.c dissectors/packet-bjnp.c + dissectors/packet-bmc.c dissectors/packet-bofl.c dissectors/packet-bootp.c dissectors/packet-bootparams.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 624b3cd00c..e80af76f11 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -276,6 +276,7 @@ DISSECTOR_SRC = \ packet-bgp.c \ packet-bittorrent.c \ packet-bjnp.c \ + packet-bmc.c \ packet-bofl.c \ packet-bootp.c \ packet-bootparams.c \ diff --git a/epan/dissectors/packet-bmc.c b/epan/dissectors/packet-bmc.c new file mode 100644 index 0000000000..f891bfacce --- /dev/null +++ b/epan/dissectors/packet-bmc.c @@ -0,0 +1,350 @@ +/* packet-bmc.c + * Routines for Broadcast/Multicast Control dissection + * Copyright 2011, Neil Piercy + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include +#include + +static int dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +static int dissect_bmc_cbs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +static int dissect_bmc_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +static int dissect_bmc_cbs41_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +void proto_reg_handoff_bmc(void); + +static int proto_bmc = -1; +static int hf_bmc_message_type = -1; +static int hf_bmc_message_id = -1; +static int hf_bmc_serial_number = -1; +static int hf_bmc_data_coding_scheme = -1; +static int hf_bmc_cb_data = -1; +static int hf_bmc_offset_to_begin_ctch_bs_index = -1; +static int hf_bmc_length_of_cbs_schedule_period = -1; +static int hf_bmc_new_message_bitmap = -1; +static int hf_bmc_message_description_type = -1; +static int hf_bmc_offset_to_ctch_bs_index_of_first_transmission = -1; +static int hf_bmc_broadcast_address = -1; +static int hf_bmc_cb_data41 = -1; +static int hf_bmc_cbs_schedule_message_extension = -1; +static int hf_bmc_future_extension_bitmap = -1; +static int hf_bmc_length_of_serial_number_list = -1; +static int hf_bmc_ctch_bs_index = -1; + +#define MESSAGE_TYPE_CBS_MESSAGE 1 +#define MESSAGE_TYPE_SCHEDULE_MESSAGE 2 +#define MESSAGE_TYPE_CBS41_MESSAGE 3 + +const static value_string message_type_vals[] = { + {MESSAGE_TYPE_CBS_MESSAGE, "CBS Message"}, + {MESSAGE_TYPE_SCHEDULE_MESSAGE, "Schedule Message"}, + {MESSAGE_TYPE_CBS41_MESSAGE, "CBS41 Message"}, + {0, NULL} +}; + +const static value_string message_description_type_vals[] = { + {0, "Repetition of new BMC CBS message within schedule period"}, + {1, "New BMC CBS message (a BMC CBS message never previously sent)"}, + {2, "Reading advised"}, + {3, "Reading optional"}, + {4, "Repetition of old BMC CBS message within schedule period"}, + {5, "Old BMC CBS message (repetition of a BMC CBS message sent in a previous schedule period)"}, + {6, "Schedule message"}, + {7, "CBS41 message"}, + {8, "no message"}, + {0, NULL} +}; + +static gint ett_bmc = -1; +static gint ett_bmc_message_description = -1; + +static int +dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 message_type; + guint8 *p_rev, *reversing_buffer; + gint offset = 0; + gint i, len; + proto_item *ti; + proto_tree *bmc_tree; + tvbuff_t *bit_reversed_tvb; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BMC"); + col_clear(pinfo->cinfo, COL_INFO); + + ti = proto_tree_add_item(tree, proto_bmc, tvb, 0, -1, ENC_NA); + bmc_tree = proto_item_add_subtree(ti, ett_bmc); + + /* Needs bit-reversing. Create a new buffer, copy the message to it and bit-reverse */ + len = tvb_length(tvb); + reversing_buffer = se_alloc(len); + memcpy(reversing_buffer, tvb_get_ptr(tvb, offset, -1), len); + + p_rev = reversing_buffer; + /* Entire message is bit reversed */ + for (i=0; icinfo, COL_INFO, "%s", val_to_str(message_type, message_type_vals,"Reserved 0x%02x")); + + switch (message_type) { + case MESSAGE_TYPE_CBS_MESSAGE: + offset = dissect_bmc_cbs_message(bit_reversed_tvb, pinfo, bmc_tree); + break; + + case MESSAGE_TYPE_SCHEDULE_MESSAGE: + offset = dissect_bmc_schedule_message(bit_reversed_tvb, pinfo, bmc_tree); + break; + + case MESSAGE_TYPE_CBS41_MESSAGE: + offset = dissect_bmc_cbs41_message(bit_reversed_tvb, pinfo, bmc_tree); + break; + + default: + break; + } + + return offset; +} + +static int dissect_bmc_cbs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + gint offset=1; + + proto_tree_add_item(tree, hf_bmc_message_id, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_bmc_serial_number, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_bmc_data_coding_scheme, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_bmc_cb_data, tvb, offset, tvb_length_remaining(tvb,offset), ENC_BIG_ENDIAN); + offset = tvb_length(tvb); + + return offset; +} + +static int dissect_bmc_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + gint offset=1, i, bitmap_offset, saved_offset; + guint8 new_message_bitmap_len; + guint8 length_of_cbs_schedule_period; + guint8 message_description_type; + guint8 future_extension_bitmap; + guint8 length_of_serial_number_list; + guint8 entry; + guint8 byte, mask, bit; + proto_tree *message_description_tree; + proto_item *ti; + + proto_tree_add_item(tree, hf_bmc_offset_to_begin_ctch_bs_index, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + length_of_cbs_schedule_period = tvb_get_guint8(tvb,offset); + proto_tree_add_item(tree, hf_bmc_length_of_cbs_schedule_period, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + new_message_bitmap_len = length_of_cbs_schedule_period>>3; + if (length_of_cbs_schedule_period & 0x7) + new_message_bitmap_len += 1; + + proto_tree_add_item(tree, hf_bmc_new_message_bitmap, tvb, offset, new_message_bitmap_len, ENC_BIG_ENDIAN); + bitmap_offset = offset; + offset += new_message_bitmap_len; + + ti = proto_tree_add_text(tree, tvb, offset, 0, "Message Description" ); + message_description_tree = proto_item_add_subtree(ti, ett_bmc_message_description); + saved_offset = offset; + + bit=1; + for (i=0; icinfo, COL_INFO)) + if (dissected == FALSE) col_set_str(pinfo->cinfo, COL_INFO, "[RLC UM Fragment]"); } } @@ -887,8 +893,7 @@ static gint16 rlc_decode_li(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinf proto_malformed, tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto); expert_add_info_format(pinfo, malformed, PI_MALFORMED, PI_ERROR, "Malformed Packet (Uses reserved LI)"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); + col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); return -1; /* just give up on this */ default: /* since the LI is an offset (from the end of the header), it @@ -902,8 +907,7 @@ static gint16 rlc_decode_li(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinf proto_malformed, tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto); expert_add_info_format(pinfo, malformed, PI_MALFORMED, PI_ERROR, "Malformed Packet (incorrect LI value)"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); + col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); return -1; /* just give up on this */ } li[num_li].len = li[num_li].li - prev_li; @@ -970,8 +974,7 @@ static void dissect_rlc_um(enum channel_type channel, tvbuff_t *tvb, packet_info if (pinfo->fd->num == 0) return; /* check for duplicates */ if (rlc_is_duplicate(RLC_UM, pinfo, seq, &orig_num) == TRUE) { - if (check_col(pinfo->cinfo, COL_INFO)) - col_set_str(pinfo->cinfo, COL_INFO, "[RLC UM Fragment] [Duplicate]"); + col_set_str(pinfo->cinfo, COL_INFO, "[RLC UM Fragment] [Duplicate]"); proto_tree_add_uint(tree, hf_rlc_duplicate_of, tvb, 0, 0, orig_num); return; } @@ -1062,8 +1065,7 @@ static void dissect_rlc_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree proto_malformed, tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto); expert_add_info_format(pinfo, malformed, PI_MALFORMED, PI_ERROR, "Malformed Packet (invalid SUFI type)"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, " [Malformed Packet]"); + col_append_str(pinfo->cinfo, COL_INFO, " [Malformed Packet]"); return; /* invalid value, ignore the rest */ } } @@ -1091,8 +1093,7 @@ static void dissect_rlc_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t proto_malformed, tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto); expert_add_info_format(pinfo, malformed, PI_MALFORMED, PI_ERROR, "Malformed Packet (invalid RLC AM control type %u)", type); - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, " [Malformed Packet]"); + col_append_str(pinfo->cinfo, COL_INFO, " [Malformed Packet]"); return; /* invalid */ } } @@ -1148,7 +1149,7 @@ static void rlc_am_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo, pr next_tvb = NULL; } } - if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO)) + if (dissected == FALSE) col_set_str(pinfo->cinfo, COL_INFO, "[RLC AM Fragment]"); } @@ -1169,8 +1170,7 @@ static void dissect_rlc_am(enum channel_type channel, tvbuff_t *tvb, packet_info if (tree) proto_tree_add_item(tree, hf_rlc_dc, tvb, 0, 1, FALSE); if (dc == 0) { - if (check_col(pinfo->cinfo, COL_INFO)) - col_set_str(pinfo->cinfo, COL_INFO, "RLC Control Frame"); + col_set_str(pinfo->cinfo, COL_INFO, "RLC Control Frame"); dissect_rlc_control(tvb, pinfo, tree); return; } @@ -1195,8 +1195,7 @@ static void dissect_rlc_am(enum channel_type channel, tvbuff_t *tvb, packet_info proto_malformed, tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto); expert_add_info_format(pinfo, malformed, PI_MALFORMED, PI_ERROR, "Malformed Packet (incorrect HE value)"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); + col_append_str(pinfo->cinfo, COL_INFO, "[Malformed Packet]"); return; } @@ -1222,8 +1221,7 @@ static void dissect_rlc_am(enum channel_type channel, tvbuff_t *tvb, packet_info if (pinfo->fd->num == 0) return; /* check for duplicates */ if (rlc_is_duplicate(RLC_AM, pinfo, seq, &orig_num) == TRUE) { - if (check_col(pinfo->cinfo, COL_INFO)) - col_set_str(pinfo->cinfo, COL_INFO, "[RLC AM Fragment] [Duplicate]"); + col_set_str(pinfo->cinfo, COL_INFO, "[RLC AM Fragment] [Duplicate]"); proto_tree_add_uint(tree, hf_rlc_duplicate_of, tvb, 0, 0, orig_num); return; } @@ -1235,10 +1233,8 @@ static void dissect_rlc_am(enum channel_type channel, tvbuff_t *tvb, packet_info static void dissect_rlc_pcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *subtree = NULL; - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); + col_clear(pinfo->cinfo, COL_INFO); /* PCCH is always RLC UM */ if (tree) { @@ -1256,10 +1252,8 @@ static void dissect_rlc_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree proto_item *ti = NULL; proto_tree *subtree = NULL; - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); + col_clear(pinfo->cinfo, COL_INFO); fpi = p_get_proto_data(pinfo->fd, proto_fp); if (!fpi) return; /* dissection failure */ @@ -1280,6 +1274,29 @@ static void dissect_rlc_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree } } +static void dissect_rlc_ctch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + fp_info *fpi; + proto_item *ti = NULL; + proto_tree *subtree = NULL; + + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); + col_clear(pinfo->cinfo, COL_INFO); + + fpi = p_get_proto_data(pinfo->fd, proto_fp); + if (!fpi) return; /* dissection failure */ + + if (tree) { + ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, FALSE); + subtree = proto_item_add_subtree(ti, ett_rlc); + } + + /* CTCH is always UM */ + proto_item_append_text(ti, " UM (CTCH)"); + dissect_rlc_um(DL_CTCH, tvb, pinfo, tree, subtree); +} + static void dissect_rlc_dcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti = NULL; @@ -1288,10 +1305,8 @@ static void dissect_rlc_dcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree rlc_info *rlci; enum channel_type channel; - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); + col_clear(pinfo->cinfo, COL_INFO); fpi = p_get_proto_data(pinfo->fd, proto_fp); rlci = p_get_proto_data(pinfo->fd, proto_rlc); @@ -1324,10 +1339,8 @@ static void dissect_rlc_ps_dtch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t fp_info *fpi; rlc_info *rlci; - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC"); + col_clear(pinfo->cinfo, COL_INFO); fpi = p_get_proto_data(pinfo->fd, proto_fp); rlci = p_get_proto_data(pinfo->fd, proto_rlc); @@ -1401,6 +1414,7 @@ proto_register_rlc(void) proto_rlc = proto_register_protocol("RLC", "RLC", "rlc"); register_dissector("rlc.pcch", dissect_rlc_pcch, proto_rlc); register_dissector("rlc.ccch", dissect_rlc_ccch, proto_rlc); + register_dissector("rlc.ctch", dissect_rlc_ctch, proto_rlc); register_dissector("rlc.dcch", dissect_rlc_dcch, proto_rlc); register_dissector("rlc.ps_dtch", dissect_rlc_ps_dtch, proto_rlc); @@ -1415,4 +1429,5 @@ proto_reg_handoff_rlc(void) { rrc_handle = find_dissector("rrc"); ip_handle = find_dissector("ip"); + bmc_handle = find_dissector("bmc"); } diff --git a/epan/dissectors/packet-umts_mac.c b/epan/dissectors/packet-umts_mac.c index 36b03d636d..ed2c347096 100644 --- a/epan/dissectors/packet-umts_mac.c +++ b/epan/dissectors/packet-umts_mac.c @@ -55,6 +55,7 @@ static int ett_mac_hsdsch = -1; static dissector_handle_t rlc_pcch_handle; static dissector_handle_t rlc_ccch_handle; +static dissector_handle_t rlc_ctch_handle; static dissector_handle_t rlc_dcch_handle; static dissector_handle_t rlc_ps_dtch_handle; @@ -387,8 +388,16 @@ static void dissect_mac_fdd_fach(tvbuff_t *tvb, packet_info *pinfo, proto_tree * proto_item_append_text(ti, " (Unknown FACH Content"); } break; + case TCTF_CTCH_FACH_FDD: + proto_item_append_text(ti, " (CTCH)"); + channel_type = proto_tree_add_uint(fach_tree, hf_mac_channel, tvb, 0, 0, MAC_CTCH); + PROTO_ITEM_SET_GENERATED(channel_type); + /* CTCH over FACH is always octet aligned */ + next_tvb = tvb_new_subset(tvb, 1, tvb_length_remaining(tvb, 1), -1); + call_dissector(rlc_ctch_handle, next_tvb, pinfo, tree); + break; default: - proto_item_append_text(ti, " (Unknown FACH Content"); + proto_item_append_text(ti, " (Unknown FACH Content)"); } } @@ -601,6 +610,7 @@ proto_reg_handoff_umts_mac(void) { rlc_pcch_handle = find_dissector("rlc.pcch"); rlc_ccch_handle = find_dissector("rlc.ccch"); + rlc_ctch_handle = find_dissector("rlc.ctch"); rlc_dcch_handle = find_dissector("rlc.dcch"); rlc_ps_dtch_handle = find_dissector("rlc.ps_dtch"); }