/* packet-bmc.c * Routines for Broadcast/Multicast Control dissection * Copyright 2011, Neil Piercy * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #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; static int hf_bmc_message_type; static int hf_bmc_message_id; static int hf_bmc_serial_number; /* static int hf_bmc_data_coding_scheme; */ /* static int hf_bmc_cb_data; */ static int hf_bmc_offset_to_begin_ctch_bs_index; static int hf_bmc_length_of_cbs_schedule_period; static int hf_bmc_new_message_bitmap; static int hf_bmc_message_description_type; static int hf_bmc_offset_to_ctch_bs_index_of_first_transmission; static int hf_bmc_broadcast_address; static int hf_bmc_cb_data41; static int hf_bmc_future_extension_bitmap; static int hf_bmc_length_of_serial_number_list; static int hf_bmc_ctch_bs_index; #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 int ett_bmc; static int ett_bmc_message_description; static int dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { uint8_t message_type; uint8_t *reversing_buffer; int offset = 0; int 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 = (uint8_t *)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_uint8(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_str(pinfo->cinfo, COL_INFO, 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; int 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) { int offset = 1, i, saved_offset; uint8_t new_message_bitmap_len; uint8_t length_of_cbs_schedule_period; uint8_t message_description_type; uint8_t future_extension_bitmap; uint8_t length_of_serial_number_list; uint8_t entry; uint8_t 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_uint8(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