MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-bssap.c
blob665e82333b6595e175ef6b75007c0b3d670b13f5
1 /* packet-bssap.c
2 * Routines for Base Station Subsystem Application Part (BSSAP/BSAP) dissection
3 * Specifications from 3GPP2 (www.3gpp2.org) and 3GPP (www.3gpp.org)
4 * IOS 4.0.1 (BSAP)
5 * GSM 08.06 (BSSAP)
7 * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
8 * In association with Telos Technology Inc.
10 * Added BSSAP+ according to ETSI TS 129 018 V6.3.0 (2005-3GPP TS 29.018 version 6.3.0 Release 6)
11 * Copyright 2006, Anders Broman <Anders.Broman [AT] ericsson.com>
13 * $Id$
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "config.h"
36 #include <glib.h>
38 #include <epan/packet.h>
39 #include <epan/prefs.h>
40 #include <epan/wmem/wmem.h>
42 #include "packet-bssap.h"
43 #include "packet-sccp.h"
44 #include "packet-gsm_a_common.h"
45 #include "packet-e212.h"
47 void proto_register_bssap(void);
48 void proto_reg_handoff_bssap(void);
50 #define BSSAP 0
51 #define BSAP 1
53 #define GSM_INTERFACE 0
54 #define LB_INTERFACE 1
56 #define BSSAP_OR_BSAP_DEFAULT BSSAP
58 #define GSM_OR_LB_INTERFACE_DEFAULT GSM_INTERFACE
60 #define PDU_TYPE_OFFSET 0
61 #define PDU_TYPE_LENGTH 1
63 /* Same as below but with names typed out */
64 static const value_string bssap_pdu_type_values[] = {
65 { BSSAP_PDU_TYPE_BSSMAP, "BSS Management" },
66 { BSSAP_PDU_TYPE_DTAP, "Direct Transfer" },
67 { 0, NULL } };
69 static const value_string bsap_pdu_type_values[] = {
70 { BSSAP_PDU_TYPE_BSSMAP, "BS Management" },
71 { BSSAP_PDU_TYPE_DTAP, "Direct Transfer" },
72 { 0, NULL } };
74 /* Same as above but in acronym for (for the Info column) */
75 static const value_string bssap_pdu_type_acro_values[] = {
76 { BSSAP_PDU_TYPE_BSSMAP, "BSSMAP" },
77 { BSSAP_PDU_TYPE_DTAP, "DTAP" },
78 { 0, NULL } };
80 /* Same as above but in acronym for (for the Info column) */
81 static const value_string bsap_pdu_type_acro_values[] = {
82 { BSSAP_PDU_TYPE_BSSMAP, "BSMAP" },
83 { BSSAP_PDU_TYPE_DTAP, "DTAP" },
84 { 0, NULL } };
86 #define PARAMETER_DLCI 0x00
87 #define PARAMETER_LENGTH 0x01
88 #define PARAMETER_DATA 0x02
90 #define DLCI_LENGTH 1
91 #define LENGTH_LENGTH 1
92 #define DATA_LENGTH 1
94 #define CC_MASK 0xc0
95 #define SPARE_MASK 0x38
96 #define SAPI_MASK 0x07
98 static guint global_bssap_ssn = 98;
100 static const value_string bssap_cc_values[] = {
101 { 0x00, "not further specified" },
102 { 0x80, "FACCH or SDCCH" },
103 { 0xc0, "SACCH" },
104 { 0, NULL } };
106 static const value_string bsap_cc_values[] = {
107 { 0x00, "default for TIA/EIA/IS-2000" },
108 { 0, NULL } };
110 static const value_string bssap_sapi_values[] = {
111 { 0x00, "RR/MM/CC" },
112 { 0x03, "SMS" },
113 { 0, NULL } };
115 static const value_string bsap_sapi_values[] = {
116 { 0x00, "Not used" },
117 { 0, NULL } };
119 #define BSSAP_PAGING_REQUEST 1
120 #define BSSAP_PAGING_REJECT 2 /* 17.1.18 */
121 #define BSSAP_DOWNLINK_TUNNEL_REQUEST 7 /* 17.1.4 */
122 #define BSSAP_UPLINK_TUNNEL_REQUEST 8 /* 17.1.23 */
123 #define BSSAP_LOCATION_UPDATE_REQUEST 9 /* 17.1.11 */
124 #define BSSAP_LOCATION_UPDATE_ACCEPT 10 /* 17.1.9 */
125 #define BSSAP_LOCATION_UPDATE_REJECT 11 /* 17.1.10 */
126 #define BSSAP_TMSI_REALLOCATION_COMPLETE 12 /* 17.1.22 */
127 #define BSSAP_ALERT_REQUEST 13 /* 17.1.3 */
128 #define BSSAP_ALERT_ACK 14 /* 17.1.1 */
129 #define BSSAP_ALERT_REJECT 15 /* 17.1.2 */
130 #define BSSAP_MS_ACTIVITY_INDICATION 16 /* 17.1.14 */
131 #define BSSAP_GPRS_DETACH_INDICATION 17 /* 17.1.6 */
132 #define BSSAP_GPRS_DETACH_ACK 18 /* 17.1.5 */
133 #define BSSAP_IMSI_DETACH_INDICATION 19 /* 17.1.8 */
134 #define BSSAP_IMSI_DETACH_ACK 20 /* 17.1.7 */
135 #define BSSAP_RESET_INDICATION 21 /* 17.1.21 */
136 #define BSSAP_RESET_ACK 22 /* 17.1.20 */
137 #define BSSAP_MS_INFORMATION_REQUEST 23 /* 17.1.15 */
138 #define BSSAP_MS_INFORMATION_RESPONSE 24 /* 17.1.16 */
139 #define BSSAP_MM_INFORMATION_REQUEST 26 /* 17.1.12 */
140 #define BSSAP_MOBILE_STATUS 29 /* 17.1.13 */
141 #define BSSAP_MS_UNREACHABLE 31 /* 17.1.17 */
143 static const value_string bssap_plus_message_type_values[] = {
144 /* 0 */ { 0x00, "Unassigned: treated as an unknown Message type." },
145 /* 1 */ { BSSAP_PAGING_REQUEST, "BSSAP+-PAGING-REQUEST" }, /* 17.1.19 */
146 /* 2 */ { BSSAP_PAGING_REJECT, "BSSAP+-PAGING-REJECT" }, /* 17.1.18 */
147 /* 3 */ { 0x03, "Unassigned: treated as an unknown Message type." },
148 /* 4 */ { 0x04, "Unassigned: treated as an unknown Message type." },
149 /* 5 */ { 0x05, "Unassigned: treated as an unknown Message type." },
150 /* 6 */ { 0x06, "Unassigned: treated as an unknown Message type." },
151 /* 7 */ { BSSAP_DOWNLINK_TUNNEL_REQUEST, "BSSAP+-DOWNLINK-TUNNEL-REQUEST" }, /* 17.1.4 */
152 /* 8 */ { BSSAP_UPLINK_TUNNEL_REQUEST, "BSSAP+-UPLINK-TUNNEL-REQUEST" }, /* 17.1.23 */
153 /* 9 */ { BSSAP_LOCATION_UPDATE_REQUEST, "BSSAP+-LOCATION-UPDATE-REQUEST" }, /* 17.1.11 */
154 /* 10 */ { BSSAP_LOCATION_UPDATE_ACCEPT, "BSSAP+-LOCATION-UPDATE-ACCEPT" }, /* 17.1.9 */
155 /* 11 */ { BSSAP_LOCATION_UPDATE_REJECT, "BSSAP+-LOCATION-UPDATE-REJECT" }, /* 17.1.10 */
156 /* 12 */ { BSSAP_TMSI_REALLOCATION_COMPLETE, "BSSAP+-TMSI-REALLOCATION-COMPLETE" }, /* 17.1.22 */
157 /* 13 */ { BSSAP_ALERT_REQUEST, "BSSAP+-ALERT-REQUEST" }, /* 17.1.3 */
158 /* 14 */ { BSSAP_ALERT_ACK, "BSSAP+-ALERT-ACK" }, /* 17.1.1 */
159 /* 15 */ { BSSAP_ALERT_REJECT, "BSSAP+-ALERT-REJECT" }, /* 17.1.2 */
160 /* 16 */ { BSSAP_MS_ACTIVITY_INDICATION, "BSSAP+-MS-ACTIVITY-INDICATION" }, /* 17.1.14 */
161 /* 17 */ { BSSAP_GPRS_DETACH_INDICATION, "BSSAP+-GPRS-DETACH-INDICATION" }, /* 17.1.6 */
162 /* 18 */ { BSSAP_GPRS_DETACH_ACK, "BSSAP+-GPRS-DETACH-ACK" }, /* 17.1.5 */
163 /* 19 */ { BSSAP_IMSI_DETACH_INDICATION, "BSSAP+-IMSI-DETACH-INDICATION" }, /* 17.1.8 */
164 /* 20 */ { BSSAP_IMSI_DETACH_ACK, "BSSAP+-IMSI-DETACH-ACK" }, /* 17.1.7 */
165 /* 21 */ { BSSAP_RESET_INDICATION, "BSSAP+-RESET-INDICATION" }, /* 17.1.21 */
166 /* 22 */ { BSSAP_RESET_ACK, "BSSAP+-RESET-ACK" }, /* 17.1.20 */
167 /* 23 */ { BSSAP_MS_INFORMATION_REQUEST, "BSSAP+-MS-INFORMATION-REQUEST" }, /* 17.1.15 */
168 /* 24 */ { BSSAP_MS_INFORMATION_RESPONSE, "BSSAP+-MS-INFORMATION-RESPONSE" }, /* 17.1.16 */
169 /* 25 */ { 0x19, "Unassigned: treated as an unknown Message type." },
170 /* 26 */ { BSSAP_MM_INFORMATION_REQUEST, "BSSAP+-MM-INFORMATION-REQUEST" }, /* 17.1.12 */
171 /* 27 */ { 0x1b, "Unassigned: treated as an unknown Message type." },
172 /* 28 */ { 0x1c, "Unassigned: treated as an unknown Message type." },
173 /* 29 */ { BSSAP_MOBILE_STATUS, "BSSAP+-MOBILE-STATUS" }, /* 17.1.13 */
174 /* 30 */ { 0x1e, "Unassigned: treated as an unknown Message type." },
175 /* 31 */ { BSSAP_MS_UNREACHABLE, "BSSAP+-MS-UNREACHABLE" }, /* 17.1.17 */
176 { 0, NULL }
178 static value_string_ext bssap_plus_message_type_values_ext = VALUE_STRING_EXT_INIT(bssap_plus_message_type_values);
180 #define BSSAP_IMSI 1
181 #define BSSAP_VLR_NUMBER 2
182 #define BSSAP_TMSI 3
183 #define BSSAP_LOC_AREA_ID 4
184 #define BSSAP_CHANNEL_NEEDED 5
185 #define BSSAP_EMLPP_PRIORITY 6
186 #define BSSAP_TMSI_STATUS 7
187 #define BSSAP_GS_CAUSE 8
188 #define BSSAP_SGSN_NUMBER 9
189 #define BSSAP_GPRS_LOC_UPD_TYPE 0x0a
190 #define BSSAP_GLOBAL_CN_ID 0x0b
191 #define BSSAP_MOBILE_STN_CLS_MRK1 0x0d
192 #define BSSAP_MOBILE_ID 0x0e
193 #define BSSAP_REJECT_CAUSE 0x0f
194 #define BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE 0x10
195 #define BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE 0x11
196 #define BSSAP_INFO_REQ 0x12
197 #define BSSAP_PTMSI 0x13
198 #define BSSAP_IMEI 0x14
199 #define BSSAP_IMEISV 0x15
200 #define BSSAP_MM_INFORMATION 0x17
201 #define BSSAP_CELL_GBL_ID 0x18
202 #define BSSAP_LOC_INF_AGE 0x19
203 #define BSSAP_MOBILE_STN_STATE 0x1a
204 #define BSSAP_ERRONEOUS_MSG 0x1b
205 #define BSSAP_DLINK_TNL_PLD_CTR_AND_INF 0x1c
206 #define BSSAP_ULINK_TNL_PLD_CTR_AND_INF 0x1d
207 #define BSSAP_SERVICE_AREA_ID 0x1e
208 #define BSSAP_MSI_BASED_NRI_CON 0x1f
210 static const value_string bssap_plus_ie_id_values[] = {
211 { BSSAP_IMSI, "IMSI" }, /* 18.4.10 */
212 { BSSAP_VLR_NUMBER, "VLR number" }, /* 18.4.26 */
213 { BSSAP_TMSI, "TMSI" }, /* 18.4.23 */
214 { BSSAP_LOC_AREA_ID, "Location area identifier" }, /* 18.4.14 */
215 { BSSAP_CHANNEL_NEEDED, "Channel Needed" }, /* 18.4.2 */
216 { BSSAP_EMLPP_PRIORITY, "eMLPP Priority" }, /* 18.4.4 */
217 { BSSAP_TMSI_STATUS, "TMSI status" }, /* 18.4.24 */
218 { BSSAP_GS_CAUSE, "Gs cause" }, /* 18.4.7 */
219 { BSSAP_SGSN_NUMBER, "SGSN number" }, /* 18.4.22 */
220 { BSSAP_GPRS_LOC_UPD_TYPE, "GPRS location update type" }, /* 18.4.6 */
221 { BSSAP_GLOBAL_CN_ID, "Global CN-Id" }, /* 18.4.27 */
222 { 0x0c, "Unassigned: treated as an unknown IEI." }, /* 18 and 16 */
223 { BSSAP_MOBILE_STN_CLS_MRK1, "Mobile station classmark 1" }, /* 18.4.18 */
224 { BSSAP_MOBILE_ID, "Mobile identity" }, /* 18.4.17 */
225 { BSSAP_REJECT_CAUSE, "Reject cause" }, /* 18.4.21 */
226 { BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE, "IMSI detach from GPRS service type" }, /* 18.4.11 */
227 { BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE, "IMSI detach from non-GPRS service type" }, /* 18.4.12 */
228 { BSSAP_INFO_REQ, "Information requested" }, /* 18.4.13 */
229 { BSSAP_PTMSI, "PTMSI" }, /* 18.4.20 */
230 { BSSAP_IMEI, "IMEI" }, /* 18.4.8 */
231 { BSSAP_IMEISV, "IMEISV" }, /* 18.4.9 */
232 { 0x16, "Unassigned: treated as an unknown IEI." }, /* 18 and 16 */
233 { BSSAP_MM_INFORMATION, "MM information" }, /* 18.4.16 */
234 { BSSAP_CELL_GBL_ID, "Cell Global Identity" }, /* 18.4.1 */
235 { BSSAP_LOC_INF_AGE, "Location information age" }, /* 18.4.15 */
236 { BSSAP_MOBILE_STN_STATE, "Mobile station state" }, /* 18.4.19 */
237 { BSSAP_ERRONEOUS_MSG, "Erroneous message" }, /* 18.4.5 */
238 { BSSAP_DLINK_TNL_PLD_CTR_AND_INF, "Downlink Tunnel Payload Control and Info" }, /* 18.4.3 */
239 { BSSAP_ULINK_TNL_PLD_CTR_AND_INF, "Uplink Tunnel Payload Control and Info" }, /* 18.4.25 */
240 { BSSAP_SERVICE_AREA_ID, "Service Area Identification" }, /* 18.4.21b */
241 { BSSAP_MSI_BASED_NRI_CON, "TMSI based NRI container" }, /* 18.4.28 */
242 { 0, NULL }
244 static value_string_ext bssap_plus_ie_id_values_ext = VALUE_STRING_EXT_INIT(bssap_plus_ie_id_values);
246 /* Initialize the protocol and registered fields */
247 static int proto_bssap = -1;
248 /*static int proto_bssap_plus = -1;*/
249 static int hf_bssap_pdu_type = -1;
250 static int hf_bsap_pdu_type = -1;
251 static int hf_bssap_dlci_cc = -1;
252 static int hf_bsap_dlci_cc = -1;
253 static int hf_bssap_dlci_spare = -1;
254 static int hf_bsap_dlci_rsvd = -1;
255 static int hf_bssap_dlci_sapi = -1;
256 static int hf_bsap_dlci_sapi = -1;
257 static int hf_bssap_length = -1;
258 static int hf_bssap_plus_ie = -1;
259 static int hf_bssap_plus_ie_len = -1;
261 static int hf_bssap_plus_message_type = -1;
262 static int hf_bssap_imsi_ie = -1;
263 static int hf_bssap_imsi_det_from_gprs_serv_type_ie = -1;
264 static int hf_bssap_imsi_det_from_non_gprs_serv_type_ie = -1;
265 static int hf_bssap_info_req_ie = -1;
266 static int hf_bssap_loc_area_id_ie = -1;
267 static int hf_bssap_loc_inf_age_ie = -1;
268 static int hf_bssap_mm_information_ie = -1;
269 static int hf_bssap_mobile_id_ie = -1;
270 static int hf_bssap_mobile_stn_cls_mrk1_ie = -1;
271 static int hf_bssap_mobile_station_state_ie = -1;
272 static int hf_bssap_ptmsi_ie = -1;
273 static int hf_bssap_reject_cause_ie = -1;
274 static int hf_bssap_service_area_id_ie = -1;
275 static int hf_bssap_sgsn_nr_ie = -1;
276 static int hf_bssap_tmsi_ie = -1;
277 static int hf_bssap_tmsi_status_ie = -1;
278 static int hf_bssap_vlr_number_ie = -1;
279 static int hf_bssap_global_cn_id_ie = -1;
280 static int hf_bssap_plus_ie_data = -1;
282 static int hf_bssap_extension = -1;
283 static int hf_bssap_type_of_number = -1;
284 static int hf_bssap_numbering_plan_id = -1;
285 static int hf_bssap_sgsn_number = -1;
286 /* static int hf_bssap_vlr_number = -1; */
287 static int hf_bssap_call_priority = -1;
288 static int hf_bssap_gprs_loc_upd_type_ie = -1;
289 static int hf_bssap_Gs_cause_ie = -1;
290 static int hf_bssap_imei_ie = -1;
291 static int hf_bssap_imesiv_ie = -1;
292 static int hf_bssap_cell_global_id_ie = -1;
293 static int hf_bssap_channel_needed_ie = -1;
294 static int hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie = -1;
295 static int hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie = -1;
296 static int hf_bssap_emlpp_prio_ie = -1;
297 static int hf_bssap_gprs_erroneous_msg_ie = -1;
299 static int hf_bssap_gprs_loc_upd_type = -1;
300 static int hf_bssap_Gs_cause = -1;
301 static int hf_bssap_imei = -1;
302 static int hf_bssap_imeisv = -1;
303 static int hf_bssap_imsi = -1;
304 static int hf_bssap_imsi_det_from_gprs_serv_type = -1;
305 static int hf_bssap_info_req = -1;
306 static int hf_bssap_loc_inf_age = -1;
307 static int hf_bssap_mobile_station_state = -1;
308 static int hf_bssap_ptmsi = -1;
309 static int hf_bssap_tmsi = -1;
310 static int hf_bssap_tmsi_status = -1;
311 static int hf_bssap_tom_prot_disc = -1;
312 static int hf_bssap_e_bit = -1;
313 static int hf_bssap_tunnel_prio = -1;
314 static int hf_bssap_global_cn_id = -1;
315 static int hf_bssap_plmn_id = -1;
316 static int hf_bssap_cn_id = -1;
317 static int hf_bssap_cell_global_id = -1;
319 /* Initialize the subtree pointers */
320 static gint ett_bssap = -1;
321 static gint ett_bssap_dlci = -1;
322 static gint ett_bssap_imsi = -1;
323 static gint ett_bssap_imsi_det_from_gprs_serv_type = -1;
324 static gint ett_bssap_imsi_det_from_non_gprs_serv_type = -1;
325 static gint ett_bssap_info_req = -1;
326 static gint ett_bssap_loc_area_id = -1;
327 static gint ett_bssap_loc_inf_age = -1;
328 static gint ett_bssap_mm_information = -1;
329 static gint ett_bssap_mobile_id = -1;
330 static gint ett_bssap_sgsn_nr = -1;
331 static gint ett_bssap_tmsi = -1;
332 static gint ett_bssap_tmsi_status = -1;
333 static gint ett_bssap_vlr_number = -1;
334 static gint ett_bssap_global_cn = -1;
335 static gint ett_bssap_gprs_loc_upd = -1;
336 static gint ett_bassp_Gs_cause = -1;
337 static gint ett_bassp_imei = -1;
338 static gint ett_bassp_imesiv = -1;
339 static gint ett_bssap_cell_global_id = -1;
340 static gint ett_bssap_cgi = -1;
341 static gint ett_bssap_channel_needed = -1;
342 static gint ett_bssap_dlink_tnl_pld_cntrl_amd_inf = -1;
343 static gint ett_bssap_ulink_tnl_pld_cntrl_amd_inf = -1;
344 static gint ett_bssap_emlpp_prio = -1;
345 static gint ett_bssap_erroneous_msg = -1;
346 static gint ett_bssap_mobile_stn_cls_mrk1 = -1;
347 static gint ett_bssap_mobile_station_state = -1;
348 static gint ett_bssap_ptmsi = -1;
349 static gint ett_bssap_reject_cause = -1;
350 static gint ett_bssap_service_area_id =-1;
351 static gint ett_bssap_global_cn_id = -1;
352 static gint ett_bssap_plmn = -1;
354 static dissector_handle_t data_handle;
355 static dissector_handle_t rrlp_handle;
357 static dissector_table_t bssap_dissector_table;
358 static dissector_table_t bsap_dissector_table;
360 static dissector_handle_t bsap_dissector_handle;
363 * Keep track of pdu_type so we can call appropriate sub-dissector
365 static guint8 pdu_type = 0xFF;
367 static gint bssap_or_bsap_global = BSSAP_OR_BSAP_DEFAULT;
369 static gint gsm_or_lb_interface_global = GSM_OR_LB_INTERFACE_DEFAULT;
371 static void
372 dissect_bssap_unknown_message(tvbuff_t *message_tvb, proto_tree *bssap_tree)
374 guint32 message_length;
376 message_length = tvb_length(message_tvb);
378 proto_tree_add_text(bssap_tree, message_tvb, 0, message_length,
379 "Unknown message (%u byte%s)",
380 message_length, plurality(message_length, "", "s"));
383 static void
384 dissect_bssap_unknown_param(tvbuff_t *tvb, proto_tree *tree, guint8 type, guint16 length)
386 proto_tree_add_text(tree, tvb, 0, length,
387 "Unknown parameter 0x%x (%u byte%s)",
388 type, length, plurality(length, "", "s"));
391 static void
392 dissect_bssap_data_param(tvbuff_t *tvb, packet_info *pinfo,
393 proto_tree *bssap_tree, proto_tree *tree)
395 if ((pdu_type <= 0x01))
397 if (bssap_or_bsap_global == BSSAP)
399 /* BSSAP */
400 if((gsm_or_lb_interface_global == LB_INTERFACE) && (pdu_type == BSSAP_PDU_TYPE_BSSMAP))
402 bsap_dissector_handle = find_dissector("gsm_bssmap_le");
404 if(bsap_dissector_handle == NULL) return;
406 call_dissector(bsap_dissector_handle, tvb, pinfo, tree);
408 return;
410 else if((gsm_or_lb_interface_global == GSM_INTERFACE) && (pdu_type == BSSAP_PDU_TYPE_BSSMAP))
412 bsap_dissector_handle = find_dissector("gsm_a_bssmap");
414 if(bsap_dissector_handle == NULL) return;
416 call_dissector(bsap_dissector_handle, tvb, pinfo, tree);
418 return;
420 else
422 if (dissector_try_uint(bssap_dissector_table, pdu_type, tvb, pinfo, tree)) return;
425 else
427 /* BSAP */
428 if (dissector_try_uint(bsap_dissector_table, pdu_type, tvb, pinfo, tree))
429 return;
433 /* No sub-dissection occurred, treat it as raw data */
434 call_dissector(data_handle, tvb, pinfo, bssap_tree);
437 static void
438 dissect_bssap_dlci_param(tvbuff_t *tvb, proto_tree *tree, guint16 length)
440 proto_item *dlci_item;
441 proto_tree *dlci_tree;
442 guint8 oct;
444 dlci_item =
445 proto_tree_add_text(tree, tvb, 0, length,
446 "Data Link Connection Identifier");
448 dlci_tree = proto_item_add_subtree(dlci_item, ett_bssap_dlci);
450 oct = tvb_get_guint8(tvb, 0);
452 if (bssap_or_bsap_global == BSSAP)
454 proto_tree_add_uint(dlci_tree, hf_bssap_dlci_cc, tvb, 0, length, oct);
455 proto_tree_add_uint(dlci_tree, hf_bssap_dlci_spare, tvb, 0, length, oct);
456 proto_tree_add_uint(dlci_tree, hf_bssap_dlci_sapi, tvb, 0, length, oct);
458 else
460 proto_tree_add_uint(dlci_tree, hf_bsap_dlci_cc, tvb, 0, length, oct);
461 proto_tree_add_uint(dlci_tree, hf_bsap_dlci_rsvd, tvb, 0, length, oct);
462 proto_tree_add_uint(dlci_tree, hf_bsap_dlci_sapi, tvb, 0, length, oct);
466 static void
467 dissect_bssap_length_param(tvbuff_t *tvb, proto_tree *tree, guint16 length)
469 guint8 data_length;
471 data_length = tvb_get_guint8(tvb, 0);
472 proto_tree_add_uint(tree, hf_bssap_length, tvb, 0, length, data_length);
476 * Dissect a parameter given its type, offset into tvb, and length.
478 static guint16
479 dissect_bssap_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bssap_tree,
480 proto_tree *tree, guint8 parameter_type, gint offset,
481 guint16 parameter_length)
483 tvbuff_t *parameter_tvb;
485 parameter_tvb = tvb_new_subset(tvb, offset, parameter_length, parameter_length);
487 switch (parameter_type)
489 case PARAMETER_DLCI:
490 dissect_bssap_dlci_param(parameter_tvb, bssap_tree, parameter_length);
491 break;
493 case PARAMETER_LENGTH:
494 dissect_bssap_length_param(parameter_tvb, bssap_tree, parameter_length);
495 break;
497 case PARAMETER_DATA:
498 dissect_bssap_data_param(parameter_tvb, pinfo, bssap_tree, tree);
499 break;
501 default:
502 dissect_bssap_unknown_param(parameter_tvb, bssap_tree, parameter_type,
503 parameter_length);
504 break;
507 return(parameter_length);
510 static guint16
511 dissect_bssap_var_parameter(tvbuff_t *tvb, packet_info *pinfo,
512 proto_tree *bssap_tree, proto_tree *tree,
513 guint8 parameter_type, gint offset)
515 guint16 parameter_length;
516 guint8 length_length;
518 parameter_length = tvb_get_guint8(tvb, offset);
519 length_length = LENGTH_LENGTH;
521 offset += length_length;
523 dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree, parameter_type,
524 offset, parameter_length);
526 return(parameter_length + length_length);
529 static int
530 dissect_bssap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bssap_tree,
531 proto_tree *tree)
533 gint offset;
536 * Extract the PDU type
538 pdu_type = tvb_get_guint8(tvb, PDU_TYPE_OFFSET);
539 offset = PDU_TYPE_LENGTH;
541 if (bssap_tree)
544 * add the message type to the protocol tree
546 proto_tree_add_uint(bssap_tree,
547 (bssap_or_bsap_global == BSSAP) ? hf_bssap_pdu_type : hf_bsap_pdu_type,
548 tvb, PDU_TYPE_OFFSET, PDU_TYPE_LENGTH, pdu_type);
551 /* Starting a new message dissection */
553 switch (pdu_type)
555 case BSSAP_PDU_TYPE_BSSMAP:
556 offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
557 PARAMETER_LENGTH, offset,
558 LENGTH_LENGTH);
559 offset += dissect_bssap_var_parameter(tvb, pinfo, bssap_tree, tree,
560 PARAMETER_DATA,
561 (offset - LENGTH_LENGTH));
562 break;
564 case BSSAP_PDU_TYPE_DTAP:
565 offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
566 PARAMETER_DLCI,
567 offset, DLCI_LENGTH);
568 offset += dissect_bssap_parameter(tvb, pinfo, bssap_tree, tree,
569 PARAMETER_LENGTH, offset,
570 LENGTH_LENGTH);
571 offset += dissect_bssap_var_parameter(tvb, pinfo, bssap_tree, tree,
572 PARAMETER_DATA,
573 (offset - LENGTH_LENGTH));
574 break;
576 default:
577 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
578 val_to_str_const(pdu_type,
579 ((bssap_or_bsap_global == BSSAP) ?
580 bssap_pdu_type_acro_values : bsap_pdu_type_acro_values),
581 "Unknown"));
582 dissect_bssap_unknown_message(tvb, bssap_tree);
583 break;
585 return offset;
588 static void
589 dissect_bssap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
591 proto_item *bssap_item;
592 proto_tree *bssap_tree;
595 * Make entry in the Protocol column on summary display
597 col_set_str(pinfo->cinfo, COL_PROTOCOL, ((bssap_or_bsap_global == BSSAP) ? "BSSAP" : "BSAP"));
599 if (pinfo->sccp_info && pinfo->sccp_info->data.co.assoc )
600 pinfo->sccp_info->data.co.assoc->payload = SCCP_PLOAD_BSSAP;
603 * create the bssap protocol tree
605 bssap_item = proto_tree_add_protocol_format(tree, proto_bssap, tvb, 0, -1,
606 (bssap_or_bsap_global == BSSAP) ? "BSSAP" : "BSAP");
607 bssap_tree = proto_item_add_subtree(bssap_item, ett_bssap);
609 /* dissect the message */
611 dissect_bssap_message(tvb, pinfo, bssap_tree, tree);
616 * BSSAP+ Routines
619 #ifdef REMOVED
620 static dgt_set_t Dgt_tbcd = {
622 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
623 '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
626 #endif
628 static dgt_set_t Dgt1_9_bcd = {
630 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
631 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
634 /* Assumes the rest of the tvb contains the digits to be turned into a string
636 static const char*
637 unpack_digits(tvbuff_t *tvb, int offset, dgt_set_t *dgt, gboolean skip_first)
639 int length;
640 guint8 octet;
641 int i = 0;
642 char *digit_str;
644 length = tvb_length(tvb);
645 if (length < offset)
646 return "";
647 digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
649 while (offset < length) {
651 octet = tvb_get_guint8(tvb, offset);
652 if (!skip_first) {
653 digit_str[i] = dgt->out[octet & 0x0f];
654 i++;
656 skip_first = FALSE;
659 * unpack second value in byte
661 octet = octet >> 4;
663 if (octet == 0x0f) /* odd number bytes - hit filler */
664 break;
666 digit_str[i] = dgt->out[octet & 0x0f];
667 i++;
668 offset++;
671 digit_str[i]= '\0';
672 return digit_str;
675 static gboolean
676 check_ie(tvbuff_t *tvb, proto_tree *tree, int *offset, guint8 expected_ie)
678 guint8 ie_type;
679 guint8 ie_len;
681 ie_type = tvb_get_guint8(tvb, *offset);
682 if (ie_type != expected_ie) {
683 proto_tree_add_text(tree, tvb, *offset, 1, "Mandatory IE %s expected but IE %s Found",
684 val_to_str_ext(expected_ie, &bssap_plus_ie_id_values_ext, "Unknown %u"),
685 val_to_str_ext(ie_type, &bssap_plus_ie_id_values_ext, "Unknown %u"));
686 (*offset)++;
687 ie_len = tvb_get_guint8(tvb, *offset);
688 *offset = *offset + ie_len;
689 return FALSE;
692 return TRUE;
696 static gboolean
697 check_optional_ie(tvbuff_t *tvb, int offset, guint8 expected_ie)
699 guint8 ie_type;
701 ie_type = tvb_get_guint8(tvb, offset);
702 if (ie_type != expected_ie) {
703 return FALSE;
705 return TRUE;
709 /* 18.4.1 Cell global identity */
710 static int
711 dissect_bssap_cell_global_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
713 proto_item *item;
714 proto_tree *ie_tree;
715 proto_item *cgi_item;
716 proto_tree *cgi_tree;
717 guint8 ie_len;
719 ie_len = tvb_get_guint8(tvb, offset+1);
720 item = proto_tree_add_item(tree, hf_bssap_cell_global_id_ie, tvb, offset, ie_len+2, ENC_NA);
721 ie_tree = proto_item_add_subtree(item, ett_bssap_cell_global_id);
723 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
724 offset++;
725 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
726 offset++;
728 * The rest of the information element is coded as the the value part
729 * of the cell global id IE defined in 3GPP TS 48.018 (not including
730 * 3GPP TS 48.018 IEI and 3GPP TS 48.018 length indicator).
732 cgi_item = proto_tree_add_item(ie_tree, hf_bssap_cell_global_id, tvb, offset, ie_len, ENC_NA);
733 cgi_tree = proto_item_add_subtree(cgi_item, ett_bssap_cgi);
734 /* octets 3-8 Octets 3 to 8 contain the value part (starting with octet 2) of the
735 * Routing Area Identification IE defined in 3GPP TS 24.008, not
736 * including 3GPP TS 24.008 IEI
738 de_gmm_rai(tvb, cgi_tree, pinfo, offset, ie_len, NULL, 0);
739 /* Octets 9 and 10 contain the value part (starting with octet 2) of the
740 * Cell Identity IE defined in 3GPP TS 24.008, not including
741 * 3GPP TS 24.008 IEI
743 offset = offset + 6;
744 de_cell_id(tvb, cgi_tree, pinfo, offset, ie_len, NULL, 0);
745 offset = offset + 2;
747 return offset;
750 /* 18.4.2 Channel needed */
751 static int
752 dissect_bssap_channel_needed(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
754 proto_item *item;
755 proto_tree *ie_tree;
756 guint8 ie_len;
758 ie_len = tvb_get_guint8(tvb, offset+1);
759 item = proto_tree_add_item(tree, hf_bssap_channel_needed_ie, tvb, offset, ie_len+2, ENC_NA);
760 ie_tree = proto_item_add_subtree(item, ett_bssap_channel_needed);
762 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
763 offset++;
764 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
765 offset++;
767 * The rest of the information element is coded as the IEI part and the
768 * value part of the Channel Needed IE defined in 3GPP TS 44.018.
769 * 10.5.2.8 Channel Needed
771 de_rr_chnl_needed(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
773 return offset + ie_len;
776 /* 18.4.3 Downlink Tunnel Payload Control and Info */
777 static int
778 dissect_bssap_dlink_tunnel_payload_control_and_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
780 proto_item *item;
781 proto_tree *ie_tree;
782 tvbuff_t *next_tvb;
783 guint8 ie_len;
784 guint8 octet;
785 guint8 prot_disc;
787 ie_len = tvb_get_guint8(tvb, offset+1);
788 item = proto_tree_add_item(tree, hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie, tvb, offset, ie_len+2, ENC_NA);
789 ie_tree = proto_item_add_subtree(item, ett_bssap_dlink_tnl_pld_cntrl_amd_inf);
791 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
792 offset++;
793 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
794 offset++;
795 /* Bit 8 Spare */
796 /* Bit 7 - 4
797 * TOM Protocol Discriminator: Identifies the protocol using tunnelling of non-GSM signalling.
798 * For coding, see 3GPP TS 44.064.
801 proto_tree_add_item(ie_tree, hf_bssap_tom_prot_disc, tvb, offset, 1, ENC_BIG_ENDIAN);
802 octet = tvb_get_guint8(tvb, offset);
803 prot_disc = (octet&0x78)>>3;
805 /* octet 3 bit 3 E: Cipher Request. When set to 1 indicates that the SGSN received the payload in ciphered form,
806 * when set to 0 indicates that the SGSN did not receive the payload in ciphered form.
808 proto_tree_add_item(ie_tree, hf_bssap_e_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
810 /* octet 3 bit 2 - 1
811 * Tunnel Priority: Indicates the priority of the Tunnel Payload. For coding, see Table 20.1: Association
812 * between Tunnel Priority and LLC SAPs.
814 proto_tree_add_item(ie_tree, hf_bssap_tunnel_prio, tvb, offset, 1, ENC_BIG_ENDIAN);
815 /* Tunnel payload */
816 next_tvb = tvb_new_subset(tvb, offset, ie_len-4, ie_len-4);
818 if ((prot_disc == 2)&&(rrlp_handle))
819 call_dissector(rrlp_handle, next_tvb, pinfo, ie_tree);
820 else
821 call_dissector(data_handle, next_tvb, pinfo, ie_tree);
824 return offset + ie_len;
828 /* 18.4.4 eMLPP Priority */
829 /* Call priority */
830 static const value_string bssap_call_priority_values[] = {
831 { 0x00, "No priority applied" },
832 { 0x01, "Call priority level 4" },
833 { 0x02, "Call priority level 3" },
834 { 0x03, "Call priority level 2" },
835 { 0x04, "Call priority level 1" },
836 { 0x05, "Call priority level 0" },
837 { 0x06, "Call priority level B" },
838 { 0x07, "Call priority level A" },
839 { 0, NULL }
841 static int
842 dissect_bssap_emlpp_priority(tvbuff_t *tvb, proto_tree *tree, int offset)
844 proto_item *item;
845 proto_tree *ie_tree;
846 guint8 ie_len;
848 ie_len = tvb_get_guint8(tvb, offset+1);
849 item = proto_tree_add_item(tree, hf_bssap_emlpp_prio_ie, tvb, offset, ie_len+2, ENC_NA);
850 ie_tree = proto_item_add_subtree(item, ett_bssap_emlpp_prio);
852 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
853 offset++;
854 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
855 offset++;
856 /* The rest of the information element is coded as the value part of
857 the eMLPP-Priority IE defined in 3GPP TS 48.008 (not including
858 3GPP TS 48.008 IEI and 3GPP TS 48.008 length indicator).
859 3.2.2.56 eMLPP Priority
860 The call priority field (bit 3 to 1 of octet 2) is coded in the same way
861 as the call priority field (bit 3 to 1 of octet 5) in the Descriptive group
862 or broadcast call reference information element as defined in 3GPP TS 24.008.
864 proto_tree_add_item(ie_tree, hf_bssap_call_priority, tvb, offset, ie_len, ENC_BIG_ENDIAN);
866 return offset + ie_len;
869 /* 18.4.5 Erroneous message */
870 /* Erroneous message including the message type. */
872 static int
873 dissect_bssap_gprs_erroneous_msg(tvbuff_t *tvb, proto_tree *tree, int offset)
875 proto_item *item;
876 proto_tree *ie_tree;
877 guint8 ie_len;
879 ie_len = tvb_get_guint8(tvb, offset+1);
880 item = proto_tree_add_item(tree, hf_bssap_gprs_erroneous_msg_ie, tvb, offset, ie_len+2, ENC_NA);
881 ie_tree = proto_item_add_subtree(item, ett_bssap_erroneous_msg);
883 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
884 offset++;
885 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
886 offset++;
888 /* Erroneous message including the message type. */
889 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_NA);
891 return offset + ie_len;
896 static const value_string bssap_plus_GPRS_loc_upd_type_values[] = {
897 { 0x00, "Shall not be sent in this version of the protocol. If received, shall be treated as '00000010'." },
898 { 0x01, "IMSI attach" },
899 { 0x02, "Normal location update" },
900 { 0, NULL }
902 /* 18.4.6 GPRS location update type */
903 static int
904 dissect_bssap_gprs_location_update_type(tvbuff_t *tvb, proto_tree *tree, int offset)
906 proto_item *item;
907 proto_tree *ie_tree;
908 guint8 ie_len;
910 ie_len = tvb_get_guint8(tvb, offset+1);
911 item = proto_tree_add_item(tree, hf_bssap_gprs_loc_upd_type_ie, tvb, offset, ie_len+2, ENC_NA);
912 ie_tree = proto_item_add_subtree(item, ett_bssap_gprs_loc_upd);
914 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
915 offset++;
916 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
917 offset++;
919 /* GPRS location update type value (octet 3) */
920 proto_tree_add_item(ie_tree, hf_bssap_gprs_loc_upd_type, tvb, offset, ie_len, ENC_BIG_ENDIAN);
922 return offset + ie_len;
925 /* Gs Cause value (octet 3) */
926 static const value_string bssap_Gs_cause_values[] = {
928 { 0x00, "Normal, unspecified in this version of the protocol." },
929 { 0x01, "IMSI detached for GPRS services" },
930 { 0x02, "IMSI detached for GPRS and non-GPRS services" },
931 { 0x03, "IMSI unknown" },
932 { 0x04, "IMSI detached for non-GPRS services" },
933 { 0x05, "IMSI implicitly detached for non-GPRS services" },
934 { 0x06, "MS unreachable" },
935 { 0x07, "Message not compatible with the protocol state" },
936 { 0x08, "Missing mandatory information element" },
937 { 0x09, "Invalid mandatory information" },
938 { 0x0a, "Conditional IE error" },
939 { 0x0b, "Semantically incorrect message" },
940 { 0x0c, "Message unknown" },
941 { 0x0d, "Address error" },
942 { 0x0e, "TOM functionality not supported" },
943 { 0x0f, "Ciphering request cannot be accommodated" },
944 { 0, NULL }
947 /* 18.4.7 Gs cause */
948 static int
949 dissect_bssap_Gs_cause(tvbuff_t *tvb, proto_tree *tree, int offset)
951 proto_item *item;
952 proto_tree *ie_tree;
953 guint8 ie_len;
955 ie_len = tvb_get_guint8(tvb, offset+1);
956 item = proto_tree_add_item(tree, hf_bssap_Gs_cause_ie, tvb, offset, ie_len+2, ENC_NA);
957 ie_tree = proto_item_add_subtree(item, ett_bassp_Gs_cause);
959 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
960 offset++;
961 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
962 offset++;
963 /* Gs Cause value (octet 3) */
964 proto_tree_add_item(ie_tree, hf_bssap_Gs_cause, tvb, offset, ie_len, ENC_BIG_ENDIAN);
967 return offset + ie_len;
970 /* 18.4.8 IMEI */
971 static int
972 dissect_bssap_imei(tvbuff_t *tvb, proto_tree *tree, int offset)
974 proto_item *item;
975 proto_tree *ie_tree;
976 guint8 ie_len;
977 tvbuff_t *ie_tvb;
978 const char *digit_str;
980 ie_len = tvb_get_guint8(tvb, offset+1);
981 item = proto_tree_add_item(tree, hf_bssap_imei_ie, tvb, offset, ie_len+2, ENC_NA);
982 ie_tree = proto_item_add_subtree(item, ett_bassp_imei);
984 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
985 offset++;
986 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
987 offset++;
988 /* The IMEI is coded as a sequence of BCD digits, compressed two into each octet.
989 * The IMEI consists of 15 digits (see 3GPP TS 23.003).
991 ie_tvb = tvb_new_subset(tvb, offset, ie_len, ie_len);
992 digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, FALSE);
993 proto_tree_add_string(ie_tree, hf_bssap_imei, ie_tvb, 0, -1, digit_str);
995 return offset + ie_len;
998 /* 18.4.9 IMEISV */
999 static int
1000 dissect_bssap_imesiv(tvbuff_t *tvb, proto_tree *tree, int offset)
1002 proto_item *item;
1003 proto_tree *ie_tree;
1004 guint8 ie_len;
1005 tvbuff_t *ie_tvb;
1006 const char *digit_str;
1008 ie_len = tvb_get_guint8(tvb, offset+1);
1009 item = proto_tree_add_item(tree, hf_bssap_imesiv_ie, tvb, offset, ie_len+2, ENC_NA);
1010 ie_tree = proto_item_add_subtree(item, ett_bassp_imesiv);
1012 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1013 offset++;
1014 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1015 offset++;
1016 /* The IMEISV is coded as a sequence of BCD digits, compressed two into each octet.
1017 * The IMEISV consists of 16 digits (see 3GPP TS 23.003).
1019 ie_tvb = tvb_new_subset(tvb, offset, ie_len, ie_len);
1020 digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, FALSE);
1021 proto_tree_add_string(ie_tree, hf_bssap_imeisv, ie_tvb, 0, -1, digit_str);
1023 return offset + ie_len;
1026 /* 18.4.10 IMSI
1027 * The IMSI is coded as a sequence of BCD digits, compressed two into each octet.
1028 * This is a variable length element, and includes a length indicator.
1029 * The IMSI is defined in 3GPP TS 23.003. It shall not exceed 15 digits (see 3GPP TS 23.003).
1033 static int
1034 dissect_bssap_imsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1036 proto_item *item;
1037 proto_tree *ie_tree;
1038 guint8 ie_len;
1039 tvbuff_t *ie_tvb;
1040 const char *digit_str;
1042 ie_len = tvb_get_guint8(tvb, offset+1);
1043 item = proto_tree_add_item(tree, hf_bssap_imsi_ie, tvb, offset, ie_len+2, ENC_NA);
1044 ie_tree = proto_item_add_subtree(item, ett_bssap_imsi);
1046 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1047 offset++;
1048 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1049 offset++;
1050 ie_tvb = tvb_new_subset(tvb, offset, ie_len, ie_len);
1051 digit_str = unpack_digits(ie_tvb, 0, &Dgt1_9_bcd, TRUE);
1052 proto_tree_add_string(ie_tree, hf_bssap_imsi, ie_tvb, 0, -1, digit_str);
1054 return offset + ie_len;
1057 static const value_string bssap_imsi_det_from_gprs_serv_type_values[] _U_ = {
1058 { 0x00, "Interpreted as reserved in this version of the protocol" },
1059 { 0x01, "Network initiated IMSI detach from GPRS service" },
1060 { 0x02, "MS initiated IMSI detach from GPRS service" },
1061 { 0x03, "GPRS services not allowed" },
1062 { 0, NULL }
1065 /* 18.4.11 IMSI detach from GPRS service type */
1066 static int
1067 dissect_bssap_imsi_det_from_gprs_serv_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1069 proto_item *item;
1070 proto_tree *ie_tree;
1071 guint8 ie_len;
1073 ie_len = tvb_get_guint8(tvb, offset+1);
1074 item = proto_tree_add_item(tree, hf_bssap_imsi_det_from_gprs_serv_type_ie, tvb, offset, ie_len+2, ENC_NA);
1075 ie_tree = proto_item_add_subtree(item, ett_bssap_imsi_det_from_gprs_serv_type);
1077 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1078 offset++;
1079 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1080 offset++;
1081 /* IMSI detach from GPRS service type value (octet 3)*/
1082 proto_tree_add_item(ie_tree, hf_bssap_imsi_det_from_gprs_serv_type, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1085 return offset + ie_len;
1088 /* 18.4.12 IMSI detach from non-GPRS service type */
1089 static int
1090 dissect_bssap_imsi_det_from_non_gprs_serv_type(tvbuff_t *tvb, proto_tree *tree, int offset)
1092 proto_item *item;
1093 proto_tree *ie_tree;
1094 guint8 ie_len;
1096 ie_len = tvb_get_guint8(tvb, offset+1);
1097 item = proto_tree_add_item(tree, hf_bssap_imsi_det_from_non_gprs_serv_type_ie, tvb, offset, ie_len+2, ENC_NA);
1098 ie_tree = proto_item_add_subtree(item, ett_bssap_imsi_det_from_non_gprs_serv_type);
1100 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1101 offset++;
1102 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1103 offset++;
1104 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_NA);
1107 return offset + ie_len;
1110 static const value_string bssap_info_req_values[] = {
1111 { 0x00, "Interpreted as Not supported in this version of the protocol." },
1112 { 0x01, "PTMSI" },
1113 { 0x02, "IMEI" },
1114 { 0x03, "IMEISV" },
1115 { 0x04, "PTMSI and IMEI" },
1116 { 0x05, "PTMSI and IMEISV" },
1117 { 0x06, "IMEI and IMEISV" },
1118 { 0x07, "PTMSI, IMEI, and IMEISV" },
1119 { 0x08, "Mobile location information" },
1120 { 0x09, "TMSI" },
1121 { 0, NULL }
1123 /* 18.4.13 Information requested */
1124 static int
1125 dissect_bssap_info_req(tvbuff_t *tvb, proto_tree *tree, int offset)
1127 proto_item *item;
1128 proto_tree *ie_tree;
1129 guint8 ie_len;
1131 ie_len = tvb_get_guint8(tvb, offset+1);
1132 item = proto_tree_add_item(tree, hf_bssap_info_req_ie, tvb, offset, ie_len+2, ENC_NA);
1133 ie_tree = proto_item_add_subtree(item, ett_bssap_info_req);
1135 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1136 offset++;
1137 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1138 offset++;
1139 /*Information requested value (octet 3) */
1140 proto_tree_add_item(ie_tree, hf_bssap_info_req, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1143 return offset + ie_len;
1146 /* 18.4.14 Location area identifier */
1147 static int
1148 dissect_bssap_loc_area_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1150 proto_item *item;
1151 proto_tree *ie_tree;
1152 guint8 ie_len;
1154 ie_len = tvb_get_guint8(tvb, offset+1);
1155 item = proto_tree_add_item(tree, hf_bssap_loc_area_id_ie, tvb, offset, ie_len+2, ENC_NA);
1156 ie_tree = proto_item_add_subtree(item, ett_bssap_loc_area_id);
1158 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1159 offset++;
1160 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1161 offset++;
1162 /* The rest of the information element is coded as the value part of
1163 * the location area identifier IE defined in 3GPP TS 48.018 (not
1164 * including 3GPP TS 48.018 IEI and 3GPP TS 48.018 length
1165 * indicator).
1167 de_lai(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1169 return offset + ie_len;
1172 /* 18.4.15 Location information age */
1173 static int
1174 dissect_bssap_location_information_age(tvbuff_t *tvb, proto_tree *tree, int offset)
1176 proto_item *item;
1177 proto_tree *ie_tree;
1178 guint8 ie_len;
1180 ie_len = tvb_get_guint8(tvb, offset+1);
1181 item = proto_tree_add_item(tree, hf_bssap_loc_inf_age_ie, tvb, offset, ie_len+2, ENC_NA);
1182 ie_tree = proto_item_add_subtree(item, ett_bssap_loc_inf_age);
1184 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1185 offset++;
1186 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1187 offset++;
1188 /* The rest of the IE is coded as the value part of the
1189 * AgeOfLocationInformation as specified in 3GPP TS 29.002.:
1190 * AgeOfLocationInformation ::= INTEGER (0..32767)
1191 * -- the value represents the elapsed time in minutes since the last
1192 * -- network contact of the mobile station (i.e. the actuality of the
1193 * -- location information).
1194 * -- value '0' indicates that the MS is currently in contact with the
1195 * -- network
1196 * -- value '32767' indicates that the location information is at least
1197 * -- 32767 minutes old
1199 proto_tree_add_item(ie_tree, hf_bssap_loc_inf_age, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1202 return offset + ie_len;
1205 /* 18.4.16 MM information */
1206 static int
1207 dissect_bssap_MM_information(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1209 proto_item *item;
1210 proto_tree *ie_tree;
1211 guint8 ie_len;
1213 ie_len = tvb_get_guint8(tvb, offset+1);
1214 item = proto_tree_add_item(tree, hf_bssap_mm_information_ie, tvb, offset, ie_len+2, ENC_NA);
1215 ie_tree = proto_item_add_subtree(item, ett_bssap_mm_information);
1217 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1218 offset++;
1219 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1220 offset++;
1221 /* User information: This field is composed of one or more of the
1222 * information elements of the MM information message as defined
1223 * 3GPP TS 24.008, excluding the Protocol discriminator, Skip
1224 * indicator and Message type. This field includes the IEI and length
1225 * indicatior of the other information elements.
1227 dtap_mm_mm_info(tvb, ie_tree, pinfo, offset, ie_len);
1230 return offset + ie_len;
1233 /* 18.4.17 Mobile identity */
1234 static int
1235 dissect_bssap_mobile_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1237 proto_item *item;
1238 proto_tree *ie_tree;
1239 guint ie_len;
1241 ie_len = tvb_get_guint8(tvb, offset+1);
1242 item = proto_tree_add_item(tree, hf_bssap_mobile_id_ie, tvb, offset, ie_len+2, ENC_NA);
1243 ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_id);
1245 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1246 offset++;
1247 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1248 offset++;
1249 /* The rest of the information element is coded as the value part of
1250 * the mobile identity IE defined in 3GPP TS 24.008 (not including
1251 * 3GPP TS 24.008 IEI and 3GPP TS 24.008 length indicator).
1253 de_mid(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1256 return offset + ie_len;
1259 /* 18.4.18 Mobile station classmark 1 */
1260 static int
1261 dissect_bssap_mobile_stn_cls_mrk1(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1263 proto_item *item;
1264 proto_tree *ie_tree;
1265 guint8 ie_len;
1267 ie_len = tvb_get_guint8(tvb, offset+1);
1268 item = proto_tree_add_item(tree, hf_bssap_mobile_stn_cls_mrk1_ie, tvb, offset, ie_len+2, ENC_NA);
1269 ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_stn_cls_mrk1);
1271 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1272 offset++;
1273 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1274 offset++;
1275 /* The rest of the information element is coded as the value part of
1276 * the mobile station classmark 1 IE defined in 3GPP TS 24.008 (not
1277 * including 3GPP TS 24.008 IEI)
1279 de_ms_cm_1(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1281 return offset + ie_len;
1284 /* 18.4.19 Mobile station state */
1285 static const value_string bssap_mobile_station_state_values[] = {
1286 { 0x00, "IDLE or PMM-DETACHED" },
1287 { 0x01, "STANDBY or PMM-IDLE, 0 PDP contexts active" },
1288 { 0x02, "STANDBY or PMM-IDLE, 1 or more PDP contexts active" },
1289 { 0x03, "SUSPENDED, 0 PDP contexts active" },
1290 { 0x04, "SUSPENDED, 1 or more PDP contexts active" },
1291 { 0x05, "READY or PMM-CONNECTED, 0 PDP contexts active" },
1292 { 0x06, "READY or PMM-CONNECTED, 1 or more PDP contexts active" },
1293 { 0x07, "IMSI unknown" },
1294 { 0x08, "Information requested not supported" },
1295 { 0, NULL }
1297 static int
1298 dissect_bssap_mobile_station_state(tvbuff_t *tvb, proto_tree *tree, int offset)
1300 proto_item *item;
1301 proto_tree *ie_tree;
1302 guint8 ie_len;
1304 ie_len = tvb_get_guint8(tvb, offset+1);
1305 item = proto_tree_add_item(tree, hf_bssap_mobile_station_state_ie, tvb, offset, ie_len+2, ENC_NA);
1306 ie_tree = proto_item_add_subtree(item, ett_bssap_mobile_station_state);
1308 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1309 offset++;
1310 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1311 offset++;
1312 /* Mobile station state value (octet 3) */
1313 proto_tree_add_item(ie_tree, hf_bssap_mobile_station_state, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1315 return offset + ie_len;
1318 /* 18.4.20 PTMSI */
1319 static int
1320 dissect_bssap_ptmsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1322 proto_item *item;
1323 proto_tree *ie_tree;
1324 guint8 ie_len;
1326 ie_len = tvb_get_guint8(tvb, offset+1);
1327 item = proto_tree_add_item(tree, hf_bssap_ptmsi_ie, tvb, offset, ie_len+2, ENC_NA);
1328 ie_tree = proto_item_add_subtree(item, ett_bssap_ptmsi);
1330 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1331 offset++;
1332 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1333 offset++;
1334 /* The PTMSI consists of 4 octets. It can be coded using a full hexadecimal representation
1335 * (see 3GPP TS 23.003).
1337 proto_tree_add_item(ie_tree, hf_bssap_ptmsi, tvb, offset, ie_len, ENC_NA);
1339 return offset + ie_len;
1342 /* 18.4.21 Reject cause */
1343 static int
1344 dissect_bssap_reject_cause(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset)
1346 proto_item *item;
1347 proto_tree *ie_tree;
1348 guint8 ie_len;
1350 ie_len = tvb_get_guint8(tvb, offset+1);
1351 item = proto_tree_add_item(tree, hf_bssap_reject_cause_ie, tvb, offset, ie_len+2, ENC_NA);
1352 ie_tree = proto_item_add_subtree(item, ett_bssap_reject_cause);
1354 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1355 offset++;
1356 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1357 offset++;
1358 /* The rest of the information element is coded as the value part of
1359 * the reject cause IE defined in 3GPP TS 24.008, not including
1360 * 3GPP TS 24.008 IEI.
1362 de_rej_cause(tvb, ie_tree, pinfo, offset, ie_len, NULL, 0);
1364 return offset + ie_len;
1368 /* 18.4.21b Service Area Identification */
1369 static int
1370 dissect_bssap_service_area_id(tvbuff_t *tvb, proto_tree *tree, int offset)
1372 proto_item *item;
1373 proto_tree *ie_tree;
1374 guint8 ie_len;
1376 ie_len = tvb_get_guint8(tvb, offset+1);
1377 item = proto_tree_add_item(tree, hf_bssap_service_area_id_ie, tvb, offset, ie_len+2, ENC_NA);
1378 ie_tree = proto_item_add_subtree(item, ett_bssap_service_area_id);
1380 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1381 offset++;
1382 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1383 offset++;
1384 /* The rest of the information element is coded as the the value part
1385 * of the SAI IE defined in 3GPP TS 25.413 (not including
1386 * 3GPP TS 25.413 IEI and 3GPP TS 25.413 length indicator).
1388 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_data, tvb, offset, ie_len, ENC_NA);
1390 return offset + ie_len;
1394 /* 18.4.22 SGSN number */
1396 static const true_false_string bssap_extension_value = {
1397 "No Extension",
1398 "Extension"
1401 static int
1402 dissect_bssap_sgsn_number(tvbuff_t *tvb, proto_tree *tree, int offset)
1404 proto_item *item;
1405 proto_tree *ie_tree;
1406 guint8 ie_len;
1407 tvbuff_t *number_tvb;
1408 const char *digit_str;
1410 ie_len = tvb_get_guint8(tvb, offset+1);
1411 item = proto_tree_add_item(tree, hf_bssap_sgsn_nr_ie, tvb, offset, ie_len+2, ENC_NA);
1412 ie_tree = proto_item_add_subtree(item, ett_bssap_sgsn_nr);
1414 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1415 offset++;
1416 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1417 offset++;
1418 /* The SGSN number is coded as a sequence of TBCD digits (as specified in 3GPP TS 29.002),
1419 * compressed two into each octet. The Number is in international E.164 format as indicated by Octet 3
1420 * which coding is specified in 3GPP TS 29.002. This is a variable length information element,
1421 * and includes a length indicator. The value part of the SGSN number information element
1422 * (not including IEI, Length indicator and Octet 3) shall not exceed 15 digits.
1424 proto_tree_add_item(ie_tree, hf_bssap_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
1425 proto_tree_add_item(ie_tree, hf_bssap_type_of_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1426 proto_tree_add_item(ie_tree, hf_bssap_numbering_plan_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1427 offset++;
1428 number_tvb = tvb_new_subset(tvb, offset, ie_len-1, ie_len-1);
1429 digit_str = unpack_digits(number_tvb, 0, &Dgt1_9_bcd, FALSE);
1430 proto_tree_add_string(ie_tree, hf_bssap_sgsn_number, number_tvb, 0, -1, digit_str);
1433 return offset + ie_len-1;
1436 /* 18.4.23 TMSI */
1437 static int
1438 dissect_bssap_tmsi(tvbuff_t *tvb, proto_tree *tree, int offset)
1440 proto_item *item;
1441 proto_tree *ie_tree;
1442 guint8 ie_len;
1444 ie_len = tvb_get_guint8(tvb, offset+1);
1445 item = proto_tree_add_item(tree, hf_bssap_tmsi_ie, tvb, offset, ie_len+2, ENC_NA);
1446 ie_tree = proto_item_add_subtree(item, ett_bssap_tmsi);
1448 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1449 offset++;
1450 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1451 offset++;
1452 /* The TMSI consists of 4 octets. It can be coded using a full hexadecimal representation
1453 * (see 3GPP TS 23.003).
1455 proto_tree_add_item(ie_tree, hf_bssap_tmsi, tvb, offset, ie_len, ENC_NA);
1458 return offset + ie_len;
1462 /* 18.4.24 TMSI status */
1463 static const true_false_string bssap_tmsi_flag = {
1464 "Valid TMSI available",
1465 "No valid TMSI available"
1467 static int
1468 dissect_bssap_tmsi_status(tvbuff_t *tvb, proto_tree *tree, int offset)
1470 proto_item *item;
1471 proto_tree *ie_tree;
1472 guint8 ie_len;
1474 ie_len = tvb_get_guint8(tvb, offset+1);
1475 item = proto_tree_add_item(tree, hf_bssap_tmsi_status_ie, tvb, offset, ie_len+2, ENC_NA);
1476 ie_tree = proto_item_add_subtree(item, ett_bssap_tmsi_status);
1478 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1479 offset++;
1480 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1481 offset++;
1482 /* TMSI flag (octet 3) */
1483 proto_tree_add_item(ie_tree, hf_bssap_tmsi_status, tvb, offset, ie_len, ENC_BIG_ENDIAN);
1486 return offset + ie_len;
1489 /* 18.4.25 Uplink Tunnel Payload Control and Info */
1490 static const true_false_string bssap_E_flag = {
1491 "SGSN received the payload in ciphered",
1492 "SGSN did not receive the payload in ciphered form"
1494 /* 3GPP TS 44.064 B.1.1 TOM Protocol Discriminator */
1495 static const value_string bssap_tom_prot_disc_values[] = {
1496 { 0x00, "Not specified" },
1497 { 0x01, "TIA/EIA-136" },
1498 { 0x02, "RRLP" },
1499 { 0x03, "Reserved for extension" },
1500 { 0, NULL }
1502 static int
1503 dissect_bssap_ulink_tunnel_payload_control_and_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1505 proto_item *item;
1506 proto_tree *ie_tree;
1507 tvbuff_t *next_tvb;
1508 guint8 ie_len;
1509 guint8 octet;
1510 guint8 prot_disc;
1512 ie_len = tvb_get_guint8(tvb, offset+1);
1513 item = proto_tree_add_item(tree, hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie, tvb, offset, ie_len+2, ENC_NA);
1514 ie_tree = proto_item_add_subtree(item, ett_bssap_ulink_tnl_pld_cntrl_amd_inf);
1516 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1517 offset++;
1518 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1519 offset++;
1520 /* octet 3 bit 8 Spare */
1521 /* octet 3 bit 7 - 4
1522 * TOM Protocol Discriminator: Identifies the protocol using tunnelling of non-GSM signalling.
1523 * For coding, see 3GPP TS 44.064.
1525 proto_tree_add_item(ie_tree, hf_bssap_tom_prot_disc, tvb, offset, 1, ENC_BIG_ENDIAN);
1526 octet = tvb_get_guint8(tvb, offset);
1527 prot_disc = (octet&0x78)>>3;
1529 /* octet 3 bit 3 E: Cipher Request. When set to 1 indicates that the SGSN received the payload in ciphered form,
1530 * when set to 0 indicates that the SGSN did not receive the payload in ciphered form.
1532 proto_tree_add_item(ie_tree, hf_bssap_e_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
1534 /* octet 3 bit 2 - 1
1535 * Tunnel Priority: Indicates the priority of the Tunnel Payload. For coding, see Table 20.1: Association
1536 * between Tunnel Priority and LLC SAPs.
1538 proto_tree_add_item(ie_tree, hf_bssap_tunnel_prio, tvb, offset, 1, ENC_BIG_ENDIAN);
1539 /* Tunnel payload */
1540 next_tvb = tvb_new_subset(tvb, offset, ie_len - 4, ie_len - 4);
1542 if ((prot_disc == 2)&&(rrlp_handle))
1543 call_dissector(rrlp_handle, next_tvb, pinfo, ie_tree);
1544 else
1545 call_dissector(data_handle, next_tvb, pinfo, ie_tree);
1547 return offset + ie_len;
1551 /* 18.4.26 VLR number */
1552 static int
1553 dissect_bssap_vlr_number(tvbuff_t *tvb, proto_tree *tree, int offset)
1555 proto_item *item;
1556 proto_tree *ie_tree;
1557 guint8 ie_len;
1558 tvbuff_t *number_tvb;
1559 const char *digit_str;
1561 ie_len = tvb_get_guint8(tvb, offset+1);
1562 item = proto_tree_add_item(tree, hf_bssap_vlr_number_ie, tvb, offset, ie_len+2, ENC_NA);
1563 ie_tree = proto_item_add_subtree(item, ett_bssap_vlr_number);
1565 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1566 offset++;
1567 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1568 offset++;
1569 /* The VLR number is coded as a sequence of TBCD digits (as specified in 3GPP TS 29.002),
1570 * compressed two into each octet. The Number is in international E.164 format as indicated by Octet 3
1571 * which coding is specified in 3GPP TS 29.002. This is a variable length information element,
1572 * and includes a length indicator. The value part of the VLR number information element
1573 * (not including IEI, length indicator and Octet 3), shall not exceed 15 digits.
1576 proto_tree_add_item(ie_tree, hf_bssap_extension, tvb, offset, 1, ENC_BIG_ENDIAN);
1577 proto_tree_add_item(ie_tree, hf_bssap_type_of_number, tvb, offset, 1, ENC_BIG_ENDIAN);
1578 proto_tree_add_item(ie_tree, hf_bssap_numbering_plan_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1579 offset++;
1580 number_tvb = tvb_new_subset(tvb, offset, ie_len - 1, ie_len - 1);
1581 digit_str = unpack_digits(number_tvb, 0, &Dgt1_9_bcd, FALSE);
1582 proto_tree_add_string(ie_tree, hf_bssap_sgsn_number, number_tvb, 0, -1, digit_str);
1584 return offset + ie_len - 1;
1587 /* 18.4.27 Global CN-Id */
1588 static int
1589 dissect_bssap_global_cn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1591 proto_item *item;
1592 proto_tree *ie_tree;
1593 proto_item *plmn_item;
1594 proto_tree *plmn_tree;
1595 proto_item *global_cn_id_item;
1596 proto_tree *global_cn_id_tree;
1597 guint8 ie_len;
1599 ie_len = tvb_get_guint8(tvb, offset+1);
1600 item = proto_tree_add_item(tree, hf_bssap_global_cn_id_ie, tvb, offset, ie_len+2, ENC_NA);
1601 ie_tree = proto_item_add_subtree(item, ett_bssap_global_cn);
1603 proto_tree_add_item(ie_tree, hf_bssap_plus_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
1604 offset++;
1605 proto_tree_add_item(ie_tree, hf_bssap_plus_ie_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1606 offset++;
1607 /* The Global CN-Id consists of a PLMN-Id and a CN-Id, see 3GPP TS 23.003.
1608 * The PLMN-Id consists of MCC and MNC coded according to Location Area Identification
1609 * in 3GPP TS 24.008. The CN-Id is an integer defined by O&M.
1610 * The least significant bit of the CN-Id field is bit 1 of octet 7 and
1611 * the most significant bit is bit 8 of octet 6. If the CN-Id does not fill the field reserved for it,
1612 * the rest of the bits are set to '0'.
1614 global_cn_id_item = proto_tree_add_item(ie_tree, hf_bssap_global_cn_id, tvb, offset, ie_len, ENC_NA);
1615 global_cn_id_tree = proto_item_add_subtree(global_cn_id_item, ett_bssap_global_cn_id);
1616 /* Octet 3 - 5 PLMN-Id Coded as octets 2 to 4 of the Location Area Identification IE,
1617 * defined in 3GPP TS 24.008 (not including 3GPP TS 24.008 IEI and LAC).
1619 plmn_item = proto_tree_add_item(global_cn_id_tree, hf_bssap_plmn_id, tvb, offset, 3, ENC_NA);
1620 plmn_tree = proto_item_add_subtree(plmn_item, ett_bssap_plmn);
1621 dissect_e212_mcc_mnc(tvb, pinfo, plmn_tree, offset, TRUE);
1622 offset = offset + 3;
1624 /* Octet 6 - 7 CN-Id (INTEGER 0..4095) */
1625 proto_tree_add_item(global_cn_id_tree, hf_bssap_cn_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1626 offset = offset+2;
1628 return offset;
1632 static void dissect_bssap_plus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1634 proto_item *bssap_item;
1635 proto_tree *bssap_tree;
1636 guint8 message_type;
1637 int offset = 0;
1640 * Make entry in the Protocol column on summary display
1642 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSAP+");
1644 if (pinfo->sccp_info && pinfo->sccp_info->data.co.assoc)
1645 pinfo->sccp_info->data.co.assoc->payload = SCCP_PLOAD_BSSAP;
1647 /* create the BSSAP+ protocol tree */
1648 bssap_item = proto_tree_add_item(tree, proto_bssap, tvb, 0, -1, ENC_NA);
1649 bssap_tree = proto_item_add_subtree(bssap_item, ett_bssap);
1651 message_type = tvb_get_guint8(tvb, offset);
1652 proto_tree_add_item(bssap_tree, hf_bssap_plus_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1653 offset++;
1655 col_add_str(pinfo->cinfo, COL_INFO, val_to_str_ext(message_type, &bssap_plus_message_type_values_ext, "Unknown %u"));
1657 switch (message_type) {
1658 case BSSAP_PAGING_REQUEST:
1659 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1660 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1661 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1663 /* VLR number VLR number 18.4.26 M TLV 5-11 */
1664 if (check_ie(tvb, tree, &offset, BSSAP_VLR_NUMBER))
1665 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1667 /* End of mandatory elements */
1668 if (tvb_length_remaining(tvb, offset) <= 0)
1669 return;
1671 /* TMSI TMSI 18.4.23 O TLV 6 */
1672 if (check_optional_ie(tvb, offset, BSSAP_TMSI))
1673 offset = dissect_bssap_tmsi(tvb, bssap_tree, offset);
1674 if (tvb_length_remaining(tvb, offset) <= 0)
1675 return;
1677 /* Location area identifier Location area identifier 18.4.14 O TLV 7 */
1678 if (check_optional_ie(tvb, offset, BSSAP_LOC_AREA_ID))
1679 offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1680 if (tvb_length_remaining(tvb, offset) <= 0)
1681 return;
1683 /* Channel needed Channel needed 18.4.2 O TLV 3 */
1684 if (check_optional_ie(tvb, offset, BSSAP_CHANNEL_NEEDED))
1685 offset = dissect_bssap_channel_needed(tvb, bssap_tree, pinfo, offset);
1686 if (tvb_length_remaining(tvb, offset) <= 0)
1687 return;
1689 /* eMLPP Priority eMLPP Priority 18.4.4 O TLV 3 */
1690 if (check_optional_ie(tvb, offset, BSSAP_EMLPP_PRIORITY))
1691 offset = dissect_bssap_emlpp_priority(tvb, bssap_tree, offset);
1692 if (tvb_length_remaining(tvb, offset) <= 0)
1693 return;
1695 /* Global CN-Id Global CN-Id 18.4.27 O TLV 7 */
1696 if (check_optional_ie(tvb, offset, BSSAP_GLOBAL_CN_ID))
1697 offset = dissect_bssap_global_cn_id(tvb, pinfo, bssap_tree, offset);
1698 if (tvb_length_remaining(tvb, offset) <= 0)
1699 return;
1701 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1702 break;
1703 case BSSAP_PAGING_REJECT: /* 17.1.18 */
1704 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1705 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1706 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1707 /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
1708 if (check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
1709 offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
1711 if (tvb_length_remaining(tvb, offset) <= 0)
1712 return;
1713 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1714 break;
1715 case BSSAP_DOWNLINK_TUNNEL_REQUEST: /* 17.1.4 */
1716 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1717 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1718 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1720 /* VLR number VLR number 18.4.26 M TLV 5-11 */
1721 if (check_ie(tvb, tree, &offset, BSSAP_VLR_NUMBER))
1722 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1724 /* Downlink Tunnel Payload Control and Info 18.4.3 M TLV 3-223 */
1725 if (check_ie(tvb, tree, &offset, BSSAP_DLINK_TNL_PLD_CTR_AND_INF))
1726 offset = dissect_bssap_dlink_tunnel_payload_control_and_info(tvb, pinfo, bssap_tree, offset);
1728 if (tvb_length_remaining(tvb, offset) <= 0)
1729 return;
1730 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1731 break;
1732 case BSSAP_UPLINK_TUNNEL_REQUEST: /* 17.1.23 */
1733 /* SGSN number 18.4.22 M TLV 5-11 */
1734 if (check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1735 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1737 /* Uplink Tunnel Payload Control and Info 18.4.25 M TLV 3-223 */
1738 if (check_ie(tvb, tree, &offset, BSSAP_ULINK_TNL_PLD_CTR_AND_INF))
1739 offset = dissect_bssap_ulink_tunnel_payload_control_and_info(tvb, pinfo, bssap_tree, offset);
1741 if (tvb_length_remaining(tvb, offset) <= 0)
1742 return;
1743 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1744 break;
1745 case BSSAP_LOCATION_UPDATE_REQUEST: /* 17.1.11 BSSAP+-LOCATION-UPDATE-REQUEST */
1746 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1747 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1748 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1750 /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1751 if (check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1752 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1754 /* Update type GPRS location update type 18.4.6 M TLV 3 */
1755 if (check_ie(tvb, tree, &offset, BSSAP_GPRS_LOC_UPD_TYPE))
1756 offset = dissect_bssap_gprs_location_update_type(tvb, bssap_tree, offset);
1758 /* New Cell global identity Cell global identity 18.4.1 M TLV 10 */
1759 if (check_ie(tvb, tree, &offset, BSSAP_CELL_GBL_ID))
1760 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1762 /* Mobile station classmark Mobile station classmark 1 18.4.18 M TLV 3 */
1763 if (check_ie(tvb, tree, &offset, BSSAP_MOBILE_STN_CLS_MRK1))
1764 offset = dissect_bssap_mobile_stn_cls_mrk1(tvb, bssap_tree, pinfo, offset);
1765 if (tvb_length_remaining(tvb, offset) <= 0)
1766 return;
1768 /* Old location area identifier Location area identifier 18.4.14 O TLV 7 */
1769 if (check_optional_ie(tvb, offset, BSSAP_LOC_AREA_ID))
1770 offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1771 if (tvb_length_remaining(tvb, offset) <= 0)
1772 return;
1774 /* TMSI status TMSI status 18.4.24 O TLV 3 */
1775 if (check_optional_ie(tvb, offset, BSSAP_TMSI_STATUS))
1776 offset = dissect_bssap_tmsi_status(tvb, bssap_tree, offset);
1777 if (tvb_length_remaining(tvb, offset) <= 0)
1778 return;
1780 /* New service area identification Service area identification 18.4.21b O TLV 9 */
1781 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1782 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1783 if (tvb_length_remaining(tvb, offset) <= 0)
1784 return;
1786 /* IMEISV IMEISV 18.4.9 O TLV 10 */
1787 if (check_optional_ie(tvb, offset, BSSAP_IMEISV))
1788 offset = dissect_bssap_imesiv(tvb, bssap_tree, offset);
1789 if (tvb_length_remaining(tvb, offset) <= 0)
1790 return;
1791 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1792 break;
1793 case BSSAP_LOCATION_UPDATE_ACCEPT: /* 17.1.9 */
1794 /* IMSI 18.4.10 M TLV 6-10 */
1795 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1796 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1798 /* Location area identifier Location area identifier 18.4.14 M TLV 7 */
1799 if (check_ie(tvb, tree, &offset, BSSAP_LOC_AREA_ID))
1800 offset = dissect_bssap_loc_area_id(tvb, bssap_tree, pinfo, offset);
1802 if (tvb_length_remaining(tvb, offset) <= 0)
1803 return;
1805 /* New TMSI, or IMSI Mobile identity 18.4.17 O TLV 6-10 */
1806 if (check_optional_ie(tvb, offset, BSSAP_MOBILE_ID))
1807 offset = dissect_bssap_mobile_id(tvb, bssap_tree, pinfo, offset);
1808 if (tvb_length_remaining(tvb, offset) <= 0)
1809 return;
1810 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1811 break;
1812 case BSSAP_LOCATION_UPDATE_REJECT: /* 17.1.10 */
1813 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1814 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1815 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1816 /* Reject cause Reject cause 18.4.21 M TLV 3 */
1817 if (check_ie(tvb, tree, &offset, BSSAP_REJECT_CAUSE))
1818 offset = dissect_bssap_reject_cause(tvb, bssap_tree, pinfo, offset);
1819 if (tvb_length_remaining(tvb, offset) <= 0)
1820 return;
1821 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1822 break;
1823 case BSSAP_TMSI_REALLOCATION_COMPLETE: /* 17.1.22 */
1824 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1825 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1826 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1828 if (tvb_length_remaining(tvb, offset) <= 0)
1829 return;
1831 /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1832 if (check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1833 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1835 if (tvb_length_remaining(tvb, offset) <= 0)
1836 return;
1838 /* Service area identification Service area identification 18.4.21b O TLV 9 */
1839 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1840 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1841 if (tvb_length_remaining(tvb, offset) <= 0)
1842 return;
1843 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1844 break;
1845 case BSSAP_ALERT_REQUEST: /* 17.1.3 */
1846 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1847 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1848 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1850 if (tvb_length_remaining(tvb, offset) <= 0)
1851 return;
1852 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1853 break;
1854 case BSSAP_ALERT_ACK: /* 17.1.1 */
1855 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1856 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1857 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1859 if (tvb_length_remaining(tvb, offset) <= 0)
1860 return;
1861 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1862 break;
1863 case BSSAP_ALERT_REJECT: /* 17.1.2 */
1864 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1865 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1866 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1868 /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
1869 if (check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
1870 offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
1872 if (tvb_length_remaining(tvb, offset) <= 0)
1873 return;
1874 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1875 break;
1876 case BSSAP_MS_ACTIVITY_INDICATION: /* 17.1.14 */
1877 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1878 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1879 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1881 if (tvb_length_remaining(tvb, offset) <= 0)
1882 return;
1884 /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1885 if (check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1886 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1888 if (tvb_length_remaining(tvb, offset) <= 0)
1889 return;
1891 /* Service area identification Service area identification 18.4.21b O TLV 9 */
1892 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1893 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1894 if (tvb_length_remaining(tvb, offset) <= 0)
1895 return;
1896 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1897 break;
1898 case BSSAP_GPRS_DETACH_INDICATION: /* 17.1.6 */
1899 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1900 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1901 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1903 /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1904 if (check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1905 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1907 /* IMSI detach from GPRS service type IMSI detach from GPRS service type 18.4.17 M TLV 3 */
1908 if (check_ie(tvb, tree, &offset, BSSAP_IMSI_DET_FROM_GPRS_SERV_TYPE))
1909 offset = dissect_bssap_imsi_det_from_gprs_serv_type(tvb, bssap_tree, offset);
1911 if (tvb_length_remaining(tvb, offset) <= 0)
1912 return;
1914 /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1915 if (check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1916 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1918 if (tvb_length_remaining(tvb, offset) <= 0)
1919 return;
1921 /* Service area identification Service area identification 18.4.21b O TLV 9 */
1922 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1923 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1924 if (tvb_length_remaining(tvb, offset) <= 0)
1925 return;
1926 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1927 break;
1928 case BSSAP_GPRS_DETACH_ACK: /* 17.1.5 */
1929 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1930 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1931 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1933 if (tvb_length_remaining(tvb, offset) <= 0)
1934 return;
1935 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1936 break;
1937 case BSSAP_IMSI_DETACH_INDICATION: /* 17.1.8 */
1938 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1939 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1940 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1942 /* SGSN number SGSN number 18.4.22 M TLV 5-11 */
1943 if (check_ie(tvb, tree, &offset, BSSAP_SGSN_NUMBER))
1944 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1946 /* Detach type IMSI detach from non-GPRS service type 18.4.11 M TLV 3 */
1947 if (check_ie(tvb, tree, &offset, BSSAP_IMSI_DET_FROM_NON_GPRS_SERV_TYPE))
1948 offset = dissect_bssap_imsi_det_from_non_gprs_serv_type(tvb, bssap_tree, offset);
1950 if (tvb_length_remaining(tvb, offset) <= 0)
1951 return;
1953 /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
1954 if (check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
1955 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
1957 if (tvb_length_remaining(tvb, offset) <= 0)
1958 return;
1960 /* Location information age Location information age 18.4.14 O TLV 4 */
1961 if (check_optional_ie(tvb, offset, BSSAP_LOC_INF_AGE))
1962 offset = dissect_bssap_location_information_age(tvb, bssap_tree, offset);
1964 if (tvb_length_remaining(tvb, offset) <= 0)
1965 return;
1967 /* Service area identification Service area identification 18.4.21b O TLV 9 */
1968 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
1969 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
1970 if (tvb_length_remaining(tvb, offset) <= 0)
1971 return;
1972 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1973 break;
1974 case BSSAP_IMSI_DETACH_ACK: /* 17.1.7 */
1975 /* IMSI IMSI 18.4.10 M TLV 6-10 */
1976 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
1977 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
1979 if (tvb_length_remaining(tvb, offset) <= 0)
1980 return;
1981 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1982 break;
1983 case BSSAP_RESET_INDICATION: /* 17.1.21 */
1984 /* Conditional IE:s */
1985 /* SGSN number SGSN number 18.4.22 C TLV 5-11 */
1986 if (check_optional_ie(tvb, offset, BSSAP_SGSN_NUMBER)) {
1987 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
1988 if (tvb_length_remaining(tvb, offset) <= 0)
1989 return;
1990 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
1991 }else{
1992 /* VLR number VLR number 18.4.26 C TLV 5-11 */
1993 if (check_optional_ie(tvb, offset, BSSAP_VLR_NUMBER)) {
1994 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
1995 if (tvb_length_remaining(tvb, offset) <= 0)
1996 return;
1997 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2000 proto_tree_add_text(tree, tvb, offset, -1, "Conditional IE");
2001 break;
2002 case BSSAP_RESET_ACK: /* 17.1.20 */
2003 /* Conditional IE:s */
2004 /* SGSN number SGSN number 18.4.22 C TLV 5-11 */
2005 if (check_optional_ie(tvb, offset, BSSAP_SGSN_NUMBER)) {
2006 offset = dissect_bssap_sgsn_number(tvb, bssap_tree, offset);
2007 if (tvb_length_remaining(tvb, offset) <= 0)
2008 return;
2009 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2010 }else{
2011 /* VLR number VLR number 18.4.26 C TLV 5-11 */
2012 if (check_optional_ie(tvb, offset, BSSAP_VLR_NUMBER)) {
2013 offset = dissect_bssap_vlr_number(tvb, bssap_tree, offset);
2014 if (tvb_length_remaining(tvb, offset) <= 0)
2015 return;
2016 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2019 proto_tree_add_text(tree, tvb, offset, -1, "Conditional IE");
2020 break;
2021 case BSSAP_MS_INFORMATION_REQUEST: /* 17.1.15 */
2022 /* IMSI IMSI 18.4.10 M TLV 6-10 */
2023 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
2024 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2026 /* Information requested Information requested 18.4.13 M TLV 3 */
2027 if (check_ie(tvb, tree, &offset, BSSAP_INFO_REQ))
2028 offset = dissect_bssap_info_req(tvb, bssap_tree, offset);
2030 if (tvb_length_remaining(tvb, offset) <= 0)
2031 return;
2033 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2034 break;
2035 case BSSAP_MS_INFORMATION_RESPONSE: /* 17.1.16 */
2036 /* IMSI IMSI 18.4.10 M TLV 6-10 */
2037 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
2038 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2039 if (tvb_length_remaining(tvb, offset) <= 0)
2040 return;
2042 /* TMSI TMSI 18.4.23 O TLV 6 */
2043 if (check_optional_ie(tvb, offset, BSSAP_TMSI))
2044 offset = dissect_bssap_tmsi(tvb, bssap_tree, offset);
2045 if (tvb_length_remaining(tvb, offset) <= 0)
2046 return;
2048 /* PTMSI PTMSI 18.4.20 O TLV 6 BSSAP_PTMSI*/
2049 if (check_optional_ie(tvb, offset, BSSAP_PTMSI))
2050 offset = dissect_bssap_ptmsi(tvb, bssap_tree, offset);
2051 if (tvb_length_remaining(tvb, offset) <= 0)
2052 return;
2054 /* IMEI IMEI 18.4.8 O TLV 10 */
2055 if (check_optional_ie(tvb, offset, BSSAP_IMEI))
2056 offset = dissect_bssap_imei(tvb, bssap_tree, offset);
2057 if (tvb_length_remaining(tvb, offset) <= 0)
2058 return;
2059 /* IMEISV IMEISV 18.4.9 O TLV 10 BSSAP_IMEISV*/
2060 if (check_optional_ie(tvb, offset, BSSAP_IMEISV))
2061 offset = dissect_bssap_imesiv(tvb, bssap_tree, offset);
2062 if (tvb_length_remaining(tvb, offset) <= 0)
2063 return;
2065 /* Cell global identity Cell global identity 18.4.1 O TLV 10 */
2066 if (check_optional_ie(tvb, offset, BSSAP_CELL_GBL_ID))
2067 offset = dissect_bssap_cell_global_id(tvb, bssap_tree, pinfo, offset);
2069 if (tvb_length_remaining(tvb, offset) <= 0)
2070 return;
2071 /* Location information age Location information age 18.4.15 O TLV 4 */
2072 if (check_optional_ie(tvb, offset, BSSAP_LOC_INF_AGE))
2073 offset = dissect_bssap_location_information_age(tvb, bssap_tree, offset);
2075 if (tvb_length_remaining(tvb, offset) <= 0)
2076 return;
2078 /* Mobile station state Mobile station state 18.4.19 O TLV 3 */
2079 if (check_optional_ie(tvb, offset, BSSAP_MOBILE_STN_STATE))
2080 offset = dissect_bssap_mobile_station_state(tvb, bssap_tree, offset);
2082 if (tvb_length_remaining(tvb, offset) <= 0)
2083 return;
2085 /* Service area identification Service area identification 18.4.21b O TLV 9 */
2086 if (check_optional_ie(tvb, offset, BSSAP_SERVICE_AREA_ID))
2087 offset = dissect_bssap_service_area_id(tvb, bssap_tree, offset);
2088 if (tvb_length_remaining(tvb, offset) <= 0)
2089 return;
2090 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2091 break;
2092 case BSSAP_MM_INFORMATION_REQUEST: /* 17.1.12 */
2093 /* IMSI IMSI 18.4.10 M TLV 6-10 */
2094 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
2095 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2097 if (tvb_length_remaining(tvb, offset) <= 0)
2098 return;
2099 /* MM information MM information 18.4.16 O TLV 3-n */
2100 if (check_optional_ie(tvb, offset, BSSAP_MM_INFORMATION))
2101 offset = dissect_bssap_MM_information(tvb, bssap_tree, pinfo, offset);
2102 if (tvb_length_remaining(tvb, offset) <= 0)
2103 return;
2104 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2105 break;
2106 case BSSAP_MOBILE_STATUS: /* 17.1.13 */
2107 /* IMSI IMSI 18.4.10 O TLV 6-10 */
2108 if (check_optional_ie(tvb, offset, BSSAP_IMSI))
2109 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2110 /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
2111 if (check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
2112 offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
2114 /* Erroneous message Erroneous message 18.4.5 M TLV 3-n BSSAP_ERRONEOUS_MSG*/
2115 if (check_ie(tvb, tree, &offset, BSSAP_ERRONEOUS_MSG))
2116 offset = dissect_bssap_gprs_erroneous_msg(tvb, bssap_tree, offset);
2118 if (tvb_length_remaining(tvb, offset) <= 0)
2119 return;
2120 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2121 break;
2122 case BSSAP_MS_UNREACHABLE: /* 17.1.17 */
2123 /* IMSI IMSI 18.4.10 M TLV 6-10 */
2124 if (check_ie(tvb, tree, &offset, BSSAP_IMSI))
2125 offset = dissect_bssap_imsi(tvb, bssap_tree, offset);
2127 /* Gs Cause Gs Cause 18.4.7 M TLV 3 */
2128 if (check_ie(tvb, tree, &offset, BSSAP_GS_CAUSE))
2129 offset = dissect_bssap_Gs_cause(tvb, bssap_tree, offset);
2131 if (tvb_length_remaining(tvb, offset) <= 0)
2132 return;
2133 proto_tree_add_text(tree, tvb, offset, -1, "Extraneous data");
2134 break;
2135 default:
2136 break;
2140 static gboolean
2141 dissect_bssap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2143 /* Is it a BSSAP/BSAP packet?
2144 * If octet_1 == 0x00 and octet_2 == length(tvb) - 2
2145 * or if octet_1 == 0x01 and octet_3 == length(tvb) - 3
2146 * then we'll assume it is a bssap packet
2147 * If octet_1 == 0x00 a further check is done
2148 * to differentiate a BSSMAP BLOCK message from a
2149 * RANAP DirectTransfer (under certain conditions)
2151 switch (tvb_get_guint8(tvb, 0))
2153 case 0x00:
2154 if (tvb_get_guint8(tvb, 1) != (tvb_length(tvb) - 2)) {
2155 return(FALSE);
2157 if (tvb_get_guint8(tvb, 2) == 0x40 && tvb_get_guint8(tvb, 3) != 0x01) {
2158 return(FALSE);
2160 break;
2162 case 0x01:
2163 if (tvb_get_guint8(tvb, 2) != (tvb_length(tvb) - 3)) {
2164 return(FALSE);
2166 break;
2168 default:
2169 return(FALSE);
2172 dissect_bssap(tvb, pinfo, tree);
2174 return(TRUE);
2177 /* Register the protocol with Wireshark */
2178 void
2179 proto_register_bssap(void)
2181 module_t *bssap_module;
2183 /* Setup list of header fields */
2184 static hf_register_info hf[] = {
2185 { &hf_bssap_pdu_type,
2186 { "Message Type", "bssap.pdu_type",
2187 FT_UINT8, BASE_HEX, VALS(bssap_pdu_type_values), 0x0,
2188 NULL, HFILL}},
2190 { &hf_bsap_pdu_type,
2191 { "Message Type", "bsap.pdu_type",
2192 FT_UINT8, BASE_HEX, VALS(bsap_pdu_type_values), 0x0,
2193 NULL, HFILL}},
2195 { &hf_bssap_dlci_cc,
2196 { "Control Channel", "bssap.dlci.cc",
2197 FT_UINT8, BASE_HEX, VALS(bssap_cc_values), CC_MASK,
2198 NULL, HFILL}},
2200 { &hf_bsap_dlci_cc,
2201 { "Control Channel", "bsap.dlci.cc",
2202 FT_UINT8, BASE_HEX, VALS(bsap_cc_values), CC_MASK,
2203 NULL, HFILL}},
2205 { &hf_bssap_dlci_spare,
2206 { "Spare", "bssap.dlci.spare",
2207 FT_UINT8, BASE_HEX, NULL, SPARE_MASK,
2208 NULL, HFILL}},
2210 { &hf_bsap_dlci_rsvd,
2211 { "Reserved", "bsap.dlci.rsvd",
2212 FT_UINT8, BASE_HEX, NULL, SPARE_MASK,
2213 NULL, HFILL}},
2215 { &hf_bssap_dlci_sapi,
2216 { "SAPI", "bssap.dlci.sapi",
2217 FT_UINT8, BASE_HEX, VALS(bssap_sapi_values), SAPI_MASK,
2218 NULL, HFILL}},
2220 { &hf_bsap_dlci_sapi,
2221 { "SAPI", "bsap.dlci.sapi",
2222 FT_UINT8, BASE_HEX, VALS(bsap_sapi_values), SAPI_MASK,
2223 NULL, HFILL}},
2225 { &hf_bssap_length,
2226 { "Length", "bssap.length",
2227 FT_UINT8, BASE_DEC, NULL, 0x0,
2228 NULL, HFILL}},
2231 { &hf_bssap_plus_message_type,
2232 { "Message Type", "bssap_plus.msg_type",
2233 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &bssap_plus_message_type_values_ext, 0x0,
2234 NULL, HFILL}},
2236 { &hf_bssap_plus_ie,
2237 { "IEI", "bssap_plus.iei",
2238 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &bssap_plus_ie_id_values_ext, 0x0,
2239 NULL, HFILL}},
2241 { &hf_bssap_plus_ie_len,
2242 { "Length indicator", "bssap_plus.ie_len",
2243 FT_UINT8, BASE_DEC, NULL, 0x0,
2244 NULL, HFILL}},
2246 { &hf_bssap_extension,
2247 { "Extension", "bssap.extension",
2248 FT_BOOLEAN, 8, TFS(&bssap_extension_value), 0x80,
2249 NULL, HFILL }},
2251 { &hf_bssap_type_of_number,
2252 { "Type of number", "bssap.type_of_number",
2253 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_type_of_number_values), 0x70,
2254 NULL, HFILL }},
2256 { &hf_bssap_numbering_plan_id,
2257 { "Numbering plan identification", "bssap.number_plan",
2258 FT_UINT8, BASE_HEX, VALS(gsm_a_dtap_numbering_plan_id_values), 0x0f,
2259 NULL, HFILL }},
2261 { &hf_bssap_sgsn_number,
2262 { "SGSN number", "bssap.sgsn_number",
2263 FT_STRING, BASE_NONE, NULL, 0,
2264 NULL, HFILL }},
2266 #if 0
2267 { &hf_bssap_vlr_number,
2268 { "VLR number", "bssap.vlr_number",
2269 FT_STRING, BASE_NONE, NULL, 0,
2270 NULL, HFILL }},
2271 #endif
2273 { &hf_bssap_cell_global_id_ie,
2274 { "Cell global identity IE", "bssap.cell_global_id_ie",
2275 FT_NONE, BASE_NONE, NULL, 0,
2276 NULL, HFILL }},
2278 { &hf_bssap_channel_needed_ie,
2279 { "Channel needed IE", "bssap.channel_needed_ie",
2280 FT_NONE, BASE_NONE, NULL, 0,
2281 NULL, HFILL }},
2283 { &hf_bssap_dlink_tnl_pld_cntrl_amd_inf_ie,
2284 { "Downlink Tunnel Payload Control and Info IE", "bssap.dlink_tnl_pld_cntrl_amd_inf_ie",
2285 FT_NONE, BASE_NONE, NULL, 0,
2286 NULL, HFILL }},
2288 { &hf_bssap_ulink_tnl_pld_cntrl_amd_inf_ie,
2289 { "Uplink Tunnel Payload Control and Info IE", "bssap.ulink_tnl_pld_cntrl_amd_inf_ie",
2290 FT_NONE, BASE_NONE, NULL, 0,
2291 NULL, HFILL }},
2293 { &hf_bssap_emlpp_prio_ie,
2294 { "eMLPP Priority IE", "bssap.emlpp_prio_ie",
2295 FT_NONE, BASE_NONE, NULL, 0,
2296 NULL, HFILL }},
2298 { &hf_bssap_gprs_erroneous_msg_ie,
2299 { "Erroneous message IE", "bssap.erroneous_msg_ie",
2300 FT_NONE, BASE_NONE, NULL, 0,
2301 NULL, HFILL }},
2303 { &hf_bssap_gprs_loc_upd_type_ie,
2304 { "GPRS location update type IE", "bssap.loc_upd_type_ie",
2305 FT_NONE, BASE_NONE, NULL, 0,
2306 NULL, HFILL }},
2308 { &hf_bssap_Gs_cause_ie,
2309 { "Gs Cause IE", "bssap.Gs_cause_ie",
2310 FT_NONE, BASE_NONE, NULL, 0,
2311 NULL, HFILL }},
2313 { &hf_bssap_imei_ie,
2314 { "IMEI IE", "bssap.imei_ie",
2315 FT_NONE, BASE_NONE, NULL, 0,
2316 NULL, HFILL }},
2318 { &hf_bssap_imesiv_ie,
2319 { "IMEISV IE", "bssap.imesiv",
2320 FT_NONE, BASE_NONE, NULL, 0,
2321 NULL, HFILL }},
2323 { &hf_bssap_imsi_ie,
2324 { "IMSI IE", "bssap.imsi_ie",
2325 FT_NONE, BASE_NONE, NULL, 0,
2326 NULL, HFILL }},
2328 { &hf_bssap_imsi_det_from_gprs_serv_type_ie,
2329 { "IMSI detach from GPRS service type IE", "bssap.msi_det_from_gprs_serv_type_ie",
2330 FT_NONE, BASE_NONE, NULL, 0,
2331 NULL, HFILL }},
2333 { &hf_bssap_imsi_det_from_non_gprs_serv_type_ie,
2334 { "IMSI detach from non-GPRS service IE", "bssap.msi_det_from_non_gprs_serv_type_ie",
2335 FT_NONE, BASE_NONE, NULL, 0,
2336 NULL, HFILL }},
2338 { &hf_bssap_info_req_ie,
2339 { "Information requested IE", "bssap.info_req_ie",
2340 FT_NONE, BASE_NONE, NULL, 0,
2341 NULL, HFILL }},
2343 { &hf_bssap_loc_area_id_ie,
2344 { "Location area identifier IE", "bssap.loc_area_id_ie",
2345 FT_NONE, BASE_NONE, NULL, 0,
2346 NULL, HFILL }},
2348 { &hf_bssap_loc_inf_age_ie,
2349 { "Location information age IE", "bssap.loc_inf_age_ie",
2350 FT_NONE, BASE_NONE, NULL, 0,
2351 NULL, HFILL }},
2353 { &hf_bssap_mm_information_ie,
2354 { "MM information IE", "bssap.mm_information",
2355 FT_NONE, BASE_NONE, NULL, 0,
2356 NULL, HFILL }},
2358 { &hf_bssap_mobile_id_ie,
2359 { "Mobile identity IE", "bssap.mobile_id_ie",
2360 FT_NONE, BASE_NONE, NULL, 0,
2361 NULL, HFILL }},
2363 { &hf_bssap_mobile_stn_cls_mrk1_ie,
2364 { "Mobile station classmark 1 IE", "bssap.mobile_stn_cls_mrk1_ie",
2365 FT_NONE, BASE_NONE, NULL, 0,
2366 NULL, HFILL }},
2368 { &hf_bssap_mobile_station_state_ie,
2369 { "Mobile station state IE", "bssap.mobile_station_state_ie",
2370 FT_NONE, BASE_NONE, NULL, 0,
2371 NULL, HFILL }},
2373 { &hf_bssap_ptmsi_ie,
2374 { "PTMSI IE", "bssap.ptmsi_ie",
2375 FT_NONE, BASE_NONE, NULL, 0,
2376 NULL, HFILL }},
2378 { &hf_bssap_reject_cause_ie,
2379 { "Reject cause IE", "bssap.reject_cause_ie",
2380 FT_NONE, BASE_NONE, NULL, 0,
2381 NULL, HFILL }},
2383 { &hf_bssap_service_area_id_ie,
2384 { "Service area identification IE", "bssap.service_area_id_ie",
2385 FT_NONE, BASE_NONE, NULL, 0,
2386 "Mobile station classmark 1", HFILL }},
2388 { &hf_bssap_sgsn_nr_ie,
2389 { "SGSN number IE", "bssap.sgsn_nr_ie",
2390 FT_NONE, BASE_NONE, NULL, 0,
2391 NULL, HFILL }},
2393 { &hf_bssap_tmsi_ie,
2394 { "TMSI IE", "bssap.tmsi_ie",
2395 FT_NONE, BASE_NONE, NULL, 0,
2396 NULL, HFILL }},
2398 { &hf_bssap_tmsi_status_ie,
2399 { "TMSI status IE", "bssap.tmsi_status_ie",
2400 FT_NONE, BASE_NONE, NULL, 0,
2401 NULL, HFILL }},
2403 { &hf_bssap_vlr_number_ie,
2404 { "VLR number IE", "bssap.vlr_number_ie",
2405 FT_NONE, BASE_NONE, NULL, 0,
2406 NULL, HFILL }},
2408 { &hf_bssap_global_cn_id_ie,
2409 { "Global CN-Id IE", "bssap.global_cn_id_ie",
2410 FT_NONE, BASE_NONE, NULL, 0,
2411 NULL, HFILL }},
2413 { &hf_bssap_plus_ie_data,
2414 { "IE Data", "bssap.ie_data",
2415 FT_BYTES, BASE_NONE, NULL, 0,
2416 NULL, HFILL }},
2418 { &hf_bssap_call_priority,
2419 { "eMLPP Priority", "bssap.call_priority",
2420 FT_UINT8, BASE_DEC, VALS(bssap_call_priority_values), 0x07,
2421 NULL, HFILL}},
2423 { &hf_bssap_gprs_loc_upd_type,
2424 { "GPRS location update type", "bssap.gprs_loc_upd_type",
2425 FT_UINT8, BASE_DEC, VALS(bssap_plus_GPRS_loc_upd_type_values), 0x0,
2426 NULL, HFILL}},
2428 { &hf_bssap_Gs_cause,
2429 { "Gs cause", "bssap.Gs_cause",
2430 FT_UINT8, BASE_DEC, VALS(bssap_Gs_cause_values), 0x0,
2431 NULL, HFILL}},
2433 { &hf_bssap_imei,
2434 { "IMEI", "bssap.imei",
2435 FT_STRING, BASE_NONE, NULL, 0,
2436 NULL, HFILL }},
2438 { &hf_bssap_imeisv,
2439 { "IMEISV", "bssap.imeisv",
2440 FT_STRING, BASE_NONE, NULL, 0,
2441 NULL, HFILL }},
2443 { &hf_bssap_imsi,
2444 { "IMSI", "bssap.imsi",
2445 FT_STRING, BASE_NONE, NULL, 0,
2446 NULL, HFILL }},
2448 { &hf_bssap_imsi_det_from_gprs_serv_type,
2449 { "IMSI detach from GPRS service type", "bssap.imsi_det_from_gprs_serv_type",
2450 FT_UINT8, BASE_DEC, VALS(bssap_Gs_cause_values), 0x0,
2451 NULL, HFILL}},
2453 { &hf_bssap_info_req,
2454 { "Information requested", "bssap.info_req",
2455 FT_UINT8, BASE_DEC, VALS(bssap_info_req_values), 0x0,
2456 NULL, HFILL}},
2458 { &hf_bssap_loc_inf_age,
2459 { "AgeOfLocationInformation in minutes", "bssap.loc_inf_age",
2460 FT_UINT16, BASE_DEC, NULL, 0x0,
2461 NULL, HFILL}},
2463 { &hf_bssap_mobile_station_state,
2464 { "Mobile station state", "bssap.mobile_station_state",
2465 FT_UINT8, BASE_DEC, VALS(bssap_mobile_station_state_values), 0x0,
2466 NULL, HFILL}},
2468 { &hf_bssap_ptmsi,
2469 { "PTMSI", "bssap.ptmsi",
2470 FT_BYTES, BASE_NONE, NULL, 0x0,
2471 NULL, HFILL}},
2473 { &hf_bssap_tmsi,
2474 { "TMSI", "bssap.tmsi",
2475 FT_BYTES, BASE_NONE, NULL, 0x0,
2476 NULL, HFILL}},
2478 { &hf_bssap_tmsi_status,
2479 { "TMSI status", "bssap.tmsi_status",
2480 FT_BOOLEAN, 8, TFS(&bssap_tmsi_flag), 0x01,
2481 NULL, HFILL }},
2483 { &hf_bssap_tom_prot_disc,
2484 { "TOM Protocol Discriminator", "bssap.Tom_prot_disc",
2485 FT_UINT8, BASE_DEC, VALS(bssap_tom_prot_disc_values), 0x78,
2486 NULL, HFILL}},
2488 { &hf_bssap_e_bit,
2489 { "E: Cipher Request", "bssap.e_bit",
2490 FT_BOOLEAN, 8, TFS(&bssap_E_flag), 0x04,
2491 NULL, HFILL }},
2493 { &hf_bssap_tunnel_prio,
2494 { "Tunnel Priority", "bssap.tunnel_prio",
2495 FT_UINT8, BASE_DEC, NULL, 0x0,
2496 NULL, HFILL}},
2498 { &hf_bssap_global_cn_id,
2499 { "Global CN-Id", "bssap.global_cn_id",
2500 FT_BYTES, BASE_NONE, NULL, 0x0,
2501 NULL, HFILL}},
2503 { &hf_bssap_plmn_id,
2504 { "PLMN-Id", "bssap.plmn_id",
2505 FT_BYTES, BASE_NONE, NULL, 0x0,
2506 NULL, HFILL}},
2508 { &hf_bssap_cn_id,
2509 { "CN-Id", "bssap.cn_id",
2510 FT_UINT16, BASE_DEC, NULL, 0x0,
2511 NULL, HFILL}},
2513 { &hf_bssap_cell_global_id,
2514 { "Cell global identity", "bssap.cell_global_id",
2515 FT_BYTES, BASE_NONE, NULL, 0x0,
2516 NULL, HFILL}},
2519 /* Setup protocol subtree array */
2520 static gint *ett[] = {
2521 &ett_bssap,
2522 &ett_bssap_dlci,
2523 &ett_bssap_imsi,
2524 &ett_bssap_imsi_det_from_gprs_serv_type,
2525 &ett_bssap_imsi_det_from_non_gprs_serv_type,
2526 &ett_bssap_info_req,
2527 &ett_bssap_loc_area_id,
2528 &ett_bssap_loc_inf_age,
2529 &ett_bssap_mm_information,
2530 &ett_bssap_mobile_id,
2531 &ett_bssap_sgsn_nr,
2532 &ett_bssap_tmsi,
2533 &ett_bssap_tmsi_status,
2534 &ett_bssap_vlr_number,
2535 &ett_bssap_global_cn,
2536 &ett_bssap_gprs_loc_upd,
2537 &ett_bassp_Gs_cause,
2538 &ett_bassp_imei,
2539 &ett_bassp_imesiv,
2540 &ett_bssap_cell_global_id,
2541 &ett_bssap_cgi,
2542 &ett_bssap_channel_needed,
2543 &ett_bssap_dlink_tnl_pld_cntrl_amd_inf,
2544 &ett_bssap_ulink_tnl_pld_cntrl_amd_inf,
2545 &ett_bssap_emlpp_prio,
2546 &ett_bssap_erroneous_msg,
2547 &ett_bssap_mobile_stn_cls_mrk1,
2548 &ett_bssap_mobile_station_state,
2549 &ett_bssap_ptmsi,
2550 &ett_bssap_reject_cause,
2551 &ett_bssap_service_area_id,
2552 &ett_bssap_global_cn_id,
2553 &ett_bssap_plmn,
2556 static const enum_val_t gsm_or_lb_interface_options[] = {
2557 { "gsm a", "GSM A", GSM_INTERFACE },
2558 { "lb", "Lb", LB_INTERFACE },
2559 { NULL, NULL, 0 }
2562 static const enum_val_t bssap_or_bsap_options[] = {
2563 { "bssap", "BSSAP", BSSAP },
2564 { "bsap", "BSAP", BSAP },
2565 { NULL, NULL, 0 }
2569 /* Register the protocol name and description */
2570 proto_bssap = proto_register_protocol("BSSAP/BSAP", "BSSAP", "bssap");
2571 /*proto_bssap_plus = proto_register_protocol("BSSAP2", "BSSAP2", "bssap2");*/
2573 register_dissector("bssap", dissect_bssap, proto_bssap);
2574 register_dissector("bssap_plus", dissect_bssap_plus, proto_bssap);
2576 /* Required function calls to register the header fields and subtrees used */
2577 proto_register_field_array(proto_bssap, hf, array_length(hf));
2578 proto_register_subtree_array(ett, array_length(ett));
2580 bssap_module = prefs_register_protocol(proto_bssap, proto_reg_handoff_bssap);
2582 prefs_register_enum_preference(bssap_module,
2583 "bsap_or_bssap",
2584 "Identify to sub-dissector as",
2585 "For the sake of sub-dissectors registering to accept data "
2586 "from the BSSAP/BSAP dissector, this defines whether it is "
2587 "identified as BSSAP or BSAP.",
2588 &bssap_or_bsap_global,
2589 bssap_or_bsap_options,
2590 FALSE);
2592 prefs_register_enum_preference(bssap_module,
2593 "gsm_or_lb_interface",
2594 "Identify the BSSAP interface",
2595 "GSM-A is the interface between the BSC and the MSC. Lb is the interface between the BSC and the SMLC.",
2596 &gsm_or_lb_interface_global,
2597 gsm_or_lb_interface_options,
2598 FALSE);
2600 prefs_register_uint_preference(bssap_module, "ssn",
2601 "Subsystem number used for BSSAP",
2602 "Set Subsystem number used for BSSAP/BSSAP+",
2603 10, &global_bssap_ssn);
2604 bssap_dissector_table = register_dissector_table("bssap.pdu_type", "BSSAP Message Type", FT_UINT8, BASE_DEC);
2605 bsap_dissector_table = register_dissector_table("bsap.pdu_type", "BSAP Message Type", FT_UINT8, BASE_DEC);
2608 void
2609 proto_reg_handoff_bssap(void)
2611 static gboolean initialized = FALSE;
2612 static dissector_handle_t bssap_plus_handle;
2613 static guint old_bssap_ssn;
2615 if (!initialized) {
2616 heur_dissector_add("sccp", dissect_bssap_heur, proto_bssap);
2617 heur_dissector_add("sua", dissect_bssap_heur, proto_bssap);
2618 /* BSSAP+ */
2619 bssap_plus_handle = create_dissector_handle(dissect_bssap_plus, proto_bssap);
2621 data_handle = find_dissector("data");
2622 rrlp_handle = find_dissector("rrlp");
2623 initialized = TRUE;
2624 } else {
2625 dissector_delete_uint("sccp.ssn", old_bssap_ssn, bssap_plus_handle);
2628 dissector_add_uint("sccp.ssn", global_bssap_ssn, bssap_plus_handle);
2629 old_bssap_ssn = global_bssap_ssn;