2 * Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP)
4 * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/conversation.h>
18 #include <epan/asn1.h>
20 #include "packet-e164.h"
21 #include "packet-e212.h"
22 #include "packet-gsm_map.h"
23 #include "packet-cell_broadcast.h"
24 #include "packet-tcp.h" // tcp_dissect_pdus()
26 #define FRAME_HEADER_LEN 4
28 /***********************************************************************
29 * TLV related definitions
30 ***********************************************************************/
32 /*! Entry in a TLV parser array */
34 uint16_t len
; /*!< length */
35 const uint8_t *val
; /*!< pointer to value */
40 TLV_TYPE_NONE
, /*!< no type */
41 TLV_TYPE_FIXED
, /*!< fixed-length value-only */
42 TLV_TYPE_TV
, /*!< tag-value (8bit) */
43 TLV_TYPE_TLV
, /*!< tag-length-value */
44 TLV_TYPE_TL16V
, /*!< tag, 16 bit length, value */
47 /*! Definition of a single IE (Information Element) */
49 enum tlv_type type
; /*!< TLV type */
50 uint8_t fixed_len
; /*!< length in case of TLV_TYPE_FIXED */
53 /*! Definition of All 256 IE / TLV */
54 struct tlv_definition
{
55 struct tlv_def def
[256];
59 /***********************************************************************
60 * CBSP Protocol Definitions, see libosmocore/include/gsm/protocol/gsm_48_049.h
61 ***********************************************************************/
63 #define CBSP_TCP_PORT 48049
65 /* 8.2.1 Information Element Identifiers */
67 CBSP_IEI_MSG_CONTENT
= 0x01,
68 CBSP_IEI_OLD_SERIAL_NR
= 0x02,
69 CBSP_IEI_NEW_SERIAL_NR
= 0x03,
70 CBSP_IEI_CELL_LIST
= 0x04,
71 CBSP_IEI_CATEGORY
= 0x05,
72 CBSP_IEI_REP_PERIOD
= 0x06,
73 CBSP_IEI_NUM_BCAST_REQ
= 0x07,
74 CBSP_IEI_NUM_BCAST_COMPL_LIST
= 0x08,
75 CBSP_IEI_FAILURE_LIST
= 0x09,
76 CBSP_IEI_RR_LOADING_LIST
= 0x0a,
77 CBSP_IEI_CAUSE
= 0x0b,
79 CBSP_IEI_RECOVERY_IND
= 0x0d,
80 CBSP_IEI_MSG_ID
= 0x0e,
81 CBSP_IEI_EMERG_IND
= 0x0f,
82 CBSP_IEI_WARN_TYPE
= 0x10,
83 CBSP_IEI_WARN_SEC_INFO
= 0x11,
84 CBSP_IEI_CHANNEL_IND
= 0x12,
85 CBSP_IEI_NUM_OF_PAGES
= 0x13,
86 CBSP_IEI_SCHEDULE_PERIOD
= 0x14,
87 CBSP_IEI_NUM_OF_RES_SLOTS
= 0x15,
88 CBSP_IEI_BCAST_MSG_TYPE
= 0x16,
89 CBSP_IEI_WARNING_PERIOD
= 0x17,
90 CBSP_IEI_KEEP_ALIVE_REP_PERIOD
= 0x18,
93 /* 8.2.2 Message Type */
95 CBSP_MSGT_WRITE_REPLACE
= 0x01,
96 CBSP_MSGT_WRITE_REPLACE_COMPL
= 0x02,
97 CBSP_MSGT_WRITE_REPLACE_FAIL
= 0x03,
98 CBSP_MSGT_KILL
= 0x04,
99 CBSP_MSGT_KILL_COMPL
= 0x05,
100 CBSP_MSGT_KILL_FAIL
= 0x06,
101 CBSP_MSGT_LOAD_QUERY
= 0x07,
102 CBSP_MSGT_LOAD_QUERY_COMPL
= 0x08,
103 CBSP_MSGT_LOAD_QUERY_FAIL
= 0x09,
104 CBSP_MSGT_MSG_STATUS_QUERY
= 0x0a,
105 CBSP_MSGT_MSG_STATUS_QUERY_COMPL
= 0x0b,
106 CBSP_MSGT_MSG_STATUS_QUERY_FAIL
= 0x0c,
107 CBSP_MSGT_SET_DRX
= 0x0d,
108 CBSP_MSGT_SET_DRX_COMPL
= 0x0e,
109 CBSP_MSGT_SET_DRX_FAIL
= 0x0f,
110 CBSP_MSGT_RESET
= 0x10,
111 CBSP_MSGT_RESET_COMPL
= 0x11,
112 CBSP_MSGT_RESET_FAIL
= 0x12,
113 CBSP_MSGT_RESTART
= 0x13,
114 CBSP_MSGT_FAILURE
= 0x14,
115 CBSP_MSGT_ERROR_IND
= 0x15,
116 CBSP_MSGT_KEEP_ALIVE
= 0x16,
117 CBSP_MSGT_KEEP_ALIVE_COMPL
= 0x17,
122 CBSP_CATEG_HIGH_PRIO
= 0x00,
123 CBSP_CATEG_BACKGROUND
= 0x01,
124 CBSP_CATEG_NORMAL
= 0x02,
127 /* 8.2.9 Number of Broadcast Info */
128 enum cbsp_num_bcast_info
{
129 CBSP_NUM_BCAST_INFO_VALID
= 0x0,
130 CBSP_NUM_BCAST_INFO_OVERFLOW
= 0x1,
131 CBSP_NUM_BCAST_INFO_UNKNOWN
= 0x2,
134 static const value_string cbsp_num_bcast_info_vals
[] = {
135 { CBSP_NUM_BCAST_INFO_VALID
, "Number of Broadcasts Complete is Valid" },
136 { CBSP_NUM_BCAST_INFO_OVERFLOW
, "Number of Broadcasts Complete has Overflown" },
137 { CBSP_NUM_BCAST_INFO_UNKNOWN
, "Number of Broadcasts Complete is undefined" },
141 static const value_string cbsp_num_bcast_shortinfo_vals
[] = {
142 { CBSP_NUM_BCAST_INFO_VALID
, "Valid" },
143 { CBSP_NUM_BCAST_INFO_OVERFLOW
, "Overflow" },
144 { CBSP_NUM_BCAST_INFO_UNKNOWN
, "Unknown" },
148 /* Cell ID Discriminator (8.2.11, ...) */
149 enum cbsp_cell_id_disc
{
150 CBSP_CIDD_WHOLE_CGI
= 0x0,
151 CBSP_CIDD_LAC_CI
= 0x1,
155 CBSP_CIDD_ALL_IN_BSC
= 0x6,
160 CBSP_CAUSE_PARAM_NOT_RECOGNISED
= 0x00,
161 CBSP_CAUSE_PARAM_VAL_INVALID
= 0x01,
162 CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED
= 0x02,
163 CBSP_CAUSE_CELL_ID_NOT_VALID
= 0x03,
164 CBSP_CAUSE_UNRECOGNISED_MSG
= 0x04,
165 CBSP_CAUSE_MISSING_MAND_IE
= 0x05,
166 CBSP_CAUSE_BSC_CAPACITY_EXCEEDED
= 0x06,
167 CBSP_CAUSE_CELL_MEMORY_EXCEEDED
= 0x07,
168 CBSP_CAUSE_BSC_MEMORY_EXCEEDED
= 0x08,
169 CBSP_CAUSE_CB_NOT_SUPPORTED
= 0x09,
170 CBSP_CAUSE_CB_NOT_OPERATIONAL
= 0x0a,
171 CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM
= 0x0b,
172 CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED
= 0x0c,
173 CBSP_CAUSE_MSG_REF_ALREADY_USED
= 0x0d,
174 CBSP_CAUSE_UNSPECIFIED_ERROR
= 0x0e,
175 CBSP_CAUSE_LAI_OR_LAC_NPT_VALID
= 0x0f,
179 static const value_string cbsp_recov_ind_vals
[] = {
180 { 0x0, "CBS/emergency message data available" },
181 { 0x1, "CBS/emergency message data lost" },
186 static const value_string cbsp_emerg_ind_vals
[] = {
188 { 0x1, "ETWS information available" },
193 static const value_string cbsp_chan_ind_vals
[] = {
194 { 0x0, "basic channel" },
195 { 0x1, "extended channel" },
200 static const value_string cbsp_bcast_msg_type_vals
[] = {
201 { 0x0, "CBS message broadcasting" },
202 { 0x1, "emergency message broadcasting" },
206 /* conversion function from 8.2.25 warning period to seconds */
207 static int cbsp_warn_period_to_secs(uint8_t warn_per
)
209 if (warn_per
<= 0x0a)
211 else if (warn_per
<= 0x14)
212 return 10 + (warn_per
-0x0a)*2;
213 else if (warn_per
<= 0x26)
214 return 30 + (warn_per
-0x14)*5;
215 else if (warn_per
<= 0x56)
216 return 120 + (warn_per
-0x26)*10;
217 else if (warn_per
<= 0xba)
218 return 600 + (warn_per
-0x56)*60;
223 static const value_string cbsp_cell_id_disc_vals
[] = {
224 { CBSP_CIDD_WHOLE_CGI
, "CGI" },
225 { CBSP_CIDD_LAC_CI
, "LAC+CI" },
226 { CBSP_CIDD_CI
, "CI" },
227 { CBSP_CIDD_LAI
, "LAI" },
228 { CBSP_CIDD_LAC
, "LAC" },
229 { CBSP_CIDD_ALL_IN_BSC
, "BSS" },
233 static const value_string cbsp_iei_names
[] = {
234 { CBSP_IEI_MSG_CONTENT
, "Message Content" },
235 { CBSP_IEI_OLD_SERIAL_NR
, "Old Serial Number" },
236 { CBSP_IEI_NEW_SERIAL_NR
, "New Serial Number" },
237 { CBSP_IEI_CELL_LIST
, "Cell List" },
238 { CBSP_IEI_CATEGORY
, "Category" },
239 { CBSP_IEI_REP_PERIOD
, "Repetition Period" },
240 { CBSP_IEI_NUM_BCAST_REQ
, "Number of Broadcasts Requested" },
241 { CBSP_IEI_NUM_BCAST_COMPL_LIST
,"Number of Broadcasts Completed List" },
242 { CBSP_IEI_FAILURE_LIST
, "Failure List" },
243 { CBSP_IEI_RR_LOADING_LIST
, "Radio Resource Loading List" },
244 { CBSP_IEI_CAUSE
, "Cause" },
245 { CBSP_IEI_DCS
, "Data Coding Scheme" },
246 { CBSP_IEI_RECOVERY_IND
, "Recovery Indication" },
247 { CBSP_IEI_MSG_ID
, "Message Identifier" },
248 { CBSP_IEI_EMERG_IND
, "Emergency Indicator" },
249 { CBSP_IEI_WARN_TYPE
, "Warning Type" },
250 { CBSP_IEI_WARN_SEC_INFO
, "Warning Security Information" },
251 { CBSP_IEI_CHANNEL_IND
, "Channel Indicator" },
252 { CBSP_IEI_NUM_OF_PAGES
, "Number of Pages" },
253 { CBSP_IEI_SCHEDULE_PERIOD
, "Schedule Period" },
254 { CBSP_IEI_NUM_OF_RES_SLOTS
, "Number of Reserved Slots" },
255 { CBSP_IEI_BCAST_MSG_TYPE
, "Broadcast Message Type" },
256 { CBSP_IEI_WARNING_PERIOD
, "Waring Period" },
257 { CBSP_IEI_KEEP_ALIVE_REP_PERIOD
, "Keep Alive Repetition Period" },
261 static const value_string cbsp_msg_type_names
[] = {
262 { CBSP_MSGT_WRITE_REPLACE
, "WRITE-REPLACE" },
263 { CBSP_MSGT_WRITE_REPLACE_COMPL
, "WRITE-REPLACE COMPLETE" },
264 { CBSP_MSGT_WRITE_REPLACE_FAIL
, "WRITE-REPLACE FAILURE" },
265 { CBSP_MSGT_KILL
, "KILL" },
266 { CBSP_MSGT_KILL_COMPL
, "KILL COMPLETE" },
267 { CBSP_MSGT_KILL_FAIL
, "KILL FAILURE" },
268 { CBSP_MSGT_LOAD_QUERY
, "LOAD QUERY" },
269 { CBSP_MSGT_LOAD_QUERY_COMPL
, "LOAD QUERY COMPLETE" },
270 { CBSP_MSGT_LOAD_QUERY_FAIL
, "LOAD QUERY FAILURE" },
271 { CBSP_MSGT_MSG_STATUS_QUERY
, "MESSAGE STATUS QUERY" },
272 { CBSP_MSGT_MSG_STATUS_QUERY_COMPL
, "MESSAGE STATUS QUERY COMPLETE" },
273 { CBSP_MSGT_MSG_STATUS_QUERY_FAIL
, "MESSAGE STATUS QUERY FAILURE" },
274 { CBSP_MSGT_SET_DRX
, "SET-DRX" },
275 { CBSP_MSGT_SET_DRX_COMPL
, "SET-DRX COMPLETE" },
276 { CBSP_MSGT_SET_DRX_FAIL
, "SET-DRX FAILURE" },
277 { CBSP_MSGT_RESET
, "RESET" },
278 { CBSP_MSGT_RESET_COMPL
, "RESET COMPLETE" },
279 { CBSP_MSGT_RESET_FAIL
, "RESET FAILURE" },
280 { CBSP_MSGT_RESTART
, "RESTART" },
281 { CBSP_MSGT_FAILURE
, "FAILURE" },
282 { CBSP_MSGT_ERROR_IND
, "ERROR INDICATION" },
283 { CBSP_MSGT_KEEP_ALIVE
, "KEEP-ALIVE" },
284 { CBSP_MSGT_KEEP_ALIVE_COMPL
, "KEEP-ALIVE COMPLETE" },
288 static const value_string cbsp_category_names
[] = {
289 { CBSP_CATEG_HIGH_PRIO
, "High Priority" },
290 { CBSP_CATEG_BACKGROUND
, "Background" },
291 { CBSP_CATEG_NORMAL
, "Normal" },
296 static const value_string cbsp_cause_vals
[] = {
297 { CBSP_CAUSE_PARAM_NOT_RECOGNISED
, "Parameter-not-recognized" },
298 { CBSP_CAUSE_PARAM_VAL_INVALID
, "Parameter-value-invalid" },
299 { CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED
, "Message-reference-not-identified" },
300 { CBSP_CAUSE_CELL_ID_NOT_VALID
, "Cell-identity-not-valid" },
301 { CBSP_CAUSE_UNRECOGNISED_MSG
, "Unrecognised-message" },
302 { CBSP_CAUSE_MISSING_MAND_IE
, "Missing-mandatory-element" },
303 { CBSP_CAUSE_BSC_CAPACITY_EXCEEDED
, "BSC-capacity-exceeded" },
304 { CBSP_CAUSE_CELL_MEMORY_EXCEEDED
, "Cell-memory-exceeded" },
305 { CBSP_CAUSE_BSC_MEMORY_EXCEEDED
, "BSC-memory-exceeded" },
306 { CBSP_CAUSE_CB_NOT_SUPPORTED
, "Cell-broadcast-not-supported" },
307 { CBSP_CAUSE_CB_NOT_OPERATIONAL
, "Cell-broadcast-not-operational" },
308 { CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM
, "Incompatible-DRX-parameter" },
309 { CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED
, "Extended-channel-not-supported" },
310 { CBSP_CAUSE_MSG_REF_ALREADY_USED
, "Message-reference-already-used" },
311 { CBSP_CAUSE_UNSPECIFIED_ERROR
, "Unspecified-error" },
312 { CBSP_CAUSE_LAI_OR_LAC_NPT_VALID
, "LAI-or-LAC-not-valid" },
316 static const struct tlv_definition cbsp_att_tlvdef
= {
318 [CBSP_IEI_MSG_CONTENT
] = { TLV_TYPE_FIXED
, 83 },
319 [CBSP_IEI_OLD_SERIAL_NR
] = { TLV_TYPE_FIXED
, 2 },
320 [CBSP_IEI_NEW_SERIAL_NR
] = { TLV_TYPE_FIXED
, 2 },
321 [CBSP_IEI_CELL_LIST
] = { TLV_TYPE_TL16V
, 0 },
322 [CBSP_IEI_CATEGORY
] = { TLV_TYPE_TV
, 0 },
323 [CBSP_IEI_REP_PERIOD
] = { TLV_TYPE_FIXED
, 2 },
324 [CBSP_IEI_NUM_BCAST_REQ
] = { TLV_TYPE_FIXED
, 2 },
325 [CBSP_IEI_NUM_BCAST_COMPL_LIST
] = { TLV_TYPE_TL16V
, 0 },
326 [CBSP_IEI_FAILURE_LIST
] = { TLV_TYPE_TL16V
, 0 },
327 [CBSP_IEI_RR_LOADING_LIST
] = { TLV_TYPE_TL16V
, 0 },
328 [CBSP_IEI_CAUSE
] = { TLV_TYPE_TV
, 0 },
329 [CBSP_IEI_DCS
] = { TLV_TYPE_TV
, 0 },
330 [CBSP_IEI_RECOVERY_IND
] = { TLV_TYPE_TV
, 0 },
331 [CBSP_IEI_MSG_ID
] = { TLV_TYPE_FIXED
, 2 },
332 [CBSP_IEI_EMERG_IND
] = { TLV_TYPE_TV
, 0 },
333 [CBSP_IEI_WARN_TYPE
] = { TLV_TYPE_FIXED
, 2 },
334 [CBSP_IEI_WARN_SEC_INFO
] = { TLV_TYPE_FIXED
, 50 },
335 [CBSP_IEI_CHANNEL_IND
] = { TLV_TYPE_TV
, 0 },
336 [CBSP_IEI_NUM_OF_PAGES
] = { TLV_TYPE_TV
, 0 },
337 [CBSP_IEI_SCHEDULE_PERIOD
] = { TLV_TYPE_TV
, 0 },
338 [CBSP_IEI_NUM_OF_RES_SLOTS
] = { TLV_TYPE_TV
, 0 },
339 [CBSP_IEI_BCAST_MSG_TYPE
] = { TLV_TYPE_TV
, 0 },
340 [CBSP_IEI_WARNING_PERIOD
] = { TLV_TYPE_TV
, 0 },
341 [CBSP_IEI_KEEP_ALIVE_REP_PERIOD
] = { TLV_TYPE_TV
, 0 },
345 /***********************************************************************
346 * Wireshark Dissector Implementation
347 ***********************************************************************/
349 void proto_register_cbsp(void);
350 void proto_reg_handoff_cbsp(void);
352 static dissector_handle_t cbsp_handle
;
354 static int proto_cbsp
;
356 static int hf_cbsp_msg_type
;
357 static int hf_cbsp_msg_len
;
358 static int hf_cbsp_iei
;
359 static int hf_cbsp_ie_len
;
360 static int hf_cbsp_ie_payload
;
362 static int hf_cbsp_old_serial_nr
;
363 static int hf_cbsp_new_serial_nr
;
364 static int hf_cbsp_category
;
365 static int hf_cbsp_rep_period
;
366 static int hf_cbsp_num_bcast_req
;
367 static int hf_cbsp_cause
;
368 static int hf_cbsp_dcs
;
369 static int hf_cbsp_recovery_ind
;
370 static int hf_cbsp_msg_id
;
371 static int hf_cbsp_emerg_ind
;
372 static int hf_cbsp_warn_type
;
373 static int hf_cbsp_channel_ind
;
374 static int hf_cbsp_num_of_pages
;
375 static int hf_cbsp_cb_msg_page
;
376 static int hf_cbsp_cbs_page_content
;
377 static int hf_cbsp_sched_period
;
378 static int hf_cbsp_num_of_res_slots
;
379 static int hf_cbsp_bcast_msg_type
;
380 static int hf_cbsp_warning_period
;
381 static int hf_cbsp_keepalive_period
;
382 static int hf_cbsp_user_info_length
;
383 static int hf_cbsp_cell_id_disc
;
384 static int hf_cbsp_cell_load1
;
385 static int hf_cbsp_cell_load2
;
386 static int hf_cbsp_num_bcast_compl
;
387 static int hf_cbsp_num_bcast_info
;
388 static int hf_cbsp_lac
;
389 static int hf_cbsp_ci
;
392 static int ett_cbsp_ie
;
393 static int ett_cbsp_cbs_data_coding
;
394 static int ett_cbsp_cbs_page_content
;
395 static int ett_cbsp_cell_list
;
396 static int ett_cbsp_fail_list
;
397 static int ett_cbsp_load_list
;
398 static int ett_cbsp_num_bcast_compl_list
;
401 dissect_cbsp_content_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, int len
, proto_tree
*tree
,
402 uint8_t sms_encoding
, proto_item
*ti
)
404 proto_item
*cbs_page_item
;
405 tvbuff_t
*next_tvb
, *unpacked_tvb
;
408 proto_tree_add_item(tree
, hf_cbsp_user_info_length
, tvb
, offset
, 1, ENC_NA
);
409 cbs_page_item
= proto_tree_add_item(tree
, hf_cbsp_cb_msg_page
, tvb
, offset
+1, len
-1, ENC_NA
);
410 next_tvb
= tvb_new_subset_length(tvb
, offset
+1, len
-1);
412 unpacked_tvb
= dissect_cbs_data(sms_encoding
, next_tvb
, tree
, pinfo
, 0);
414 unsigned captured_len
= tvb_captured_length(unpacked_tvb
);
415 proto_tree
*cbs_page_subtree
= proto_item_add_subtree(cbs_page_item
, ett_cbsp_cbs_page_content
);
416 proto_tree_add_item_ret_string(cbs_page_subtree
, hf_cbsp_cbs_page_content
, unpacked_tvb
,
417 0, captured_len
, ENC_UTF_8
|ENC_NA
, pinfo
->pool
,
419 proto_item_append_text(ti
, ": '%s'", pstr
);
423 /* Section 8.2.6 Cell List */
425 dissect_cell_id_elem(uint8_t discr
, tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, int len _U_
,
426 proto_tree
*tree
, proto_item
*ti
)
428 unsigned base_offs
= offset
;
433 case CBSP_CIDD_WHOLE_CGI
:
434 mcc_mnc
= dissect_e212_mcc_mnc_wmem_packet_str(tvb
, pinfo
, tree
, offset
, E212_NONE
, true);
436 proto_tree_add_item_ret_uint(tree
, hf_cbsp_lac
, tvb
, offset
, 2, ENC_NA
, &lac
);
438 proto_tree_add_item_ret_uint(tree
, hf_cbsp_ci
, tvb
, offset
, 2, ENC_NA
, &ci
);
440 proto_item_append_text(ti
, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc
, lac
, ci
);
442 case CBSP_CIDD_LAC_CI
:
443 proto_tree_add_item_ret_uint(tree
, hf_cbsp_lac
, tvb
, offset
, 2, ENC_NA
, &lac
);
445 proto_tree_add_item_ret_uint(tree
, hf_cbsp_ci
, tvb
, offset
, 2, ENC_NA
, &ci
);
447 proto_item_append_text(ti
, ": LAC 0%04x, CI 0x%04x", lac
, ci
);
450 proto_tree_add_item_ret_uint(tree
, hf_cbsp_ci
, tvb
, offset
, 2, ENC_NA
, &ci
);
452 proto_item_append_text(ti
, ": CI 0x%04x", ci
);
455 mcc_mnc
= dissect_e212_mcc_mnc_wmem_packet_str(tvb
, pinfo
, tree
, offset
, E212_NONE
, true);
457 proto_tree_add_item_ret_uint(tree
, hf_cbsp_lac
, tvb
, offset
, 2, ENC_NA
, &lac
);
459 proto_item_append_text(ti
, ": %s, LAC 0x%04x", mcc_mnc
, lac
);
462 proto_tree_add_item_ret_uint(tree
, hf_cbsp_lac
, tvb
, offset
, 2, ENC_NA
, &lac
);
464 proto_item_append_text(ti
, ": LAC 0x%04x", lac
);
466 case CBSP_CIDD_ALL_IN_BSC
:
472 return offset
- base_offs
;
475 /* return the length of a single list element of the given discriminator/type */
476 static int cell_id_len(uint8_t discr
)
479 case CBSP_CIDD_WHOLE_CGI
:
481 case CBSP_CIDD_LAC_CI
:
489 case CBSP_CIDD_ALL_IN_BSC
:
497 dissect_cell_id_list_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, unsigned len
, proto_tree
*tree
,
498 proto_item
*parent_ti
)
500 unsigned base_offs
= offset
;
504 /* list-global discriminator */
505 proto_tree_add_item_ret_uint(tree
, hf_cbsp_cell_id_disc
, tvb
, offset
, 1, ENC_NA
, &discr
);
509 /* iterate over list items */
510 while (offset
- base_offs
< len
) {
511 proto_tree
*elem_tree
;
515 unsigned remain_len
= len
- (offset
- base_offs
);
516 elem_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, cell_id_len(discr
),
517 ett_cbsp_cell_list
, &ti
,
519 rc
= dissect_cell_id_elem(discr
, tvb
, pinfo
, offset
, remain_len
, elem_tree
, ti
);
525 proto_item_append_text(parent_ti
, " (%s): %u items",
526 val_to_str_const(discr
, cbsp_cell_id_disc_vals
, ""), count
);
530 dissect_rr_load_list_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, unsigned len
, proto_tree
*tree
,
531 proto_item
*parent_ti
)
533 unsigned base_offs
= offset
;
537 /* list-global discriminator */
538 proto_tree_add_item_ret_uint(tree
, hf_cbsp_cell_id_disc
, tvb
, offset
, 1, ENC_NA
, &discr
);
542 /* iterate over list items */
543 while (offset
- base_offs
< len
) {
544 proto_tree
*elem_tree
;
545 uint32_t load1
, load2
;
549 unsigned remain_len
= len
- (offset
- base_offs
);
550 elem_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, cell_id_len(discr
)+2,
551 ett_cbsp_load_list
, &ti
,
552 "RR Load List Item");
553 rc
= dissect_cell_id_elem(discr
, tvb
, pinfo
, offset
, remain_len
, elem_tree
, ti
);
558 proto_tree_add_item_ret_uint(elem_tree
, hf_cbsp_cell_load1
, tvb
, offset
++, 1,
560 proto_tree_add_item_ret_uint(elem_tree
, hf_cbsp_cell_load2
, tvb
, offset
++, 1,
562 proto_item_append_text(ti
, ": L1=%u%%, L2=%u%%", load1
, load2
);
565 proto_item_append_text(parent_ti
, " (%s): %u items",
566 val_to_str_const(discr
, cbsp_cell_id_disc_vals
, ""), count
);
570 dissect_failure_list_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, unsigned len
, proto_tree
*tree
,
571 proto_item
*parent_ti
)
573 unsigned base_offs
= offset
;
576 /* iterate over list items, each with its own discriminator */
577 while (offset
- base_offs
< len
) {
578 proto_tree
*elem_tree
;
580 unsigned remain_len
, cause
;
583 uint8_t discr
= tvb_get_uint8(tvb
, offset
) & 0x0f;
584 elem_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, cell_id_len(discr
)+2,
585 ett_cbsp_fail_list
, &ti
,
586 "Failure List Item");
587 proto_tree_add_item(elem_tree
, hf_cbsp_cell_id_disc
, tvb
, offset
++, 1, ENC_NA
);
588 remain_len
= len
- (offset
- base_offs
);
589 rc
= dissect_cell_id_elem(discr
, tvb
, pinfo
, offset
, remain_len
, elem_tree
, ti
);
594 proto_tree_add_item_ret_uint(elem_tree
, hf_cbsp_cause
, tvb
, offset
++, 1, ENC_NA
, &cause
);
595 proto_item_append_text(ti
, ": Cause %s",
596 val_to_str_const(cause
, cbsp_cause_vals
, "Undefined"));
599 proto_item_append_text(parent_ti
, ": %u items", count
);
604 dissect_bc_compl_list_ie(tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, unsigned len
, proto_tree
*tree
,
605 proto_item
*parent_ti
)
607 unsigned base_offs
= offset
;
611 /* list-global discriminator */
612 proto_tree_add_item_ret_uint(tree
, hf_cbsp_cell_id_disc
, tvb
, offset
, 1, ENC_NA
, &discr
);
616 /* iterate over list items */
617 while (offset
- base_offs
< len
) {
618 proto_tree
*elem_tree
;
620 uint32_t num_bc
, num_bi
;
623 unsigned remain_len
= len
- (offset
- base_offs
);
624 elem_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, cell_id_len(discr
)+3,
625 ett_cbsp_num_bcast_compl_list
, &ti
,
626 "Number of Broadcasts completed");
627 rc
= dissect_cell_id_elem(discr
, tvb
, pinfo
, offset
, remain_len
, elem_tree
, ti
);
632 proto_tree_add_item_ret_uint(elem_tree
, hf_cbsp_num_bcast_compl
, tvb
, offset
, 2, ENC_NA
,
635 proto_tree_add_item_ret_uint(elem_tree
, hf_cbsp_num_bcast_info
, tvb
, offset
++, 1, ENC_NA
,
637 proto_item_append_text(ti
, ": NumBC=%u (%s)", num_bc
,
638 val_to_str_const(num_bi
, cbsp_num_bcast_shortinfo_vals
, ""));
641 proto_item_append_text(parent_ti
, " (%s): %u items",
642 val_to_str_const(discr
, cbsp_cell_id_disc_vals
, ""), count
);
646 dissect_cbsp_tlvs(tvbuff_t
*tvb
, int base_offs
, int length
, packet_info
*pinfo
, proto_tree
*tree
)
648 uint8_t sms_encoding
= SMS_ENCODING_7BIT
;
649 int offset
= base_offs
;
651 while (offset
- base_offs
< length
) {
652 uint8_t tag
; /* Information Element Identifier */
653 unsigned int len
; /* Length of payload */
654 unsigned int len_len
= 0;/* Length of "length" field (may be 0) */
656 proto_tree
*att_tree
, *subtree
;
660 tag
= tvb_get_uint8(tvb
, offset
);
663 switch (cbsp_att_tlvdef
.def
[tag
].type
) {
669 len
= cbsp_att_tlvdef
.def
[tag
].fixed_len
;
673 len
= tvb_get_uint8(tvb
, offset
);
676 len
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
);
683 att_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
-1, 1+len_len
+len
,
684 ett_cbsp_ie
, &ti
, "IE: %s",
685 val_to_str(tag
, cbsp_iei_names
, "Unknown 0x%02x"));
686 proto_tree_add_item(att_tree
, hf_cbsp_iei
, tvb
, offset
-1, 1, ENC_NA
);
688 proto_tree_add_uint(att_tree
, hf_cbsp_ie_len
, tvb
, offset
, len_len
, len
);
693 case CBSP_IEI_MSG_CONTENT
:
694 dissect_cbsp_content_ie(tvb
, pinfo
, offset
, len
, att_tree
, sms_encoding
, ti
);
696 case CBSP_IEI_OLD_SERIAL_NR
:
697 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_old_serial_nr
, tvb
, offset
, len
, ENC_BIG_ENDIAN
, &tmp_u
);
698 proto_item_append_text(ti
, ": 0x%04x", tmp_u
);
700 case CBSP_IEI_NEW_SERIAL_NR
:
701 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_new_serial_nr
, tvb
, offset
, len
, ENC_BIG_ENDIAN
, &tmp_u
);
702 proto_item_append_text(ti
, ": 0x%04x", tmp_u
);
704 case CBSP_IEI_CATEGORY
:
705 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_category
, tvb
, offset
, len
, ENC_NA
,&tmp_u
);
706 proto_item_append_text(ti
, ": %s", val_to_str_const(tmp_u
, cbsp_category_names
, ""));
708 case CBSP_IEI_REP_PERIOD
:
711 crumb_spec_t cbsp_rep_period_crumbs
[] = {
717 proto_tree_add_split_bits_item_ret_val(att_tree
, hf_cbsp_rep_period
, tvb
, offset
<<3, cbsp_rep_period_crumbs
, &tmp_u64
);
718 proto_item_append_text(ti
, ": %u", (uint16_t)tmp_u64
);
721 case CBSP_IEI_NUM_BCAST_REQ
:
722 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_num_bcast_req
, tvb
, offset
, len
, ENC_BIG_ENDIAN
, &tmp_u
);
723 proto_item_append_text(ti
, ": %u", tmp_u
);
726 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_cause
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
727 proto_item_append_text(ti
, ": %s", val_to_str_const(tmp_u
, cbsp_cause_vals
, ""));
730 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_dcs
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
731 subtree
= proto_item_add_subtree(att_tree
, ett_cbsp_cbs_data_coding
);
732 sms_encoding
= dissect_cbs_data_coding_scheme(tvb
, pinfo
, subtree
, offset
);
733 proto_item_append_text(ti
, ": 0x%02x", tmp_u
);
735 case CBSP_IEI_RECOVERY_IND
:
736 proto_tree_add_item(att_tree
, hf_cbsp_recovery_ind
, tvb
, offset
, len
, ENC_NA
);
738 case CBSP_IEI_MSG_ID
:
739 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_msg_id
, tvb
, offset
, len
, ENC_BIG_ENDIAN
, &tmp_u
);
740 proto_item_append_text(ti
, ": 0x%04x", tmp_u
);
742 case CBSP_IEI_EMERG_IND
:
743 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_emerg_ind
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
744 proto_item_append_text(ti
, ": %s", val_to_str_const(tmp_u
, cbsp_emerg_ind_vals
, ""));
746 case CBSP_IEI_WARN_TYPE
:
747 proto_tree_add_item(att_tree
, hf_cbsp_warn_type
, tvb
, offset
, len
, ENC_NA
);
749 case CBSP_IEI_CHANNEL_IND
:
750 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_channel_ind
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
751 proto_item_append_text(ti
, ": %s", val_to_str_const(tmp_u
, cbsp_chan_ind_vals
, ""));
753 case CBSP_IEI_NUM_OF_PAGES
:
754 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_num_of_pages
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
755 proto_item_append_text(ti
, ": %u", tmp_u
);
757 case CBSP_IEI_SCHEDULE_PERIOD
:
758 proto_tree_add_item(att_tree
, hf_cbsp_sched_period
, tvb
, offset
, len
, ENC_NA
);
760 case CBSP_IEI_NUM_OF_RES_SLOTS
:
761 proto_tree_add_item(att_tree
, hf_cbsp_num_of_res_slots
, tvb
, offset
, len
, ENC_NA
);
763 case CBSP_IEI_BCAST_MSG_TYPE
:
764 proto_tree_add_item_ret_uint(att_tree
, hf_cbsp_bcast_msg_type
, tvb
, offset
, len
, ENC_NA
, &tmp_u
);
765 proto_item_append_text(ti
, ": %s", val_to_str_const(tmp_u
, cbsp_bcast_msg_type_vals
, ""));
767 case CBSP_IEI_WARNING_PERIOD
:
768 secs
= cbsp_warn_period_to_secs(tvb_get_uint8(tvb
, offset
));
769 proto_tree_add_uint(att_tree
, hf_cbsp_warning_period
, tvb
, offset
, len
, secs
);
770 proto_item_append_text(ti
, ": %u (s)", secs
);
772 case CBSP_IEI_KEEP_ALIVE_REP_PERIOD
:
773 secs
= cbsp_warn_period_to_secs(tvb_get_uint8(tvb
, offset
));
774 proto_tree_add_uint(att_tree
, hf_cbsp_keepalive_period
, tvb
, offset
, len
, secs
);
775 proto_item_append_text(ti
, ": %u (s)", secs
);
777 case CBSP_IEI_CELL_LIST
:
778 dissect_cell_id_list_ie(tvb
, pinfo
, offset
, len
, att_tree
, ti
);
780 case CBSP_IEI_NUM_BCAST_COMPL_LIST
:
781 dissect_bc_compl_list_ie(tvb
, pinfo
, offset
, len
, att_tree
, ti
);
783 case CBSP_IEI_FAILURE_LIST
:
784 dissect_failure_list_ie(tvb
, pinfo
, offset
, len
, att_tree
, ti
);
786 case CBSP_IEI_RR_LOADING_LIST
:
787 dissect_rr_load_list_ie(tvb
, pinfo
, offset
, len
, att_tree
, ti
);
789 case CBSP_IEI_WARN_SEC_INFO
:
790 /* this element is bogus / not used anyway, no need for a dissector */
792 /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
793 proto_tree_add_item(att_tree
, hf_cbsp_ie_payload
, tvb
, offset
, len
, ENC_NA
);
803 /* This method dissects fully reassembled CBSP messages */
805 dissect_cbsp_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
807 int len_ind
, offset
= 0;
809 proto_tree
*cbsp_tree
= NULL
;
814 //len = tvb_reported_length(tvb);
815 msg_type
= tvb_get_uint8(tvb
, offset
+ 0);
816 len_ind
= tvb_get_uint24(tvb
, offset
+ 1, ENC_BIG_ENDIAN
);
818 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CBSP");
820 col_clear(pinfo
->cinfo
, COL_INFO
);
821 str
= val_to_str(msg_type
, cbsp_msg_type_names
, "Unknown CBSP Message Type 0x%02x");
822 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s ", str
);
825 ti
= proto_tree_add_protocol_format(tree
, proto_cbsp
, tvb
, 0,
826 len_ind
+ FRAME_HEADER_LEN
, "CBSP %s", str
);
827 cbsp_tree
= proto_item_add_subtree(ti
, ett_cbsp
);
829 proto_tree_add_item(cbsp_tree
, hf_cbsp_msg_type
,
830 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
833 proto_tree_add_item(cbsp_tree
, hf_cbsp_msg_len
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
836 dissect_cbsp_tlvs(tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), pinfo
,
840 return tvb_captured_length(tvb
);
843 /* determine PDU length of protocol cbsp */
845 get_cbsp_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
847 uint32_t len_ind
= tvb_get_uint24(tvb
, offset
+ 1, ENC_BIG_ENDIAN
);
849 return len_ind
+ FRAME_HEADER_LEN
;
852 /* The main dissecting routine */
854 dissect_cbsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
856 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, FRAME_HEADER_LEN
,
857 get_cbsp_message_len
, dissect_cbsp_message
, data
);
858 return tvb_captured_length(tvb
);
862 proto_register_cbsp(void)
864 static hf_register_info hf
[] = {
865 { &hf_cbsp_msg_type
, { "Message Type", "cbsp.msg_type",
866 FT_UINT8
, BASE_DEC
, VALS(cbsp_msg_type_names
), 0, NULL
, HFILL
} },
867 { &hf_cbsp_msg_len
, { "Message Length", "cbsp.msg_len",
868 FT_UINT24
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
870 { &hf_cbsp_iei
, { "Information Element Identifier", "cbsp.ie.iei",
871 FT_UINT8
, BASE_DEC
, VALS(cbsp_iei_names
), 0, NULL
, HFILL
} },
872 { &hf_cbsp_ie_len
, { "Information Element Length", "cbsp.ie.len",
873 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
874 { &hf_cbsp_ie_payload
, { "Information Element Payload", "cbsp.ie.payload",
875 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
877 { &hf_cbsp_old_serial_nr
, { "Old Serial Number", "cbsp.old_serial_nr",
878 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
879 { &hf_cbsp_new_serial_nr
, { "New Serial Number", "cbsp.new_serial_nr",
880 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
881 { &hf_cbsp_category
, { "Category", "cbsp.category",
882 FT_UINT8
, BASE_HEX
, VALS(cbsp_category_names
), 0, NULL
, HFILL
} },
883 { &hf_cbsp_rep_period
, { "Repetition Period (units of 1.883s)", "cbsp.rep_period",
884 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
885 { &hf_cbsp_num_bcast_req
, { "Number of Broadcasts Requested", "cbsp.num_bcast_req",
886 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
887 { &hf_cbsp_cause
, { "Cause", "cbsp.cause",
888 FT_UINT8
, BASE_HEX
, VALS(cbsp_cause_vals
), 0, NULL
, HFILL
} },
889 { &hf_cbsp_dcs
, { "Data Coding Scheme", "cbsp.dcs",
890 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
891 { &hf_cbsp_recovery_ind
, { "Recovery Indication", "cbsp.recovery_ind",
892 FT_UINT8
, BASE_HEX
, VALS(cbsp_recov_ind_vals
), 0, NULL
, HFILL
} },
893 { &hf_cbsp_msg_id
, { "Message Identifier", "cbsp.message_id",
894 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
895 { &hf_cbsp_emerg_ind
, { "Emergency Indicator", "cbsp.emergency_ind",
896 FT_UINT8
, BASE_HEX
, VALS(cbsp_emerg_ind_vals
), 0, NULL
, HFILL
} },
897 { &hf_cbsp_warn_type
, { "Warning Type", "cbsp.warn_type",
898 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
899 { &hf_cbsp_channel_ind
, { "Channel Indicator", "cbsp.channel_ind",
900 FT_UINT8
, BASE_HEX
, VALS(cbsp_chan_ind_vals
), 0, NULL
, HFILL
} },
901 { &hf_cbsp_num_of_pages
, { "Number of Pages", "cbsp.num_of_pages",
902 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
903 { &hf_cbsp_cb_msg_page
, { "CBS Message Information Page", "cbsp.cb_msg_page",
904 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
905 { &hf_cbsp_cbs_page_content
, { "CBS Page Content", "cbsp.cb_page_content",
906 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
907 { &hf_cbsp_sched_period
, { "Schedule Period", "cbsp.sched_period",
908 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
909 { &hf_cbsp_num_of_res_slots
, { "Number of Reserved Slots", "cbsp.num_of_res_slots",
910 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
911 { &hf_cbsp_bcast_msg_type
, { "Broadcast Message Type", "cbsp.bcast_msg_type",
912 FT_UINT8
, BASE_DEC
, VALS(cbsp_bcast_msg_type_vals
), 0, NULL
, HFILL
} },
913 { &hf_cbsp_warning_period
, { "Warning Period", "cbsp.warning_period",
914 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
915 { &hf_cbsp_keepalive_period
, { "Keepalive Repetition Period", "cbsp.keepalive_rep_period",
916 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
917 { &hf_cbsp_user_info_length
, { "User Information Length", "cbsp.user_info_len",
918 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
919 { &hf_cbsp_cell_id_disc
, { "Cell ID Discriminator", "cbsp.cell_id_disc",
920 FT_UINT8
, BASE_DEC
, VALS(cbsp_cell_id_disc_vals
), 0, NULL
, HFILL
} },
921 { &hf_cbsp_cell_load1
, { "Radio Resource Load 1", "cbsp.rr_load1",
922 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
923 { &hf_cbsp_cell_load2
, { "Radio Resource Load 2", "cbsp.rr_load2",
924 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
925 { &hf_cbsp_num_bcast_compl
, { "Number of Broadcasts Completed", "cbsp.num_bcast_compl",
926 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
927 { &hf_cbsp_num_bcast_info
, { "Number of Broadcasts Info", "cbsp.num_bcast_info",
928 FT_UINT8
, BASE_HEX
, VALS(cbsp_num_bcast_info_vals
), 0, NULL
, HFILL
} },
929 { &hf_cbsp_lac
, { "Location Area Code (LAC)", "cbsp.lac",
930 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
931 { &hf_cbsp_ci
, { "Cell Identifier (CI)", "cbsp.ci",
932 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
934 static int *ett
[] = {
937 &ett_cbsp_cbs_data_coding
,
938 &ett_cbsp_cbs_page_content
,
942 &ett_cbsp_num_bcast_compl_list
,
945 proto_cbsp
= proto_register_protocol("3GPP/GSM Cell Broadcast Service Protocol", "cbsp", "cbsp");
946 cbsp_handle
= register_dissector("cbsp", dissect_cbsp
, proto_cbsp
);
947 proto_register_field_array(proto_cbsp
, hf
, array_length(hf
));
948 proto_register_subtree_array(ett
, array_length(ett
));
952 proto_reg_handoff_cbsp(void)
954 dissector_add_uint_with_preference("tcp.port", CBSP_TCP_PORT
, cbsp_handle
);
958 * Editor modelines - https://www.wireshark.org/tools/modelines.html
963 * indent-tabs-mode: t
966 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
967 * :indentSize=8:tabSize=8:noTabs=false: