/* packet-bmc.c * Routines for Broadcast/Multicast Control dissection * Copyright 2011, Neil Piercy * * 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. */ #include "config.h" #include #include #include /* needed for packet-gsm_map.h */ #include "packet-cell_broadcast.h" #include "packet-gsm_map.h" void proto_register_bmc(void); 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); 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_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 static const 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} }; static const 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, void *data _U_) { guint8 message_type; guint8 *reversing_buffer; gint offset = 0; gint 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_reported_length(tvb); reversing_buffer = (guint8 *)tvb_memdup(pinfo->pool, tvb, offset, len); bitswap_buf_inplace(reversing_buffer, len); /* Make this new buffer part of the display and provide a way to dispose of it */ bit_reversed_tvb = tvb_new_child_real_data(tvb, reversing_buffer, len, len); add_new_data_source(pinfo, bit_reversed_tvb, "Bit-reversed Data"); message_type = tvb_get_guint8(bit_reversed_tvb, offset); proto_tree_add_item(bmc_tree, hf_bmc_message_type, bit_reversed_tvb, offset, 1, ENC_BIG_ENDIAN); offset++; col_add_fstr(pinfo->cinfo, 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) { tvbuff_t *cell_broadcast_tvb; gint offset = 1; dissect_cbs_message_identifier(tvb, tree, offset); offset += 2; dissect_cbs_serial_number(tvb, tree, offset); offset += 2; dissect_cbs_data_coding_scheme(tvb, pinfo, tree, offset); offset += 1; cell_broadcast_tvb = tvb_new_subset_remaining(tvb, offset); dissect_umts_cell_broadcast_message(cell_broadcast_tvb, pinfo, tree, NULL); offset = tvb_reported_length(cell_broadcast_tvb); return offset; } static int dissect_bmc_schedule_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) { gint offset = 1, i, 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 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_NA); offset += new_message_bitmap_len; message_description_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_bmc_message_description, &ti, "Message Description" ); saved_offset = offset; bit=1; for (i=0; i