2 * Routines for Broadcast/Multicast Control dissection
3 * Copyright 2011, Neil Piercy <Neil.Piercy@ipaccess.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include <epan/bitswap.h>
32 #include <epan/asn1.h> /* needed for packet-gsm_map.h */
34 #include "packet-cell_broadcast.h"
35 #include "packet-gsm_map.h"
37 void proto_register_bmc(void);
39 static int dissect_bmc_cbs_message (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
40 static int dissect_bmc_schedule_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
41 static int dissect_bmc_cbs41_message (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
43 static int proto_bmc
= -1;
44 static int hf_bmc_message_type
= -1;
45 static int hf_bmc_message_id
= -1;
46 static int hf_bmc_serial_number
= -1;
47 /* static int hf_bmc_data_coding_scheme = -1; */
48 /* static int hf_bmc_cb_data = -1; */
49 static int hf_bmc_offset_to_begin_ctch_bs_index
= -1;
50 static int hf_bmc_length_of_cbs_schedule_period
= -1;
51 static int hf_bmc_new_message_bitmap
= -1;
52 static int hf_bmc_message_description_type
= -1;
53 static int hf_bmc_offset_to_ctch_bs_index_of_first_transmission
= -1;
54 static int hf_bmc_broadcast_address
= -1;
55 static int hf_bmc_cb_data41
= -1;
56 static int hf_bmc_future_extension_bitmap
= -1;
57 static int hf_bmc_length_of_serial_number_list
= -1;
58 static int hf_bmc_ctch_bs_index
= -1;
60 #define MESSAGE_TYPE_CBS_MESSAGE 1
61 #define MESSAGE_TYPE_SCHEDULE_MESSAGE 2
62 #define MESSAGE_TYPE_CBS41_MESSAGE 3
64 static const value_string message_type_vals
[] = {
65 {MESSAGE_TYPE_CBS_MESSAGE
, "CBS Message"},
66 {MESSAGE_TYPE_SCHEDULE_MESSAGE
, "Schedule Message"},
67 {MESSAGE_TYPE_CBS41_MESSAGE
, "CBS41 Message"},
71 static const value_string message_description_type_vals
[] = {
72 {0, "Repetition of new BMC CBS message within schedule period"},
73 {1, "New BMC CBS message (a BMC CBS message never previously sent)"},
74 {2, "Reading advised"},
75 {3, "Reading optional"},
76 {4, "Repetition of old BMC CBS message within schedule period"},
77 {5, "Old BMC CBS message (repetition of a BMC CBS message sent in a previous schedule period)"},
78 {6, "Schedule message"},
84 static gint ett_bmc
= -1;
85 static gint ett_bmc_message_description
= -1;
88 dissect_bmc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
91 guint8
*p_rev
, *reversing_buffer
;
96 tvbuff_t
*bit_reversed_tvb
;
98 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BMC");
99 col_clear(pinfo
->cinfo
, COL_INFO
);
101 ti
= proto_tree_add_item(tree
, proto_bmc
, tvb
, 0, -1, ENC_NA
);
102 bmc_tree
= proto_item_add_subtree(ti
, ett_bmc
);
104 /* Needs bit-reversing. Create a new buffer, copy the message to it and bit-reverse */
105 len
= tvb_length(tvb
);
106 reversing_buffer
= (guint8
*)tvb_memdup(NULL
, tvb
, offset
, len
);
107 p_rev
= reversing_buffer
;
108 /* Entire message is bit reversed */
109 for (i
=0; i
<len
; i
++, p_rev
++)
110 *p_rev
= BIT_SWAP(*p_rev
);
112 /* Make this new buffer part of the display and provide a way to dispose of it */
113 bit_reversed_tvb
= tvb_new_child_real_data(tvb
, reversing_buffer
, len
, len
);
114 tvb_set_free_cb(bit_reversed_tvb
, g_free
);
115 add_new_data_source(pinfo
, bit_reversed_tvb
, "Bit-reversed Data");
117 message_type
= tvb_get_guint8(bit_reversed_tvb
, offset
);
118 proto_tree_add_item(bmc_tree
, hf_bmc_message_type
, bit_reversed_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
120 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s", val_to_str(message_type
, message_type_vals
,"Reserved 0x%02x"));
122 switch (message_type
) {
123 case MESSAGE_TYPE_CBS_MESSAGE
:
124 offset
= dissect_bmc_cbs_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
127 case MESSAGE_TYPE_SCHEDULE_MESSAGE
:
128 offset
= dissect_bmc_schedule_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
131 case MESSAGE_TYPE_CBS41_MESSAGE
:
132 offset
= dissect_bmc_cbs41_message(bit_reversed_tvb
, pinfo
, bmc_tree
);
143 dissect_bmc_cbs_message(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
145 tvbuff_t
*cell_broadcast_tvb
;
148 dissect_cbs_message_identifier(tvb
, tree
, offset
);
151 dissect_cbs_serial_number(tvb
, tree
, offset
);
154 dissect_cbs_data_coding_scheme(tvb
, pinfo
, tree
, offset
);
157 cell_broadcast_tvb
= tvb_new_subset_remaining(tvb
, offset
);
158 dissect_umts_cell_broadcast_message(cell_broadcast_tvb
, pinfo
, tree
);
159 offset
= tvb_length(cell_broadcast_tvb
);
165 dissect_bmc_schedule_message(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
167 gint offset
= 1, i
, saved_offset
;
168 guint8 new_message_bitmap_len
;
169 guint8 length_of_cbs_schedule_period
;
170 guint8 message_description_type
;
171 guint8 future_extension_bitmap
;
172 guint8 length_of_serial_number_list
;
175 proto_tree
*message_description_tree
;
178 proto_tree_add_item(tree
, hf_bmc_offset_to_begin_ctch_bs_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
181 length_of_cbs_schedule_period
= tvb_get_guint8(tvb
,offset
);
182 proto_tree_add_item(tree
, hf_bmc_length_of_cbs_schedule_period
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
185 new_message_bitmap_len
= length_of_cbs_schedule_period
>>3;
186 if (length_of_cbs_schedule_period
& 0x7)
187 new_message_bitmap_len
+= 1;
189 proto_tree_add_item(tree
, hf_bmc_new_message_bitmap
, tvb
, offset
, new_message_bitmap_len
, ENC_NA
);
190 offset
+= new_message_bitmap_len
;
192 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Message Description" );
193 message_description_tree
= proto_item_add_subtree(ti
, ett_bmc_message_description
);
194 saved_offset
= offset
;
197 for (i
=0; i
<new_message_bitmap_len
; i
++) {
198 for(; bit
<=length_of_cbs_schedule_period
; bit
++) {
199 message_description_type
= tvb_get_guint8(tvb
,offset
);
200 proto_tree_add_uint_format(message_description_tree
, hf_bmc_message_description_type
,
201 tvb
, offset
, 1, message_description_type
,
202 "Message %d Message Description Type: %s (%d)",
204 val_to_str_const(message_description_type
, message_description_type_vals
,"Unknown"),
205 message_description_type
);
208 if ((message_description_type
==1) || (message_description_type
==5)) {
209 proto_tree_add_item(message_description_tree
, hf_bmc_message_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
212 else if ((message_description_type
==0) || (message_description_type
==4)) {
213 proto_tree_add_item(message_description_tree
, hf_bmc_offset_to_ctch_bs_index_of_first_transmission
,
214 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
219 proto_item_set_len(ti
, offset
-saved_offset
);
221 if (tvb_length_remaining(tvb
,offset
)) {
222 future_extension_bitmap
= tvb_get_guint8(tvb
,offset
);
223 proto_tree_add_item(tree
, hf_bmc_future_extension_bitmap
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
225 if (future_extension_bitmap
& 0x01) {
226 length_of_serial_number_list
= tvb_get_guint8(tvb
,offset
);
227 proto_tree_add_item(tree
, hf_bmc_length_of_serial_number_list
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
230 for (entry
=0; entry
<length_of_serial_number_list
; entry
++) {
231 proto_tree_add_item(tree
, hf_bmc_serial_number
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
234 proto_tree_add_item(tree
, hf_bmc_ctch_bs_index
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
244 dissect_bmc_cbs41_message(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
248 proto_tree_add_item(tree
, hf_bmc_broadcast_address
, tvb
, offset
, 5, ENC_NA
);
251 proto_tree_add_item(tree
, hf_bmc_cb_data41
, tvb
, offset
, tvb_length_remaining(tvb
,offset
), ENC_NA
);
252 offset
= tvb_length(tvb
);
258 proto_register_bmc(void)
260 static hf_register_info hf
[] = {
261 { &hf_bmc_message_type
,
262 { "Message Type", "bmc.message_type",
263 FT_UINT8
, BASE_DEC
, message_type_vals
, 0,
266 { &hf_bmc_message_id
,
267 { "Message ID", "bmc.message_id",
268 FT_UINT16
, BASE_HEX
, NULL
, 0,
271 { &hf_bmc_serial_number
,
272 { "Serial Number", "bmc.serial_number",
273 FT_UINT16
, BASE_HEX
, NULL
, 0,
277 { &hf_bmc_data_coding_scheme
,
278 { "Data Coding Scheme", "bmc.data_coding_scheme",
279 FT_UINT8
, BASE_HEX
, NULL
, 0,
283 { "CB Data", "bmc.cb_data",
284 FT_BYTES
, BASE_NONE
, NULL
, 0,
288 { &hf_bmc_offset_to_begin_ctch_bs_index
,
289 { "Offset to Begin CTCH Block Set Index", "bmc.offset_to_begin_ctch_bs_index",
290 FT_UINT8
, BASE_DEC
, NULL
, 0,
293 { &hf_bmc_length_of_cbs_schedule_period
,
294 { "Length of CBS Schedule Period", "bmc.length_of_cbs_schedule_period",
295 FT_UINT8
, BASE_DEC
, NULL
, 0,
298 { &hf_bmc_new_message_bitmap
,
299 { "New Message Bitmap", "bmc.new_message_bitmap",
300 FT_BYTES
, BASE_NONE
, NULL
, 0,
303 { &hf_bmc_message_description_type
,
304 { "Message Description Type", "bmc.message_description_type",
305 FT_UINT8
, BASE_DEC
, message_description_type_vals
, 0,
308 { &hf_bmc_offset_to_ctch_bs_index_of_first_transmission
,
309 { "Offset to CTCH BS index of first transmission", "bmc.offset_to_ctch_bs_index_of_first_transmission",
310 FT_UINT8
, BASE_DEC
, NULL
, 0,
313 { &hf_bmc_broadcast_address
,
314 { "Broadcast Address", "bmc.broadcast_address",
315 FT_BYTES
, BASE_NONE
, NULL
, 0,
319 { "CB Data41", "bmc.cb_data41",
320 FT_BYTES
, BASE_NONE
, NULL
, 0,
323 { &hf_bmc_future_extension_bitmap
,
324 { "Future Extension Bitmap", "bmc.future_extension_bitmap",
325 FT_UINT8
, BASE_DEC
, NULL
, 0,
328 { &hf_bmc_length_of_serial_number_list
,
329 { "Length of Serial Number List", "bmc.length_of_serial_number_list",
330 FT_UINT8
, BASE_DEC
, NULL
, 0,
333 { &hf_bmc_ctch_bs_index
,
334 { "CTCH BS Index", "bmc.ctch_bs_index",
335 FT_UINT8
, BASE_DEC
, NULL
, 0,
340 static gint
*ett
[] = {
342 &ett_bmc_message_description
345 proto_bmc
= proto_register_protocol("Broadcast/Multicast Control", "BMC", "bmc");
346 new_register_dissector("bmc", dissect_bmc
, proto_bmc
);
348 proto_register_field_array(proto_bmc
, hf
, array_length(hf
));
349 proto_register_subtree_array(ett
, array_length(ett
));