2 * Routines for Broadcast/Multicast Control dissection
3 * Copyright 2011, Neil Piercy <Neil.Piercy@ipaccess.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <wsutil/bitswap.h>
16 #include <epan/asn1.h> /* needed for packet-gsm_map.h */
18 #include "packet-cell_broadcast.h"
19 #include "packet-gsm_map.h"
21 void proto_register_bmc(void);
23 static int dissect_bmc_cbs_message (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
24 static int dissect_bmc_schedule_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
25 static int dissect_bmc_cbs41_message (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
28 static int hf_bmc_message_type
;
29 static int hf_bmc_message_id
;
30 static int hf_bmc_serial_number
;
31 /* static int hf_bmc_data_coding_scheme; */
32 /* static int hf_bmc_cb_data; */
33 static int hf_bmc_offset_to_begin_ctch_bs_index
;
34 static int hf_bmc_length_of_cbs_schedule_period
;
35 static int hf_bmc_new_message_bitmap
;
36 static int hf_bmc_message_description_type
;
37 static int hf_bmc_offset_to_ctch_bs_index_of_first_transmission
;
38 static int hf_bmc_broadcast_address
;
39 static int hf_bmc_cb_data41
;
40 static int hf_bmc_future_extension_bitmap
;
41 static int hf_bmc_length_of_serial_number_list
;
42 static int hf_bmc_ctch_bs_index
;
44 #define MESSAGE_TYPE_CBS_MESSAGE 1
45 #define MESSAGE_TYPE_SCHEDULE_MESSAGE 2
46 #define MESSAGE_TYPE_CBS41_MESSAGE 3
48 static const value_string message_type_vals
[] = {
49 {MESSAGE_TYPE_CBS_MESSAGE
, "CBS Message"},
50 {MESSAGE_TYPE_SCHEDULE_MESSAGE
, "Schedule Message"},
51 {MESSAGE_TYPE_CBS41_MESSAGE
, "CBS41 Message"},
55 static const value_string message_description_type_vals
[] = {
56 {0, "Repetition of new BMC CBS message within schedule period"},
57 {1, "New BMC CBS message (a BMC CBS message never previously sent)"},
58 {2, "Reading advised"},
59 {3, "Reading optional"},
60 {4, "Repetition of old BMC CBS message within schedule period"},
61 {5, "Old BMC CBS message (repetition of a BMC CBS message sent in a previous schedule period)"},
62 {6, "Schedule message"},
69 static int ett_bmc_message_description
;
72 dissect_bmc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
75 uint8_t *reversing_buffer
;
80 tvbuff_t
*bit_reversed_tvb
;
82 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BMC");
83 col_clear(pinfo
->cinfo
, COL_INFO
);
85 ti
= proto_tree_add_item(tree
, proto_bmc
, tvb
, 0, -1, ENC_NA
);
86 bmc_tree
= proto_item_add_subtree(ti
, ett_bmc
);
88 /* Needs bit-reversing. Create a new buffer, copy the message to it and bit-reverse */
89 len
= tvb_reported_length(tvb
);
90 reversing_buffer
= (uint8_t *)tvb_memdup(pinfo
->pool
, tvb
, offset
, len
);
91 bitswap_buf_inplace(reversing_buffer
, len
);
93 /* Make this new buffer part of the display and provide a way to dispose of it */
94 bit_reversed_tvb
= tvb_new_child_real_data(tvb
, reversing_buffer
, len
, len
);
95 add_new_data_source(pinfo
, bit_reversed_tvb
, "Bit-reversed Data");
97 message_type
= tvb_get_uint8(bit_reversed_tvb
, offset
);
98 proto_tree_add_item(bmc_tree
, hf_bmc_message_type
, bit_reversed_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
100 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(message_type
, message_type_vals
,"Reserved 0x%02x"));
102 switch (message_type
) {
103 case MESSAGE_TYPE_CBS_MESSAGE
:
104 offset
= dissect_bmc_cbs_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
107 case MESSAGE_TYPE_SCHEDULE_MESSAGE
:
108 offset
= dissect_bmc_schedule_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
111 case MESSAGE_TYPE_CBS41_MESSAGE
:
112 offset
= dissect_bmc_cbs41_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
123 dissect_bmc_cbs_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
125 tvbuff_t
*cell_broadcast_tvb
;
128 dissect_cbs_message_identifier(tvb
, tree
, offset
);
131 dissect_cbs_serial_number(tvb
, tree
, offset
);
134 dissect_cbs_data_coding_scheme(tvb
, pinfo
, tree
, offset
);
137 cell_broadcast_tvb
= tvb_new_subset_remaining(tvb
, offset
);
138 dissect_umts_cell_broadcast_message(cell_broadcast_tvb
, pinfo
, tree
, NULL
);
139 offset
= tvb_reported_length(cell_broadcast_tvb
);
145 dissect_bmc_schedule_message(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
147 int offset
= 1, i
, saved_offset
;
148 uint8_t new_message_bitmap_len
;
149 uint8_t length_of_cbs_schedule_period
;
150 uint8_t message_description_type
;
151 uint8_t future_extension_bitmap
;
152 uint8_t length_of_serial_number_list
;
155 proto_tree
*message_description_tree
;
158 proto_tree_add_item(tree
, hf_bmc_offset_to_begin_ctch_bs_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
161 length_of_cbs_schedule_period
= tvb_get_uint8(tvb
,offset
);
162 proto_tree_add_item(tree
, hf_bmc_length_of_cbs_schedule_period
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
165 new_message_bitmap_len
= length_of_cbs_schedule_period
>>3;
166 if (length_of_cbs_schedule_period
& 0x7)
167 new_message_bitmap_len
+= 1;
169 proto_tree_add_item(tree
, hf_bmc_new_message_bitmap
, tvb
, offset
, new_message_bitmap_len
, ENC_NA
);
170 offset
+= new_message_bitmap_len
;
172 message_description_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0,
173 ett_bmc_message_description
, &ti
, "Message Description" );
174 saved_offset
= offset
;
177 for (i
=0; i
<new_message_bitmap_len
; i
++) {
178 for(; bit
<=length_of_cbs_schedule_period
; bit
++) {
179 message_description_type
= tvb_get_uint8(tvb
,offset
);
180 proto_tree_add_uint_format(message_description_tree
, hf_bmc_message_description_type
,
181 tvb
, offset
, 1, message_description_type
,
182 "Message %d Message Description Type: %s (%d)",
184 val_to_str_const(message_description_type
, message_description_type_vals
,"Unknown"),
185 message_description_type
);
188 if ((message_description_type
==1) || (message_description_type
==5)) {
189 proto_tree_add_item(message_description_tree
, hf_bmc_message_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
192 else if ((message_description_type
==0) || (message_description_type
==4)) {
193 proto_tree_add_item(message_description_tree
, hf_bmc_offset_to_ctch_bs_index_of_first_transmission
,
194 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
199 proto_item_set_len(ti
, offset
-saved_offset
);
201 if (tvb_reported_length_remaining(tvb
,offset
)) {
202 future_extension_bitmap
= tvb_get_uint8(tvb
,offset
);
203 proto_tree_add_item(tree
, hf_bmc_future_extension_bitmap
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
205 if (future_extension_bitmap
& 0x01) {
206 length_of_serial_number_list
= tvb_get_uint8(tvb
,offset
);
207 proto_tree_add_item(tree
, hf_bmc_length_of_serial_number_list
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
210 for (entry
=0; entry
<length_of_serial_number_list
; entry
++) {
211 proto_tree_add_item(tree
, hf_bmc_serial_number
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
214 proto_tree_add_item(tree
, hf_bmc_ctch_bs_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
224 dissect_bmc_cbs41_message(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
228 proto_tree_add_item(tree
, hf_bmc_broadcast_address
, tvb
, offset
, 5, ENC_NA
);
231 proto_tree_add_item(tree
, hf_bmc_cb_data41
, tvb
, offset
, tvb_reported_length_remaining(tvb
,offset
), ENC_NA
);
232 offset
= tvb_reported_length(tvb
);
238 proto_register_bmc(void)
240 static hf_register_info hf
[] = {
241 { &hf_bmc_message_type
,
242 { "Message Type", "bmc.message_type",
243 FT_UINT8
, BASE_DEC
, VALS(message_type_vals
), 0,
246 { &hf_bmc_message_id
,
247 { "Message ID", "bmc.message_id",
248 FT_UINT16
, BASE_HEX
, NULL
, 0,
251 { &hf_bmc_serial_number
,
252 { "Serial Number", "bmc.serial_number",
253 FT_UINT16
, BASE_HEX
, NULL
, 0,
257 { &hf_bmc_data_coding_scheme
,
258 { "Data Coding Scheme", "bmc.data_coding_scheme",
259 FT_UINT8
, BASE_HEX
, NULL
, 0,
263 { "CB Data", "bmc.cb_data",
264 FT_BYTES
, BASE_NONE
, NULL
, 0,
268 { &hf_bmc_offset_to_begin_ctch_bs_index
,
269 { "Offset to Begin CTCH Block Set Index", "bmc.offset_to_begin_ctch_bs_index",
270 FT_UINT8
, BASE_DEC
, NULL
, 0,
273 { &hf_bmc_length_of_cbs_schedule_period
,
274 { "Length of CBS Schedule Period", "bmc.length_of_cbs_schedule_period",
275 FT_UINT8
, BASE_DEC
, NULL
, 0,
278 { &hf_bmc_new_message_bitmap
,
279 { "New Message Bitmap", "bmc.new_message_bitmap",
280 FT_BYTES
, BASE_NONE
, NULL
, 0,
283 { &hf_bmc_message_description_type
,
284 { "Message Description Type", "bmc.message_description_type",
285 FT_UINT8
, BASE_DEC
, VALS(message_description_type_vals
), 0,
288 { &hf_bmc_offset_to_ctch_bs_index_of_first_transmission
,
289 { "Offset to CTCH BS index of first transmission", "bmc.offset_to_ctch_bs_index_of_first_transmission",
290 FT_UINT8
, BASE_DEC
, NULL
, 0,
293 { &hf_bmc_broadcast_address
,
294 { "Broadcast Address", "bmc.broadcast_address",
295 FT_BYTES
, BASE_NONE
, NULL
, 0,
299 { "CB Data41", "bmc.cb_data41",
300 FT_BYTES
, BASE_NONE
, NULL
, 0,
303 { &hf_bmc_future_extension_bitmap
,
304 { "Future Extension Bitmap", "bmc.future_extension_bitmap",
305 FT_UINT8
, BASE_DEC
, NULL
, 0,
308 { &hf_bmc_length_of_serial_number_list
,
309 { "Length of Serial Number List", "bmc.length_of_serial_number_list",
310 FT_UINT8
, BASE_DEC
, NULL
, 0,
313 { &hf_bmc_ctch_bs_index
,
314 { "CTCH BS Index", "bmc.ctch_bs_index",
315 FT_UINT8
, BASE_DEC
, NULL
, 0,
320 static int *ett
[] = {
322 &ett_bmc_message_description
325 proto_bmc
= proto_register_protocol("Broadcast/Multicast Control", "BMC", "bmc");
326 register_dissector("bmc", dissect_bmc
, proto_bmc
);
328 proto_register_field_array(proto_bmc
, hf
, array_length(hf
));
329 proto_register_subtree_array(ett
, array_length(ett
));
333 * Editor modelines - https://www.wireshark.org/tools/modelines.html
338 * indent-tabs-mode: nil
341 * vi: set shiftwidth=4 tabstop=8 expandtab:
342 * :indentSize=4:tabSize=8:noTabs=true: