/src/wireshark/epan/dissectors/packet-gsm_cbsp.c
Line | Count | Source |
1 | | /* packet-gsm_cbsp.c |
2 | | * Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP) |
3 | | * |
4 | | * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | * |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | #include <epan/conversation.h> |
18 | | #include <epan/asn1.h> |
19 | | |
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() |
25 | | |
26 | 1.09k | #define FRAME_HEADER_LEN 4 |
27 | | |
28 | | /*********************************************************************** |
29 | | * TLV related definitions |
30 | | ***********************************************************************/ |
31 | | |
32 | | /*! Entry in a TLV parser array */ |
33 | | struct tlv_p_entry { |
34 | | uint16_t len; /*!< length */ |
35 | | const uint8_t *val; /*!< pointer to value */ |
36 | | }; |
37 | | |
38 | | /*! TLV type */ |
39 | | enum tlv_type { |
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 */ |
45 | | }; |
46 | | |
47 | | /*! Definition of a single IE (Information Element) */ |
48 | | struct tlv_def { |
49 | | enum tlv_type type; /*!< TLV type */ |
50 | | uint8_t fixed_len; /*!< length in case of TLV_TYPE_FIXED */ |
51 | | }; |
52 | | |
53 | | /*! Definition of All 256 IE / TLV */ |
54 | | struct tlv_definition { |
55 | | struct tlv_def def[256]; |
56 | | }; |
57 | | |
58 | | |
59 | | /*********************************************************************** |
60 | | * CBSP Protocol Definitions, see libosmocore/include/gsm/protocol/gsm_48_049.h |
61 | | ***********************************************************************/ |
62 | | |
63 | 14 | #define CBSP_TCP_PORT 48049 |
64 | | |
65 | | /* 8.2.1 Information Element Identifiers */ |
66 | | enum cbsp_iei { |
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, |
78 | | CBSP_IEI_DCS = 0x0c, |
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, |
91 | | }; |
92 | | |
93 | | /* 8.2.2 Message Type */ |
94 | | enum cbsp_msg_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, |
118 | | }; |
119 | | |
120 | | /* 8.2.7 Category */ |
121 | | enum cbsp_category { |
122 | | CBSP_CATEG_HIGH_PRIO = 0x00, |
123 | | CBSP_CATEG_BACKGROUND = 0x01, |
124 | | CBSP_CATEG_NORMAL = 0x02, |
125 | | }; |
126 | | |
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, |
132 | | }; |
133 | | |
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" }, |
138 | | { 0, NULL } |
139 | | }; |
140 | | |
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" }, |
145 | | { 0, NULL } |
146 | | }; |
147 | | |
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, |
152 | | CBSP_CIDD_CI = 0x2, |
153 | | CBSP_CIDD_LAI = 0x4, |
154 | | CBSP_CIDD_LAC = 0x5, |
155 | | CBSP_CIDD_ALL_IN_BSC = 0x6, |
156 | | }; |
157 | | |
158 | | /* 8.2.13 Cause */ |
159 | | enum cbsp_cause { |
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, |
176 | | }; |
177 | | |
178 | | /* 8.2.15 */ |
179 | | static const value_string cbsp_recov_ind_vals[] = { |
180 | | { 0x0, "CBS/emergency message data available" }, |
181 | | { 0x1, "CBS/emergency message data lost" }, |
182 | | { 0, NULL } |
183 | | }; |
184 | | |
185 | | /* 8.2.17 */ |
186 | | static const value_string cbsp_emerg_ind_vals[] = { |
187 | | { 0x0, "reserved" }, |
188 | | { 0x1, "ETWS information available" }, |
189 | | { 0, NULL } |
190 | | }; |
191 | | |
192 | | /* 8.2.20 */ |
193 | | static const value_string cbsp_chan_ind_vals[] = { |
194 | | { 0x0, "basic channel" }, |
195 | | { 0x1, "extended channel" }, |
196 | | { 0, NULL } |
197 | | }; |
198 | | |
199 | | /* 8.2.24 */ |
200 | | static const value_string cbsp_bcast_msg_type_vals[] = { |
201 | | { 0x0, "CBS message broadcasting" }, |
202 | | { 0x1, "emergency message broadcasting" }, |
203 | | { 0, NULL } |
204 | | }; |
205 | | |
206 | | /* conversion function from 8.2.25 warning period to seconds */ |
207 | | static int cbsp_warn_period_to_secs(uint8_t warn_per) |
208 | 30 | { |
209 | 30 | if (warn_per <= 0x0a) |
210 | 2 | return warn_per; |
211 | 28 | else if (warn_per <= 0x14) |
212 | 2 | return 10 + (warn_per-0x0a)*2; |
213 | 26 | else if (warn_per <= 0x26) |
214 | 16 | return 30 + (warn_per-0x14)*5; |
215 | 10 | else if (warn_per <= 0x56) |
216 | 1 | return 120 + (warn_per-0x26)*10; |
217 | 9 | else if (warn_per <= 0xba) |
218 | 6 | return 600 + (warn_per-0x56)*60; |
219 | 3 | else |
220 | 3 | return -1; |
221 | 30 | } |
222 | | |
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" }, |
230 | | { 0, NULL } |
231 | | }; |
232 | | |
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" }, |
258 | | { 0, NULL } |
259 | | }; |
260 | | |
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" }, |
285 | | { 0, NULL } |
286 | | }; |
287 | | |
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" }, |
292 | | { 0, NULL } |
293 | | }; |
294 | | |
295 | | /* 8.2.13 */ |
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" }, |
313 | | { 0, NULL } |
314 | | }; |
315 | | |
316 | | static const struct tlv_definition cbsp_att_tlvdef = { |
317 | | .def = { |
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 }, |
342 | | }, |
343 | | }; |
344 | | |
345 | | /*********************************************************************** |
346 | | * Wireshark Dissector Implementation |
347 | | ***********************************************************************/ |
348 | | |
349 | | void proto_register_cbsp(void); |
350 | | void proto_reg_handoff_cbsp(void); |
351 | | |
352 | | static dissector_handle_t cbsp_handle; |
353 | | |
354 | | static int proto_cbsp; |
355 | | |
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; |
361 | | |
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; |
390 | | |
391 | | static int ett_cbsp; |
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; |
399 | | |
400 | | static void |
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) |
403 | 10 | { |
404 | 10 | proto_item *cbs_page_item; |
405 | 10 | tvbuff_t *next_tvb, *unpacked_tvb; |
406 | 10 | const uint8_t *pstr; |
407 | | |
408 | 10 | proto_tree_add_item(tree, hf_cbsp_user_info_length, tvb, offset, 1, ENC_NA); |
409 | 10 | cbs_page_item = proto_tree_add_item(tree, hf_cbsp_cb_msg_page, tvb, offset+1, len-1, ENC_NA); |
410 | 10 | next_tvb = tvb_new_subset_length(tvb, offset+1, len-1); |
411 | | |
412 | 10 | unpacked_tvb = dissect_cbs_data(sms_encoding, next_tvb, tree, pinfo, 0); |
413 | 10 | if (tree) { |
414 | 8 | unsigned captured_len = tvb_captured_length(unpacked_tvb); |
415 | 8 | proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_cbsp_cbs_page_content); |
416 | 8 | proto_tree_add_item_ret_string(cbs_page_subtree, hf_cbsp_cbs_page_content, unpacked_tvb, |
417 | 8 | 0, captured_len, ENC_UTF_8|ENC_NA, pinfo->pool, |
418 | 8 | &pstr); |
419 | 8 | proto_item_append_text(ti, ": '%s'", pstr); |
420 | 8 | } |
421 | 10 | } |
422 | | |
423 | | /* Section 8.2.6 Cell List */ |
424 | | static int |
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) |
427 | 1.30k | { |
428 | 1.30k | unsigned base_offs = offset; |
429 | 1.30k | char *mcc_mnc; |
430 | 1.30k | uint32_t lac, ci; |
431 | | |
432 | 1.30k | switch (discr) { |
433 | 113 | case CBSP_CIDD_WHOLE_CGI: |
434 | 113 | mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true); |
435 | 113 | offset += 3; |
436 | 113 | proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac); |
437 | 113 | offset += 2; |
438 | 113 | proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci); |
439 | 113 | offset += 2; |
440 | 113 | proto_item_append_text(ti, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc, lac, ci); |
441 | 113 | break; |
442 | 56 | case CBSP_CIDD_LAC_CI: |
443 | 56 | proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac); |
444 | 56 | offset += 2; |
445 | 56 | proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci); |
446 | 56 | offset += 2; |
447 | 56 | proto_item_append_text(ti, ": LAC 0%04x, CI 0x%04x", lac, ci); |
448 | 56 | break; |
449 | 743 | case CBSP_CIDD_CI: |
450 | 743 | proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_BIG_ENDIAN, &ci); |
451 | 743 | offset += 2; |
452 | 743 | proto_item_append_text(ti, ": CI 0x%04x", ci); |
453 | 743 | break; |
454 | 109 | case CBSP_CIDD_LAI: |
455 | 109 | mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, true); |
456 | 109 | offset += 3; |
457 | 109 | proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac); |
458 | 109 | offset += 2; |
459 | 109 | proto_item_append_text(ti, ": %s, LAC 0x%04x", mcc_mnc, lac); |
460 | 109 | break; |
461 | 259 | case CBSP_CIDD_LAC: |
462 | 259 | proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_BIG_ENDIAN, &lac); |
463 | 259 | offset += 2; |
464 | 259 | proto_item_append_text(ti, ": LAC 0x%04x", lac); |
465 | 259 | break; |
466 | 4 | case CBSP_CIDD_ALL_IN_BSC: |
467 | 4 | break; |
468 | 17 | default: |
469 | 17 | return -1; |
470 | 1.30k | } |
471 | | |
472 | 1.26k | return offset - base_offs; |
473 | 1.30k | } |
474 | | |
475 | | /* return the length of a single list element of the given discriminator/type */ |
476 | | static int cell_id_len(uint8_t discr) |
477 | 1.30k | { |
478 | 1.30k | switch (discr) { |
479 | 113 | case CBSP_CIDD_WHOLE_CGI: |
480 | 113 | return 7; |
481 | 56 | case CBSP_CIDD_LAC_CI: |
482 | 56 | return 4; |
483 | 743 | case CBSP_CIDD_CI: |
484 | 743 | return 2; |
485 | 109 | case CBSP_CIDD_LAI: |
486 | 109 | return 5; |
487 | 259 | case CBSP_CIDD_LAC: |
488 | 259 | return 2; |
489 | 4 | case CBSP_CIDD_ALL_IN_BSC: |
490 | 4 | return 0; |
491 | 17 | default: |
492 | 17 | return -1; |
493 | 1.30k | } |
494 | 1.30k | } |
495 | | |
496 | | static void |
497 | | dissect_cell_id_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree, |
498 | | proto_item *parent_ti) |
499 | 22 | { |
500 | 22 | unsigned base_offs = offset; |
501 | 22 | uint32_t discr; |
502 | 22 | unsigned count = 0; |
503 | | |
504 | | /* list-global discriminator */ |
505 | 22 | proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr); |
506 | 22 | discr &= 0x0f; |
507 | 22 | offset++; |
508 | | |
509 | | /* iterate over list items */ |
510 | 1.12k | while (offset - base_offs < len) { |
511 | 1.10k | proto_tree *elem_tree; |
512 | 1.10k | proto_item *ti; |
513 | 1.10k | int rc; |
514 | | |
515 | 1.10k | unsigned remain_len = len - (offset - base_offs); |
516 | 1.10k | elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr), |
517 | 1.10k | ett_cbsp_cell_list, &ti, |
518 | 1.10k | "Cell List Item"); |
519 | 1.10k | rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); |
520 | 1.10k | if (rc <= 0) |
521 | 2 | break; |
522 | 1.10k | offset += rc; |
523 | 1.10k | count++; |
524 | 1.10k | } |
525 | 22 | proto_item_append_text(parent_ti, " (%s): %u items", |
526 | 22 | val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count); |
527 | 22 | } |
528 | | |
529 | | static void |
530 | | dissect_rr_load_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree, |
531 | | proto_item *parent_ti) |
532 | 14 | { |
533 | 14 | unsigned base_offs = offset; |
534 | 14 | uint32_t discr; |
535 | 14 | unsigned count = 0; |
536 | | |
537 | | /* list-global discriminator */ |
538 | 14 | proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr); |
539 | 14 | discr &= 0x0f; |
540 | 14 | offset++; |
541 | | |
542 | | /* iterate over list items */ |
543 | 115 | while (offset - base_offs < len) { |
544 | 108 | proto_tree *elem_tree; |
545 | 108 | uint32_t load1, load2; |
546 | 108 | proto_item *ti; |
547 | 108 | int rc; |
548 | | |
549 | 108 | unsigned remain_len = len - (offset - base_offs); |
550 | 108 | elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2, |
551 | 108 | ett_cbsp_load_list, &ti, |
552 | 108 | "RR Load List Item"); |
553 | 108 | rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); |
554 | 108 | if (rc <= 0) |
555 | 7 | break; |
556 | 101 | offset += rc; |
557 | | |
558 | 101 | proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load1, tvb, offset++, 1, |
559 | 101 | ENC_NA, &load1); |
560 | 101 | proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load2, tvb, offset++, 1, |
561 | 101 | ENC_NA, &load2); |
562 | 101 | proto_item_append_text(ti, ": L1=%u%%, L2=%u%%", load1, load2); |
563 | 101 | count++; |
564 | 101 | } |
565 | 14 | proto_item_append_text(parent_ti, " (%s): %u items", |
566 | 14 | val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count); |
567 | 14 | } |
568 | | |
569 | | static void |
570 | | dissect_failure_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree, |
571 | | proto_item *parent_ti) |
572 | 9 | { |
573 | 9 | unsigned base_offs = offset; |
574 | 9 | unsigned count = 0; |
575 | | |
576 | | /* iterate over list items, each with its own discriminator */ |
577 | 48 | while (offset - base_offs < len) { |
578 | 47 | proto_tree *elem_tree; |
579 | 47 | proto_item *ti; |
580 | 47 | unsigned remain_len, cause; |
581 | 47 | int rc; |
582 | | |
583 | 47 | uint8_t discr = tvb_get_uint8(tvb, offset) & 0x0f; |
584 | 47 | elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2, |
585 | 47 | ett_cbsp_fail_list, &ti, |
586 | 47 | "Failure List Item"); |
587 | 47 | proto_tree_add_item(elem_tree, hf_cbsp_cell_id_disc, tvb, offset++, 1, ENC_NA); |
588 | 47 | remain_len = len - (offset - base_offs); |
589 | 47 | rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); |
590 | 47 | if (rc <= 0) |
591 | 8 | break; |
592 | 39 | offset += rc; |
593 | | |
594 | 39 | proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cause, tvb, offset++, 1, ENC_NA, &cause); |
595 | 39 | proto_item_append_text(ti, ": Cause %s", |
596 | 39 | val_to_str_const(cause, cbsp_cause_vals, "Undefined")); |
597 | 39 | count++; |
598 | 39 | } |
599 | 9 | proto_item_append_text(parent_ti, ": %u items", count); |
600 | | |
601 | 9 | } |
602 | | |
603 | | static void |
604 | | dissect_bc_compl_list_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree, |
605 | | proto_item *parent_ti) |
606 | 8 | { |
607 | 8 | unsigned base_offs = offset; |
608 | 8 | uint32_t discr; |
609 | 8 | unsigned count = 0; |
610 | | |
611 | | /* list-global discriminator */ |
612 | 8 | proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr); |
613 | 8 | discr &= 0x0f; |
614 | 8 | offset++; |
615 | | |
616 | | /* iterate over list items */ |
617 | 46 | while (offset - base_offs < len) { |
618 | 42 | proto_tree *elem_tree; |
619 | 42 | proto_item *ti; |
620 | 42 | uint32_t num_bc, num_bi; |
621 | 42 | int rc; |
622 | | |
623 | 42 | unsigned remain_len = len - (offset - base_offs); |
624 | 42 | elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+3, |
625 | 42 | ett_cbsp_num_bcast_compl_list, &ti, |
626 | 42 | "Number of Broadcasts completed"); |
627 | 42 | rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti); |
628 | 42 | if (rc <= 0) |
629 | 4 | break; |
630 | 38 | offset += rc; |
631 | | |
632 | 38 | proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_compl, tvb, offset, 2, ENC_BIG_ENDIAN, |
633 | 38 | &num_bc); |
634 | 38 | offset += 2; |
635 | 38 | proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_info, tvb, offset++, 1, ENC_NA, |
636 | 38 | &num_bi); |
637 | 38 | proto_item_append_text(ti, ": NumBC=%u (%s)", num_bc, |
638 | 38 | val_to_str_const(num_bi, cbsp_num_bcast_shortinfo_vals, "")); |
639 | 38 | count++; |
640 | 38 | } |
641 | 8 | proto_item_append_text(parent_ti, " (%s): %u items", |
642 | 8 | val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count); |
643 | 8 | } |
644 | | |
645 | | static int |
646 | | dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree) |
647 | 490 | { |
648 | 490 | uint8_t sms_encoding = SMS_ENCODING_7BIT; |
649 | 490 | int offset = base_offs; |
650 | | |
651 | 1.14k | while (offset - base_offs < length) { |
652 | 817 | uint8_t tag; /* Information Element Identifier */ |
653 | 817 | unsigned int len; /* Length of payload */ |
654 | 817 | unsigned int len_len = 0;/* Length of "length" field (may be 0) */ |
655 | 817 | proto_item *ti; |
656 | 817 | proto_tree *att_tree, *subtree; |
657 | 817 | uint32_t tmp_u; |
658 | 817 | int secs; |
659 | | |
660 | 817 | tag = tvb_get_uint8(tvb, offset); |
661 | 817 | offset++; |
662 | | |
663 | 817 | switch (cbsp_att_tlvdef.def[tag].type) { |
664 | 415 | case TLV_TYPE_TV: |
665 | 415 | len = 1; |
666 | 415 | len_len = 0; |
667 | 415 | break; |
668 | 222 | case TLV_TYPE_FIXED: |
669 | 222 | len = cbsp_att_tlvdef.def[tag].fixed_len; |
670 | 222 | len_len = 0; |
671 | 222 | break; |
672 | 0 | case TLV_TYPE_TLV: |
673 | 0 | len = tvb_get_uint8(tvb, offset); |
674 | 0 | break; |
675 | 53 | case TLV_TYPE_TL16V: |
676 | 53 | len = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
677 | 53 | len_len = 2; |
678 | 53 | break; |
679 | 118 | default: |
680 | 118 | return length; |
681 | 817 | } |
682 | | |
683 | 690 | att_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+len_len+len, |
684 | 690 | ett_cbsp_ie, &ti, "IE: %s", |
685 | 690 | val_to_str(pinfo->pool, tag, cbsp_iei_names, "Unknown 0x%02x")); |
686 | 690 | proto_tree_add_item(att_tree, hf_cbsp_iei, tvb, offset-1, 1, ENC_NA); |
687 | 690 | if (len_len) |
688 | 53 | proto_tree_add_uint(att_tree, hf_cbsp_ie_len, tvb, offset, len_len, len); |
689 | | |
690 | 690 | offset += len_len; |
691 | | |
692 | 690 | switch (tag) { |
693 | 10 | case CBSP_IEI_MSG_CONTENT: |
694 | 10 | dissect_cbsp_content_ie(tvb, pinfo, offset, len, att_tree, sms_encoding, ti); |
695 | 10 | break; |
696 | 27 | case CBSP_IEI_OLD_SERIAL_NR: |
697 | 27 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); |
698 | 27 | proto_item_append_text(ti, ": 0x%04x", tmp_u); |
699 | 27 | break; |
700 | 5 | case CBSP_IEI_NEW_SERIAL_NR: |
701 | 5 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); |
702 | 5 | proto_item_append_text(ti, ": 0x%04x", tmp_u); |
703 | 5 | break; |
704 | 73 | case CBSP_IEI_CATEGORY: |
705 | 73 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA,&tmp_u); |
706 | 73 | proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_category_names, "")); |
707 | 73 | break; |
708 | 10 | case CBSP_IEI_REP_PERIOD: |
709 | 10 | { |
710 | 10 | uint64_t tmp_u64; |
711 | 10 | crumb_spec_t cbsp_rep_period_crumbs[] = { |
712 | 10 | { 0, 8 }, |
713 | 10 | { 12, 4 }, |
714 | 10 | { 0, 0 } |
715 | 10 | }; |
716 | | |
717 | 10 | proto_tree_add_split_bits_item_ret_val(att_tree, hf_cbsp_rep_period, tvb, offset<<3, cbsp_rep_period_crumbs, &tmp_u64); |
718 | 10 | proto_item_append_text(ti, ": %u", (uint16_t)tmp_u64); |
719 | 10 | } |
720 | 10 | break; |
721 | 44 | case CBSP_IEI_NUM_BCAST_REQ: |
722 | 44 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); |
723 | 44 | proto_item_append_text(ti, ": %u", tmp_u); |
724 | 44 | break; |
725 | 4 | case CBSP_IEI_CAUSE: |
726 | 4 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA, &tmp_u); |
727 | 4 | proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_cause_vals, "")); |
728 | 4 | break; |
729 | 41 | case CBSP_IEI_DCS: |
730 | 41 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA, &tmp_u); |
731 | 41 | subtree = proto_item_add_subtree(att_tree, ett_cbsp_cbs_data_coding); |
732 | 41 | sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, subtree, offset); |
733 | 41 | proto_item_append_text(ti, ": 0x%02x", tmp_u); |
734 | 41 | break; |
735 | 4 | case CBSP_IEI_RECOVERY_IND: |
736 | 4 | proto_tree_add_item(att_tree, hf_cbsp_recovery_ind, tvb, offset, len, ENC_NA); |
737 | 4 | break; |
738 | 76 | case CBSP_IEI_MSG_ID: |
739 | 76 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u); |
740 | 76 | proto_item_append_text(ti, ": 0x%04x", tmp_u); |
741 | 76 | break; |
742 | 101 | case CBSP_IEI_EMERG_IND: |
743 | 101 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA, &tmp_u); |
744 | 101 | proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_emerg_ind_vals, "")); |
745 | 101 | break; |
746 | 46 | case CBSP_IEI_WARN_TYPE: |
747 | 46 | proto_tree_add_item(att_tree, hf_cbsp_warn_type, tvb, offset, len, ENC_NA); |
748 | 46 | break; |
749 | 53 | case CBSP_IEI_CHANNEL_IND: |
750 | 53 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA, &tmp_u); |
751 | 53 | proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_chan_ind_vals, "")); |
752 | 53 | break; |
753 | 22 | case CBSP_IEI_NUM_OF_PAGES: |
754 | 22 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA, &tmp_u); |
755 | 22 | proto_item_append_text(ti, ": %u", tmp_u); |
756 | 22 | break; |
757 | 48 | case CBSP_IEI_SCHEDULE_PERIOD: |
758 | 48 | proto_tree_add_item(att_tree, hf_cbsp_sched_period, tvb, offset, len, ENC_NA); |
759 | 48 | break; |
760 | 33 | case CBSP_IEI_NUM_OF_RES_SLOTS: |
761 | 33 | proto_tree_add_item(att_tree, hf_cbsp_num_of_res_slots, tvb, offset, len, ENC_NA); |
762 | 33 | break; |
763 | 6 | case CBSP_IEI_BCAST_MSG_TYPE: |
764 | 6 | proto_tree_add_item_ret_uint(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA, &tmp_u); |
765 | 6 | proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_bcast_msg_type_vals, "")); |
766 | 6 | break; |
767 | 29 | case CBSP_IEI_WARNING_PERIOD: |
768 | 29 | secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset)); |
769 | 29 | proto_tree_add_uint(att_tree, hf_cbsp_warning_period, tvb, offset, len, secs); |
770 | 29 | proto_item_append_text(ti, ": %u (s)", secs); |
771 | 29 | break; |
772 | 1 | case CBSP_IEI_KEEP_ALIVE_REP_PERIOD: |
773 | 1 | secs = cbsp_warn_period_to_secs(tvb_get_uint8(tvb, offset)); |
774 | 1 | proto_tree_add_uint(att_tree, hf_cbsp_keepalive_period, tvb, offset, len, secs); |
775 | 1 | proto_item_append_text(ti, ": %u (s)", secs); |
776 | 1 | break; |
777 | 22 | case CBSP_IEI_CELL_LIST: |
778 | 22 | dissect_cell_id_list_ie(tvb, pinfo, offset, len, att_tree, ti); |
779 | 22 | break; |
780 | 8 | case CBSP_IEI_NUM_BCAST_COMPL_LIST: |
781 | 8 | dissect_bc_compl_list_ie(tvb, pinfo, offset, len, att_tree, ti); |
782 | 8 | break; |
783 | 9 | case CBSP_IEI_FAILURE_LIST: |
784 | 9 | dissect_failure_list_ie(tvb, pinfo, offset, len, att_tree, ti); |
785 | 9 | break; |
786 | 14 | case CBSP_IEI_RR_LOADING_LIST: |
787 | 14 | dissect_rr_load_list_ie(tvb, pinfo, offset, len, att_tree, ti); |
788 | 14 | break; |
789 | 4 | case CBSP_IEI_WARN_SEC_INFO: |
790 | | /* this element is bogus / not used anyway, no need for a dissector */ |
791 | 4 | default: |
792 | | /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */ |
793 | 4 | proto_tree_add_item(att_tree, hf_cbsp_ie_payload, tvb, offset, len, ENC_NA); |
794 | 4 | break; |
795 | 690 | } |
796 | | |
797 | 658 | offset += len; |
798 | 658 | } |
799 | | |
800 | 331 | return offset; |
801 | 490 | } |
802 | | |
803 | | /* This method dissects fully reassembled CBSP messages */ |
804 | | static int |
805 | | dissect_cbsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
806 | 490 | { |
807 | 490 | int len_ind, offset = 0; |
808 | 490 | proto_item *ti; |
809 | 490 | proto_tree *cbsp_tree = NULL; |
810 | 490 | uint8_t msg_type; |
811 | 490 | const char *str; |
812 | | |
813 | | |
814 | | //len = tvb_reported_length(tvb); |
815 | 490 | msg_type = tvb_get_uint8(tvb, offset + 0); |
816 | 490 | len_ind = tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN); |
817 | | |
818 | 490 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "CBSP"); |
819 | | |
820 | 490 | col_clear(pinfo->cinfo, COL_INFO); |
821 | 490 | str = val_to_str(pinfo->pool, msg_type, cbsp_msg_type_names, "Unknown CBSP Message Type 0x%02x"); |
822 | 490 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str); |
823 | | |
824 | 490 | if (tree) { |
825 | 490 | ti = proto_tree_add_protocol_format(tree, proto_cbsp, tvb, 0, |
826 | 490 | len_ind + FRAME_HEADER_LEN, "CBSP %s", str); |
827 | 490 | cbsp_tree = proto_item_add_subtree(ti, ett_cbsp); |
828 | | |
829 | 490 | proto_tree_add_item(cbsp_tree, hf_cbsp_msg_type, |
830 | 490 | tvb, offset, 1, ENC_BIG_ENDIAN); |
831 | 490 | offset++; |
832 | | |
833 | 490 | proto_tree_add_item(cbsp_tree, hf_cbsp_msg_len, tvb, offset, 3, ENC_BIG_ENDIAN); |
834 | 490 | offset += 3; |
835 | | |
836 | 490 | dissect_cbsp_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo, |
837 | 490 | cbsp_tree); |
838 | 490 | } |
839 | | |
840 | 490 | return tvb_captured_length(tvb); |
841 | 490 | } |
842 | | |
843 | | /* determine PDU length of protocol cbsp */ |
844 | | static unsigned |
845 | | get_cbsp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
846 | 490 | { |
847 | 490 | uint32_t len_ind = tvb_get_uint24(tvb, offset + 1, ENC_BIG_ENDIAN); |
848 | | |
849 | 490 | return len_ind + FRAME_HEADER_LEN; |
850 | 490 | } |
851 | | |
852 | | /* The main dissecting routine */ |
853 | | static int |
854 | | dissect_cbsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
855 | 110 | { |
856 | 110 | tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN, |
857 | 110 | get_cbsp_message_len, dissect_cbsp_message, data); |
858 | 110 | return tvb_captured_length(tvb); |
859 | 110 | } |
860 | | |
861 | | void |
862 | | proto_register_cbsp(void) |
863 | 14 | { |
864 | 14 | static hf_register_info hf[] = { |
865 | 14 | { &hf_cbsp_msg_type, { "Message Type", "cbsp.msg_type", |
866 | 14 | FT_UINT8, BASE_DEC, VALS(cbsp_msg_type_names), 0, NULL, HFILL } }, |
867 | 14 | { &hf_cbsp_msg_len, { "Message Length", "cbsp.msg_len", |
868 | 14 | FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL } }, |
869 | | |
870 | 14 | { &hf_cbsp_iei, { "Information Element Identifier", "cbsp.ie.iei", |
871 | 14 | FT_UINT8, BASE_DEC, VALS(cbsp_iei_names), 0, NULL, HFILL } }, |
872 | 14 | { &hf_cbsp_ie_len, { "Information Element Length", "cbsp.ie.len", |
873 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
874 | 14 | { &hf_cbsp_ie_payload, { "Information Element Payload", "cbsp.ie.payload", |
875 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } }, |
876 | | |
877 | 14 | { &hf_cbsp_old_serial_nr, { "Old Serial Number", "cbsp.old_serial_nr", |
878 | 14 | FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
879 | 14 | { &hf_cbsp_new_serial_nr, { "New Serial Number", "cbsp.new_serial_nr", |
880 | 14 | FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
881 | 14 | { &hf_cbsp_category, { "Category", "cbsp.category", |
882 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_category_names), 0, NULL, HFILL } }, |
883 | 14 | { &hf_cbsp_rep_period, { "Repetition Period (units of 1.883s)", "cbsp.rep_period", |
884 | 14 | FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
885 | 14 | { &hf_cbsp_num_bcast_req, { "Number of Broadcasts Requested", "cbsp.num_bcast_req", |
886 | 14 | FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
887 | 14 | { &hf_cbsp_cause, { "Cause", "cbsp.cause", |
888 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_cause_vals), 0, NULL, HFILL } }, |
889 | 14 | { &hf_cbsp_dcs, { "Data Coding Scheme", "cbsp.dcs", |
890 | 14 | FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
891 | 14 | { &hf_cbsp_recovery_ind, { "Recovery Indication", "cbsp.recovery_ind", |
892 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_recov_ind_vals), 0, NULL, HFILL } }, |
893 | 14 | { &hf_cbsp_msg_id, { "Message Identifier", "cbsp.message_id", |
894 | 14 | FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
895 | 14 | { &hf_cbsp_emerg_ind, { "Emergency Indicator", "cbsp.emergency_ind", |
896 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_emerg_ind_vals), 0, NULL, HFILL } }, |
897 | 14 | { &hf_cbsp_warn_type, { "Warning Type", "cbsp.warn_type", |
898 | 14 | FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, |
899 | 14 | { &hf_cbsp_channel_ind, { "Channel Indicator", "cbsp.channel_ind", |
900 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_chan_ind_vals), 0, NULL, HFILL } }, |
901 | 14 | { &hf_cbsp_num_of_pages, { "Number of Pages", "cbsp.num_of_pages", |
902 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
903 | 14 | { &hf_cbsp_cb_msg_page, { "CBS Message Information Page", "cbsp.cb_msg_page", |
904 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } }, |
905 | 14 | { &hf_cbsp_cbs_page_content, { "CBS Page Content", "cbsp.cb_page_content", |
906 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } }, |
907 | 14 | { &hf_cbsp_sched_period, { "Schedule Period", "cbsp.sched_period", |
908 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
909 | 14 | { &hf_cbsp_num_of_res_slots, { "Number of Reserved Slots", "cbsp.num_of_res_slots", |
910 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
911 | 14 | { &hf_cbsp_bcast_msg_type, { "Broadcast Message Type", "cbsp.bcast_msg_type", |
912 | 14 | FT_UINT8, BASE_DEC, VALS(cbsp_bcast_msg_type_vals), 0, NULL, HFILL } }, |
913 | 14 | { &hf_cbsp_warning_period, { "Warning Period", "cbsp.warning_period", |
914 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
915 | 14 | { &hf_cbsp_keepalive_period, { "Keepalive Repetition Period", "cbsp.keepalive_rep_period", |
916 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
917 | 14 | { &hf_cbsp_user_info_length, { "User Information Length", "cbsp.user_info_len", |
918 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
919 | 14 | { &hf_cbsp_cell_id_disc, { "Cell ID Discriminator", "cbsp.cell_id_disc", |
920 | 14 | FT_UINT8, BASE_DEC, VALS(cbsp_cell_id_disc_vals), 0, NULL, HFILL } }, |
921 | 14 | { &hf_cbsp_cell_load1, { "Radio Resource Load 1", "cbsp.rr_load1", |
922 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
923 | 14 | { &hf_cbsp_cell_load2, { "Radio Resource Load 2", "cbsp.rr_load2", |
924 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, |
925 | 14 | { &hf_cbsp_num_bcast_compl, { "Number of Broadcasts Completed", "cbsp.num_bcast_compl", |
926 | 14 | FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, |
927 | 14 | { &hf_cbsp_num_bcast_info, { "Number of Broadcasts Info", "cbsp.num_bcast_info", |
928 | 14 | FT_UINT8, BASE_HEX, VALS(cbsp_num_bcast_info_vals), 0, NULL, HFILL } }, |
929 | 14 | { &hf_cbsp_lac, { "Location Area Code (LAC)", "cbsp.lac", |
930 | 14 | FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
931 | 14 | { &hf_cbsp_ci, { "Cell Identifier (CI)", "cbsp.ci", |
932 | 14 | FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, |
933 | 14 | }; |
934 | 14 | static int *ett[] = { |
935 | 14 | &ett_cbsp, |
936 | 14 | &ett_cbsp_ie, |
937 | 14 | &ett_cbsp_cbs_data_coding, |
938 | 14 | &ett_cbsp_cbs_page_content, |
939 | 14 | &ett_cbsp_cell_list, |
940 | 14 | &ett_cbsp_fail_list, |
941 | 14 | &ett_cbsp_load_list, |
942 | 14 | &ett_cbsp_num_bcast_compl_list, |
943 | 14 | }; |
944 | | |
945 | 14 | proto_cbsp = proto_register_protocol("3GPP/GSM Cell Broadcast Service Protocol", "cbsp", "cbsp"); |
946 | 14 | cbsp_handle = register_dissector("cbsp", dissect_cbsp, proto_cbsp); |
947 | 14 | proto_register_field_array(proto_cbsp, hf, array_length(hf)); |
948 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
949 | 14 | } |
950 | | |
951 | | void |
952 | | proto_reg_handoff_cbsp(void) |
953 | 14 | { |
954 | 14 | dissector_add_uint_with_preference("tcp.port", CBSP_TCP_PORT, cbsp_handle); |
955 | 14 | } |
956 | | |
957 | | /* |
958 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
959 | | * |
960 | | * Local variables: |
961 | | * c-basic-offset: 8 |
962 | | * tab-width: 8 |
963 | | * indent-tabs-mode: t |
964 | | * End: |
965 | | * |
966 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
967 | | * :indentSize=8:tabSize=8:noTabs=false: |
968 | | */ |