Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gsm_gsup.c
blob7689b5a1963439bc80ecf3e763719168a9d33a21
1 /* packet-gsm_gsup.c
2 * Dissector for Osmocom Generic Subscriber Update Protocol (GSUP)
4 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
5 * Contributions by sysmocom - s.f.m.c. GmbH
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include <epan/conversation.h>
31 #include <epan/asn1.h>
32 #include <epan/strutil.h>
34 #include "packet-gsm_a_common.h"
35 #include "packet-gsm_map.h"
36 #include "packet-e164.h"
37 #include "packet-e212.h"
38 #include "packet-dns.h"
39 #include "packet-ber.h"
40 #include "asn1.h"
42 /* GSUP is a non-standard, Osmocom-specific protocol used between cellular
43 * network core elements and the HLR. It is a much simplified replacement
44 * for the GSM MAP (Mobile Application Part), which requires a full stack
45 * of SIGTRAN transport, SCCP as well as TCP.
47 * More information about GSUP can be found in the OsmoHLR user manual
48 * found at http://ftp.osmocom.org/docs/latest/osmohlr-usermanual.pdf
51 /***********************************************************************
52 * GSUP Protocol Definitions, see libosmocore/include/gsm/gsup.h
53 ***********************************************************************/
55 #define OSMO_GSUP_PORT 4222
56 #define IPAC_PROTO_EXT_GSUP 0x05
58 /*! Maximum number of PDP inside \ref osmo_gsup_message */
59 #define OSMO_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */
60 /*! Maximum number of auth info inside \ref osmo_gsup_message */
61 #define OSMO_GSUP_MAX_NUM_AUTH_INFO 5
62 /*! Maximum number of octets encoding MSISDN in BCD format */
63 #define OSMO_GSUP_MAX_MSISDN_LEN 9
65 /*! Information Element Identifiers for GSUP IEs */
66 enum osmo_gsup_iei {
67 OSMO_GSUP_IMSI_IE = 0x01,
68 OSMO_GSUP_CAUSE_IE = 0x02,
69 OSMO_GSUP_AUTH_TUPLE_IE = 0x03,
70 OSMO_GSUP_PDP_INFO_COMPL_IE = 0x04,
71 OSMO_GSUP_PDP_INFO_IE = 0x05,
72 OSMO_GSUP_CANCEL_TYPE_IE = 0x06,
73 OSMO_GSUP_FREEZE_PTMSI_IE = 0x07,
74 OSMO_GSUP_MSISDN_IE = 0x08,
75 OSMO_GSUP_HLR_NUMBER_IE = 0x09,
76 OSMO_GSUP_MESSAGE_CLASS_IE = 0x0a,
77 OSMO_GSUP_PDP_CONTEXT_ID_IE = 0x10,
78 OSMO_GSUP_PDP_ADDRESS_IE = 0x11,
79 OSMO_GSUP_ACCESS_POINT_NAME_IE = 0x12,
80 OSMO_GSUP_PDP_QOS_IE = 0x13,
81 OSMO_GSUP_CHARG_CHAR_IE = 0x14,
82 OSMO_GSUP_PCO_IE = 0x15,
83 OSMO_GSUP_RAND_IE = 0x20,
84 OSMO_GSUP_SRES_IE = 0x21,
85 OSMO_GSUP_KC_IE = 0x22,
86 /* 3G support */
87 OSMO_GSUP_IK_IE = 0x23,
88 OSMO_GSUP_CK_IE = 0x24,
89 OSMO_GSUP_AUTN_IE = 0x25,
90 OSMO_GSUP_AUTS_IE = 0x26,
91 OSMO_GSUP_RES_IE = 0x27,
92 OSMO_GSUP_CN_DOMAIN_IE = 0x28,
93 OSMO_GSUP_SUPPORTED_RAT_TYPES_IE = 0x29,
94 OSMO_GSUP_CURRENT_RAT_TYPE_IE = 0x2a,
95 OSMO_GSUP_SESSION_ID_IE = 0x30,
96 OSMO_GSUP_SESSION_STATE_IE = 0x31,
97 OSMO_GSUP_SS_INFO_IE = 0x35,
98 /* SM Service (see 3GPP TS 29.002, section 7.6.8) */
99 OSMO_GSUP_SM_RP_MR_IE = 0x40,
100 OSMO_GSUP_SM_RP_DA_IE = 0x41,
101 OSMO_GSUP_SM_RP_OA_IE = 0x42,
102 OSMO_GSUP_SM_RP_UI_IE = 0x43,
103 OSMO_GSUP_SM_RP_CAUSE_IE = 0x44,
104 OSMO_GSUP_SM_RP_MMS_IE = 0x45,
105 OSMO_GSUP_SM_ALERT_RSN_IE = 0x46,
107 OSMO_GSUP_IMEI_IE = 0x50,
108 OSMO_GSUP_IMEI_RESULT_IE = 0x51,
109 OSMO_GSUP_NUM_VECTORS_REQ_IE = 0x52,
111 /* Inter-MSC handover related */
112 OSMO_GSUP_SOURCE_NAME_IE = 0x60,
113 OSMO_GSUP_DESTINATION_NAME_IE = 0x61,
114 OSMO_GSUP_AN_APDU_IE = 0x62,
115 OSMO_GSUP_CAUSE_RR_IE = 0x63,
116 OSMO_GSUP_CAUSE_BSSAP_IE = 0x64,
117 OSMO_GSUP_CAUSE_SM_IE = 0x65,
120 /*! GSUP message type */
121 enum osmo_gsup_message_type {
122 OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST = 0x04,
123 OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR = 0x05,
124 OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT = 0x06,
126 OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST = 0x08,
127 OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR = 0x09,
128 OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT = 0x0a,
130 OSMO_GSUP_MSGT_AUTH_FAIL_REPORT = 0x0b,
132 OSMO_GSUP_MSGT_PURGE_MS_REQUEST = 0x0c,
133 OSMO_GSUP_MSGT_PURGE_MS_ERROR = 0x0d,
134 OSMO_GSUP_MSGT_PURGE_MS_RESULT = 0x0e,
136 OSMO_GSUP_MSGT_INSERT_DATA_REQUEST = 0x10,
137 OSMO_GSUP_MSGT_INSERT_DATA_ERROR = 0x11,
138 OSMO_GSUP_MSGT_INSERT_DATA_RESULT = 0x12,
140 OSMO_GSUP_MSGT_DELETE_DATA_REQUEST = 0x14,
141 OSMO_GSUP_MSGT_DELETE_DATA_ERROR = 0x15,
142 OSMO_GSUP_MSGT_DELETE_DATA_RESULT = 0x16,
144 OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST = 0x1c,
145 OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR = 0x1d,
146 OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT = 0x1e,
148 OSMO_GSUP_MSGT_PROC_SS_REQUEST = 0x20,
149 OSMO_GSUP_MSGT_PROC_SS_ERROR = 0x21,
150 OSMO_GSUP_MSGT_PROC_SS_RESULT = 0x22,
152 OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST = 0x24,
153 OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR = 0x25,
154 OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT = 0x26,
156 OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST = 0x28,
157 OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR = 0x29,
158 OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT = 0x2a,
160 OSMO_GSUP_MSGT_READY_FOR_SM_REQUEST = 0x2c,
161 OSMO_GSUP_MSGT_READY_FOR_SM_ERROR = 0x2d,
162 OSMO_GSUP_MSGT_READY_FOR_SM_RESULT = 0x2e,
164 OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST = 0x30,
165 OSMO_GSUP_MSGT_CHECK_IMEI_ERROR = 0x31,
166 OSMO_GSUP_MSGT_CHECK_IMEI_RESULT = 0x32,
168 OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST = 0x34,
169 OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR = 0x35,
170 OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT = 0x36,
172 OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST = 0x38,
173 OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_ERROR = 0x39,
174 OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT = 0x3a,
176 OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST = 0x3c,
177 OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_ERROR = 0x3d,
178 OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_RESULT = 0x3e,
180 OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST = 0x40,
181 OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST = 0x44,
183 OSMO_GSUP_MSGT_E_CLOSE = 0x47,
184 OSMO_GSUP_MSGT_E_ABORT = 0x4b,
186 OSMO_GSUP_MSGT_E_ROUTING_ERROR = 0x4e,
188 OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST = 0x50,
189 OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR = 0x51,
190 OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT = 0x52,
193 #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
194 #define OSMO_GSUP_IS_MSGT_ERROR(msgt) (((msgt) & 0b00000011) == 0b01)
195 #define OSMO_GSUP_TO_MSGT_ERROR(msgt) (((msgt) & 0b11111100) | 0b01)
197 enum osmo_gsup_rat_type {
198 OSMO_GSUP_RAT_UNKNOWN = 0,
199 OSMO_GSUP_RAT_GERAN_A = 1,
200 OSMO_GSUP_RAT_UTRAN_IU = 2,
201 OSMO_GSUP_RAT_EUTRAN_SGS = 3,
204 enum osmo_gsup_cancel_type {
205 OSMO_GSUP_CANCEL_TYPE_UPDATE = 0,
206 OSMO_GSUP_CANCEL_TYPE_WITHDRAW = 1,
209 enum osmo_gsup_cn_domain {
210 OSMO_GSUP_CN_DOMAIN_PS = 1,
211 OSMO_GSUP_CN_DOMAIN_CS = 2,
214 enum osmo_gsup_imei_result {
215 OSMO_GSUP_IMEI_RESULT_ACK = 0,
216 OSMO_GSUP_IMEI_RESULT_NACK = 1,
219 enum osmo_gsup_session_state {
220 OSMO_GSUP_SESSION_STATE_NONE = 0x00,
221 OSMO_GSUP_SESSION_STATE_BEGIN = 0x01,
222 OSMO_GSUP_SESSION_STATE_CONTINUE = 0x02,
223 OSMO_GSUP_SESSION_STATE_END = 0x03,
226 /* Identity types for SM-RP-{OA|DA} */
227 enum osmo_gsup_sms_sm_rp_oda_type {
228 OSMO_GSUP_SMS_SM_RP_ODA_NONE = 0x00,
229 OSMO_GSUP_SMS_SM_RP_ODA_IMSI = 0x01,
230 OSMO_GSUP_SMS_SM_RP_ODA_MSISDN = 0x02,
231 OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR = 0x03,
232 /* Special value for noSM-RP-DA and noSM-RP-OA */
233 OSMO_GSUP_SMS_SM_RP_ODA_NULL = 0xff,
236 /* SM Alert Reason values */
237 enum osmo_gsup_sms_sm_alert_rsn_t {
238 OSMO_GSUP_SMS_SM_ALERT_RSN_NONE = 0x00,
239 OSMO_GSUP_SMS_SM_ALERT_RSN_MS_PRESENT = 0x01,
240 OSMO_GSUP_SMS_SM_ALERT_RSN_MEM_AVAIL = 0x02,
243 enum osmo_gsup_access_network_protocol {
244 OSMO_GSUP_ACCESS_NETWORK_PROTOCOL_TS3G_48006 = 1,
245 OSMO_GSUP_ACCESS_NETWORK_PROTOCOL_TS3G_25413 = 2,
248 enum osmo_gsup_message_class {
249 OSMO_GSUP_MESSAGE_CLASS_UNSET = 0,
250 OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT = 1,
251 OSMO_GSUP_MESSAGE_CLASS_SMS = 2,
252 OSMO_GSUP_MESSAGE_CLASS_USSD = 3,
253 OSMO_GSUP_MESSAGE_CLASS_INTER_MSC = 4,
256 /* like TS 29.002 access network protocol ID */
257 enum osmo_gsup_an_type {
258 OSMO_GSUP_AN_TYPE_BSSAP = 1,
259 OSMO_GSUP_AN_TYPE_RANAP = 2,
262 /***********************************************************************
263 * Wireshark Dissector Implementation
264 ***********************************************************************/
266 void proto_register_gsup(void);
267 void proto_reg_handoff_gsup(void);
269 static int proto_gsup;
271 /* show GSUP source/destination names as text (true) or only binary (false) */
272 static bool show_name_as_text = true;
274 static int hf_gsup_msg_type;
275 static int hf_gsup_iei;
276 static int hf_gsup_ie_len;
277 static int hf_gsup_ie_payload;
278 static int hf_gsup_cause;
279 static int hf_gsup_pdp_info_compl;
280 static int hf_gsup_cancel_type;
281 static int hf_gsup_freeze_ptmsi;
282 static int hf_gsup_pdp_context_id;
283 static int hf_gsup_charg_char;
284 static int hf_gsup_apn;
285 static int hf_gsup_cn_domain;
286 static int hf_gsup_rand;
287 static int hf_gsup_sres;
288 static int hf_gsup_kc;
289 static int hf_gsup_ik;
290 static int hf_gsup_ck;
291 static int hf_gsup_autn;
292 static int hf_gsup_auts;
293 static int hf_gsup_res;
294 static int hf_gsup_session_id;
295 static int hf_gsup_session_state;
296 static int hf_gsup_sm_rp_mr;
297 static int hf_gsup_sm_rp_da_id_type;
298 static int hf_gsup_sm_rp_oa_id_type;
299 static int hf_gsup_sm_rp_cause;
300 static int hf_gsup_sm_rp_mms;
301 static int hf_gsup_sm_alert_rsn;
302 static int hf_gsup_imei_result;
303 static int hf_gsup_num_vectors_req;
304 static int hf_gsup_msg_class;
305 static int hf_gsup_an_type;
306 static int hf_gsup_source_name;
307 static int hf_gsup_source_name_text;
308 static int hf_gsup_destination_name;
309 static int hf_gsup_destination_name_text;
310 static int hf_gsup_supported_rat_type;
311 static int hf_gsup_current_rat_type;
312 static int hf_gsup_pdp_addr_type_org;
313 static int hf_gsup_spare_bits;
314 static int hf_gsup_pdp_addr_type_nr;
315 static int hf_gsup_pdp_addr_v4;
316 static int hf_gsup_pdp_addr_v6;
318 static int ett_gsup;
319 static int ett_gsup_ie;
321 static expert_field ei_sm_rp_da_invalid;
322 static expert_field ei_sm_rp_oa_invalid;
323 static expert_field ei_gsup_ie_len_invalid;
325 static dissector_handle_t gsm_map_handle;
326 static dissector_handle_t gsup_handle;
327 static dissector_handle_t gsm_sms_handle;
328 static dissector_handle_t bssap_imei_handle;
329 static dissector_handle_t bssap_handle;
330 static dissector_handle_t ranap_handle;
332 static const value_string gsup_iei_types[] = {
333 { OSMO_GSUP_IMSI_IE, "IMSI" },
334 { OSMO_GSUP_CAUSE_IE, "Cause" },
335 { OSMO_GSUP_AUTH_TUPLE_IE, "Authentication Tuple" },
336 { OSMO_GSUP_PDP_INFO_COMPL_IE, "PDP Information Complete" },
337 { OSMO_GSUP_PDP_INFO_IE, "PDP Information" },
338 { OSMO_GSUP_CANCEL_TYPE_IE, "Cancel Type" },
339 { OSMO_GSUP_FREEZE_PTMSI_IE, "Freeze P-TMSI" },
340 { OSMO_GSUP_MSISDN_IE, "MSISDN" },
341 { OSMO_GSUP_HLR_NUMBER_IE, "HLR Number" },
342 { OSMO_GSUP_PDP_CONTEXT_ID_IE, "PDP Context ID" },
343 { OSMO_GSUP_PDP_ADDRESS_IE, "PDP Address" },
344 { OSMO_GSUP_ACCESS_POINT_NAME_IE, "Access Point Name (APN)" },
345 { OSMO_GSUP_PDP_QOS_IE, "PDP Quality of Service (QoS)" },
346 { OSMO_GSUP_CHARG_CHAR_IE, "Charging Character" },
347 { OSMO_GSUP_PCO_IE, "Protocol Configuration Options" },
348 { OSMO_GSUP_RAND_IE, "RAND" },
349 { OSMO_GSUP_SRES_IE, "SRES" },
350 { OSMO_GSUP_KC_IE, "Kc" },
351 { OSMO_GSUP_IK_IE, "IK" },
352 { OSMO_GSUP_CK_IE, "CK" },
353 { OSMO_GSUP_AUTN_IE, "AUTN" },
354 { OSMO_GSUP_AUTS_IE, "AUTS" },
355 { OSMO_GSUP_RES_IE, "RES" },
356 { OSMO_GSUP_CN_DOMAIN_IE, "CN Domain" },
357 { OSMO_GSUP_SUPPORTED_RAT_TYPES_IE, "Supported RAT Types" },
358 { OSMO_GSUP_CURRENT_RAT_TYPE_IE, "Current RAT Type" },
359 { OSMO_GSUP_SESSION_ID_IE, "Session Id" },
360 { OSMO_GSUP_SESSION_STATE_IE, "Session State" },
361 { OSMO_GSUP_SS_INFO_IE, "Supplementary Service Info"},
362 { OSMO_GSUP_SM_RP_MR_IE, "SM-RP-MR (Message Reference)" },
363 { OSMO_GSUP_SM_RP_DA_IE, "SM-RP-DA (Destination Address)" },
364 { OSMO_GSUP_SM_RP_OA_IE, "SM-RP-OA (Originating Address)" },
365 { OSMO_GSUP_SM_RP_UI_IE, "SM-RP-UI (SMS TPDU)" },
366 { OSMO_GSUP_SM_RP_CAUSE_IE, "SM-RP-Cause" },
367 { OSMO_GSUP_SM_RP_MMS_IE, "SM-RP-MMS (More Messages to Send)" },
368 { OSMO_GSUP_SM_ALERT_RSN_IE, "SM Alert Reason" },
369 { OSMO_GSUP_IMEI_IE, "IMEI" },
370 { OSMO_GSUP_IMEI_RESULT_IE, "IMEI Check Result" },
371 { OSMO_GSUP_NUM_VECTORS_REQ_IE, "Number of Vectors Requested" },
372 { OSMO_GSUP_MESSAGE_CLASS_IE, "Message Class" },
373 { OSMO_GSUP_SOURCE_NAME_IE, "Source Name"},
374 { OSMO_GSUP_DESTINATION_NAME_IE,"Destination Name"},
375 { OSMO_GSUP_AN_APDU_IE, "AN-APDU"},
376 { OSMO_GSUP_CAUSE_RR_IE, "RR-Cause"},
377 { OSMO_GSUP_CAUSE_BSSAP_IE, "BSSAP-Cause"},
378 { OSMO_GSUP_CAUSE_SM_IE, "Session Management Cause"},
379 { 0, NULL }
382 static const value_string gsup_msg_types[] = {
383 { OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST, "UpdateLocation Request" },
384 { OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR, "UpdateLocation Error" },
385 { OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT, "UpdateLocation Result" },
386 { OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST, "SendAuthInfo Request" },
387 { OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR, "SendAuthInfo Error" },
388 { OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT, "SendAuthInfo Result" },
389 { OSMO_GSUP_MSGT_AUTH_FAIL_REPORT, "AuthFail Report" },
390 { OSMO_GSUP_MSGT_PURGE_MS_REQUEST, "PurgeMS Request" },
391 { OSMO_GSUP_MSGT_PURGE_MS_ERROR, "PurgeMS Error" },
392 { OSMO_GSUP_MSGT_PURGE_MS_RESULT, "PurgeMS Result" },
393 { OSMO_GSUP_MSGT_INSERT_DATA_REQUEST, "InsertSubscriberData Request" },
394 { OSMO_GSUP_MSGT_INSERT_DATA_ERROR, "InsertSubscriberData Error" },
395 { OSMO_GSUP_MSGT_INSERT_DATA_RESULT, "InsertSubscriberData Result" },
396 { OSMO_GSUP_MSGT_DELETE_DATA_REQUEST, "DeleteSubscriberData Request" },
397 { OSMO_GSUP_MSGT_DELETE_DATA_ERROR, "DeleteSubscriberData Error" },
398 { OSMO_GSUP_MSGT_DELETE_DATA_RESULT, "DeleteSubscriberData Result" },
399 { OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST, "LocationCancel Request" },
400 { OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR, "LocationCancel Error" },
401 { OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT, "LocationCancel Result" },
402 { OSMO_GSUP_MSGT_PROC_SS_REQUEST, "Supplementary Service Request" },
403 { OSMO_GSUP_MSGT_PROC_SS_ERROR, "Supplementary Service Error" },
404 { OSMO_GSUP_MSGT_PROC_SS_RESULT, "Supplementary Service Result" },
405 { OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST, "MO-forwardSM Request" },
406 { OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR, "MO-forwardSM Error" },
407 { OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT, "MO-forwardSM Result" },
408 { OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST, "MT-forwardSM Request" },
409 { OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR, "MT-forwardSM Error" },
410 { OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT, "MT-forwardSM Result" },
411 { OSMO_GSUP_MSGT_READY_FOR_SM_REQUEST, "Ready for SM Request"},
412 { OSMO_GSUP_MSGT_READY_FOR_SM_ERROR, "Ready for SM Error"},
413 { OSMO_GSUP_MSGT_READY_FOR_SM_RESULT, "Ready for SM Result"},
414 { OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST, "Check IMEI Request"},
415 { OSMO_GSUP_MSGT_CHECK_IMEI_ERROR, "Check IMEI Error"},
416 { OSMO_GSUP_MSGT_CHECK_IMEI_RESULT, "Check IMEI Result"},
417 { OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST, "E Prepare Handover Request"},
418 { OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR, "E Prepare Handover Error"},
419 { OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_RESULT, "E Prepare Handover Result"},
420 { OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST, "E Prepare Subsequent Handover Request"},
421 { OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_ERROR, "E Prepare Subsequent Handover Error"},
422 { OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT, "E Prepare Subsequent Handover Result"},
423 { OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST, "E Send End Signal Request"},
424 { OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_ERROR, "E Send End Signal Error"},
425 { OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_RESULT, "E Send End Signal Result"},
426 { OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST, "E Process Access Signalling Request"},
427 { OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST, "E Forward Access Signalling Request"},
428 { OSMO_GSUP_MSGT_E_CLOSE, "E Close"},
429 { OSMO_GSUP_MSGT_E_ABORT, "E Abort"},
430 { OSMO_GSUP_MSGT_E_ROUTING_ERROR, "E Routing Error"},
431 { OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST, "ePDG Tunnel Request"},
432 { OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR, "ePDG Tunnel Error"},
433 { OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT, "ePDG Tunnel Result"},
434 { 0, NULL }
437 static const value_string gsup_rat_types[] = {
438 { OSMO_GSUP_RAT_UNKNOWN, "Unknown" },
439 { OSMO_GSUP_RAT_GERAN_A, "GERAN (A)" },
440 { OSMO_GSUP_RAT_UTRAN_IU, "UTRAN (IU)" },
441 { OSMO_GSUP_RAT_EUTRAN_SGS, "EUTRAN (SGS)" },
442 { 0, NULL }
445 static const value_string gsup_cancel_types[] = {
446 { OSMO_GSUP_CANCEL_TYPE_UPDATE, "Update" },
447 { OSMO_GSUP_CANCEL_TYPE_WITHDRAW, "Withdraw" },
448 { 0, NULL }
451 static const value_string gsup_cndomain_types[] = {
452 { OSMO_GSUP_CN_DOMAIN_PS, "PS" },
453 { OSMO_GSUP_CN_DOMAIN_CS, "CS" },
454 { 0, NULL }
457 static const value_string gsup_session_states[] = {
458 { OSMO_GSUP_SESSION_STATE_NONE, "NONE" },
459 { OSMO_GSUP_SESSION_STATE_BEGIN, "BEGIN" },
460 { OSMO_GSUP_SESSION_STATE_CONTINUE, "CONTINUE" },
461 { OSMO_GSUP_SESSION_STATE_END, "END" },
462 { 0, NULL }
465 static const value_string osmo_gsup_sms_sm_rp_oda_types[] = {
466 { OSMO_GSUP_SMS_SM_RP_ODA_NONE, "NONE" },
467 { OSMO_GSUP_SMS_SM_RP_ODA_IMSI, "IMSI" },
468 { OSMO_GSUP_SMS_SM_RP_ODA_MSISDN, "MSISDN" },
469 { OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR, "SMSC Address" },
470 { OSMO_GSUP_SMS_SM_RP_ODA_NULL, "noSM-RP-DA or noSM-RP-OA" },
471 { 0, NULL }
474 static const value_string osmo_gsup_sms_sm_alert_rsn_types[] = {
475 { OSMO_GSUP_SMS_SM_ALERT_RSN_NONE, "NONE" },
476 { OSMO_GSUP_SMS_SM_ALERT_RSN_MS_PRESENT, "MS Present" },
477 { OSMO_GSUP_SMS_SM_ALERT_RSN_MEM_AVAIL, "Memory Available (SMMA)" },
478 { 0, NULL }
481 static const value_string gsup_imei_result_types[] = {
482 { OSMO_GSUP_IMEI_RESULT_ACK, "ACK" },
483 { OSMO_GSUP_IMEI_RESULT_NACK, "NACK" },
484 { 0, NULL }
487 static const value_string gsup_msg_class_types[] = {
488 { OSMO_GSUP_MESSAGE_CLASS_UNSET, "unset" },
489 { OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT, "Subscriber-Management" },
490 { OSMO_GSUP_MESSAGE_CLASS_SMS, "SMS" },
491 { OSMO_GSUP_MESSAGE_CLASS_USSD, "USSD" },
492 { OSMO_GSUP_MESSAGE_CLASS_INTER_MSC, "Inter-MSC" },
493 { 0, NULL }
496 static const value_string gsup_an_type_vals[] = {
497 { OSMO_GSUP_AN_TYPE_BSSAP, "BSSAP" },
498 { OSMO_GSUP_AN_TYPE_RANAP, "RANAP" },
499 { 0, NULL }
503 static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree)
505 unsigned saved_offset;
506 int8_t appclass;
507 bool pc;
508 bool ind = false;
509 uint32_t component_len = 0;
510 uint32_t header_end_offset;
511 uint32_t header_len;
512 asn1_ctx_t asn1_ctx;
513 tvbuff_t *ss_tvb = NULL;
514 static int comp_type_tag;
516 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
517 saved_offset = offset;
518 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
519 col_set_fence(pinfo->cinfo, COL_PROTOCOL);
520 while (len > (offset - saved_offset)) {
521 /* get the length of the component. there can be multiple components in one message */
522 header_end_offset = get_ber_identifier(tvb, offset, &appclass, &pc, &comp_type_tag);
523 header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind);
524 header_len = header_end_offset -offset;
525 component_len += header_len;
527 ss_tvb = tvb_new_subset_length(tvb, offset, component_len);
528 col_append_str(pinfo->cinfo, COL_INFO, "(GSM MAP) ");
529 col_set_fence(pinfo->cinfo, COL_INFO);
530 call_dissector(gsm_map_handle, ss_tvb, pinfo, tree);
531 offset += component_len;
535 static void dissect_sm_rp_da_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
536 unsigned ie_len, proto_tree *tree)
538 tvbuff_t *addr_tvb;
539 proto_item *ti;
540 uint8_t id_type;
542 /* Identity type is mandatory */
543 if (ie_len < 1) {
544 expert_add_info_format(pinfo, NULL, &ei_sm_rp_da_invalid,
545 "Missing mandatory SM-RP-DA ID type (IE len < 1)");
546 return;
549 /* Parse ID type */
550 ti = proto_tree_add_item(tree, hf_gsup_sm_rp_da_id_type, tvb, offset, 1, ENC_NA);
551 id_type = tvb_get_uint8(tvb, offset);
553 switch (id_type) {
554 case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:
555 dissect_e212_imsi(tvb, pinfo, tree,
556 offset + 1, ie_len - 1, false);
557 break;
558 case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
559 case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
560 addr_tvb = tvb_new_subset_length(tvb, offset + 1, ie_len - 1);
561 dissect_gsm_map_msisdn(addr_tvb, pinfo, tree);
562 break;
564 /* Special case for noSM-RP-DA and noSM-RP-OA */
565 case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
566 if (ie_len > 1) {
567 expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
568 "Unexpected ID length=%u for noSM-RP-DA", ie_len - 1);
569 return;
571 break;
573 case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
574 default:
575 expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
576 "Unexpected SM-RP-DA ID (type=0x%02x)", id_type);
577 return;
581 static void dissect_sm_rp_oa_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
582 unsigned ie_len, proto_tree *tree)
584 tvbuff_t *addr_tvb;
585 proto_item *ti;
586 uint8_t id_type;
588 /* Identity type is mandatory */
589 if (ie_len < 1) {
590 expert_add_info_format(pinfo, NULL, &ei_sm_rp_oa_invalid,
591 "Missing mandatory SM-RP-OA ID type (IE len < 1)");
592 return;
595 /* Parse ID type */
596 ti = proto_tree_add_item(tree, hf_gsup_sm_rp_oa_id_type, tvb, offset, 1, ENC_NA);
597 id_type = tvb_get_uint8(tvb, offset);
599 switch (id_type) {
600 case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
601 case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
602 addr_tvb = tvb_new_subset_length(tvb, offset + 1, ie_len - 1);
603 dissect_gsm_map_msisdn(addr_tvb, pinfo, tree);
604 break;
606 /* Special case for noSM-RP-DA and noSM-RP-OA */
607 case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
608 if (ie_len > 1) {
609 expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
610 "Unexpected ID length=%u for noSM-RP-OA", ie_len - 1);
611 return;
613 break;
615 case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
616 default:
617 expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
618 "Unexpected SM-RP-OA ID (type=0x%02x)", id_type);
619 return;
623 static void dissect_sm_rp_ui_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
624 unsigned ie_len, proto_tree *tree, uint8_t msg_type)
626 tvbuff_t *ss_tvb;
628 /* Choose direction: RECV for MO, SENT for MT */
629 switch (msg_type) {
630 case OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST:
631 case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
632 case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
633 pinfo->p2p_dir = P2P_DIR_RECV;
634 break;
635 case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
636 case OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR:
637 case OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT:
638 pinfo->p2p_dir = P2P_DIR_SENT;
639 break;
640 default:
641 /* Just to be sure */
642 DISSECTOR_ASSERT(0);
643 break;
646 ss_tvb = tvb_new_subset_length(tvb, offset, ie_len);
647 call_dissector(gsm_sms_handle, ss_tvb, pinfo, tree);
650 static void dissect_imei_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
651 unsigned ie_len, proto_tree *tree)
653 tvbuff_t *ss_tvb = tvb_new_subset_length(tvb, offset-1, ie_len+1);
654 if(bssap_imei_handle)
655 call_dissector(bssap_imei_handle, ss_tvb, pinfo, tree);
658 static void dissect_an_apdu_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
659 unsigned ie_len, proto_tree *tree, proto_item *parent_ti)
661 tvbuff_t *ss_tvb = tvb_new_subset_length(tvb, offset+1, ie_len-1);
662 uint32_t an_type;
664 proto_tree_add_item_ret_uint(tree, hf_gsup_an_type, tvb, offset, 1, ENC_NA, &an_type);
665 proto_item_append_text(parent_ti, ": %s", val_to_str_const(an_type, gsup_msg_class_types, "unknown"));
667 switch (an_type) {
668 case OSMO_GSUP_AN_TYPE_BSSAP:
669 call_dissector(bssap_handle, ss_tvb, pinfo, tree);
670 break;
671 case OSMO_GSUP_AN_TYPE_RANAP:
672 call_dissector(ranap_handle, ss_tvb, pinfo, tree);
673 break;
674 default:
675 proto_tree_add_item(tree, hf_gsup_ie_payload, ss_tvb, 0, -1, ENC_NA);
676 break;
680 static void dissect_name_ie(tvbuff_t *tvb, packet_info *pinfo _U_, unsigned offset,
681 unsigned ie_len, proto_tree *tree, proto_item *parent_ti, uint8_t tag)
683 proto_item *ti;
685 if (show_name_as_text) {
686 uint8_t *str;
687 str = tvb_get_stringzpad(pinfo->pool, tvb, offset, ie_len, ENC_ASCII|ENC_NA);
688 proto_item_append_text(parent_ti, ": %s", (char *)str);
691 switch (tag) {
692 case OSMO_GSUP_SOURCE_NAME_IE:
693 ti = proto_tree_add_item(tree, hf_gsup_source_name, tvb, offset, ie_len, ENC_NA);
694 if (show_name_as_text) {
695 proto_item_set_hidden(ti);
696 proto_tree_add_item(tree, hf_gsup_source_name_text, tvb, offset, ie_len, ENC_ASCII);
698 break;
699 case OSMO_GSUP_DESTINATION_NAME_IE:
700 ti = proto_tree_add_item(tree, hf_gsup_destination_name, tvb, offset, ie_len, ENC_NA);
701 if (show_name_as_text) {
702 proto_item_set_hidden(ti);
703 proto_tree_add_item(tree, hf_gsup_destination_name_text, tvb, offset, ie_len, ENC_ASCII);
705 break;
710 static int
711 // NOLINTNEXTLINE(misc-no-recursion)
712 dissect_gsup_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree,
713 proto_item *gsup_ti, uint8_t msg_type)
715 int offset = base_offs;
717 while (offset - base_offs < length) {
718 uint8_t tag;
719 uint8_t len;
720 proto_item *ti;
721 proto_tree *att_tree;
722 const char *apn;
723 const char *str;
724 int apn_len;
725 uint32_t ui32;
726 uint8_t i;
727 tvbuff_t *subset_tvb;
729 tag = tvb_get_uint8(tvb, offset);
730 offset++;
732 len = tvb_get_uint8(tvb, offset);
733 offset++;
735 if (offset - base_offs + len > length) {
736 expert_add_info(pinfo, gsup_ti, &ei_gsup_ie_len_invalid);
737 return offset - 2;
740 att_tree = proto_tree_add_subtree_format(tree, tvb, offset-2, len+2, ett_gsup_ie, &ti,
741 "IE: %s",
742 val_to_str(tag, gsup_iei_types, "Unknown 0x%02x"));
743 proto_tree_add_item(att_tree, hf_gsup_iei, tvb, offset-2, 1, ENC_BIG_ENDIAN);
744 proto_tree_add_uint(att_tree, hf_gsup_ie_len, tvb, offset-1, 1, len);
746 increment_dissection_depth(pinfo);
747 switch (tag) {
748 /* Nested TLVs */
749 case OSMO_GSUP_AUTH_TUPLE_IE:
750 case OSMO_GSUP_PDP_INFO_IE:
751 dissect_gsup_tlvs(tvb, offset, len, pinfo, att_tree, gsup_ti, msg_type);
752 break;
753 /* Normal IEs */
754 case OSMO_GSUP_RAND_IE:
755 proto_tree_add_item(att_tree, hf_gsup_rand, tvb, offset, len, ENC_NA);
756 break;
757 case OSMO_GSUP_SRES_IE:
758 proto_tree_add_item(att_tree, hf_gsup_sres, tvb, offset, len, ENC_NA);
759 break;
760 case OSMO_GSUP_KC_IE:
761 proto_tree_add_item(att_tree, hf_gsup_kc, tvb, offset, len, ENC_NA);
762 break;
763 case OSMO_GSUP_IK_IE:
764 proto_tree_add_item(att_tree, hf_gsup_ik, tvb, offset, len, ENC_NA);
765 break;
766 case OSMO_GSUP_CK_IE:
767 proto_tree_add_item(att_tree, hf_gsup_ck, tvb, offset, len, ENC_NA);
768 break;
769 case OSMO_GSUP_AUTN_IE:
770 proto_tree_add_item(att_tree, hf_gsup_autn, tvb, offset, len, ENC_NA);
771 break;
772 case OSMO_GSUP_AUTS_IE:
773 proto_tree_add_item(att_tree, hf_gsup_auts, tvb, offset, len, ENC_NA);
774 break;
775 case OSMO_GSUP_RES_IE:
776 proto_tree_add_item(att_tree, hf_gsup_res, tvb, offset, len, ENC_NA);
777 break;
778 case OSMO_GSUP_CN_DOMAIN_IE:
779 proto_tree_add_item(att_tree, hf_gsup_cn_domain, tvb, offset, len, ENC_NA);
780 break;
781 case OSMO_GSUP_SUPPORTED_RAT_TYPES_IE:
782 for (i = 0; i < len; i++) {
783 proto_tree_add_item(att_tree, hf_gsup_supported_rat_type,
784 tvb, offset + i, 1, ENC_NA);
786 break;
787 case OSMO_GSUP_CURRENT_RAT_TYPE_IE:
788 proto_tree_add_item(att_tree, hf_gsup_current_rat_type, tvb, offset, len, ENC_NA);
789 break;
790 case OSMO_GSUP_CANCEL_TYPE_IE:
791 proto_tree_add_item(att_tree, hf_gsup_cancel_type, tvb, offset, len, ENC_NA);
792 break;
793 case OSMO_GSUP_IMSI_IE:
794 str = dissect_e212_imsi(tvb, pinfo, att_tree, offset, len, false);
795 proto_item_append_text(ti, ", %s", str);
796 proto_item_append_text(gsup_ti, ", IMSI: %s", str);
797 break;
798 case OSMO_GSUP_MSISDN_IE:
799 str = dissect_e164_msisdn(tvb, att_tree, offset+1, len-1, E164_ENC_BCD);
800 proto_item_append_text(ti, ", %s", str);
801 proto_item_append_text(gsup_ti, ", MSISDN: %s", str);
802 break;
803 case OSMO_GSUP_ACCESS_POINT_NAME_IE:
804 if (len == 1) {
805 uint8_t ch = tvb_get_uint8(tvb, offset);
806 proto_tree_add_item(att_tree, hf_gsup_ie_payload, tvb, offset, len, ENC_NA);
807 if (ch == '*')
808 proto_item_append_text(ti, ", '*' (Wildcard)");
809 } else {
810 char *name_out;
812 get_dns_name(tvb, offset, len, 0, &apn, &apn_len);
813 name_out = format_text(pinfo->pool, apn, apn_len);
814 proto_tree_add_string(att_tree, hf_gsup_apn, tvb, offset, len, name_out);
815 proto_item_append_text(ti, ", %s", name_out);
817 break;
818 case OSMO_GSUP_PDP_CONTEXT_ID_IE:
819 proto_tree_add_item(att_tree, hf_gsup_pdp_context_id, tvb, offset, len, ENC_NA);
820 break;
821 case OSMO_GSUP_CHARG_CHAR_IE:
822 proto_tree_add_item(att_tree, hf_gsup_charg_char, tvb, offset, len, ENC_ASCII);
823 break;
824 case OSMO_GSUP_PCO_IE:
825 switch (msg_type) {
826 case OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST:
827 /* PCO options as MS to network direction */
828 pinfo->link_dir = P2P_DIR_UL;
829 break;
830 case OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR:
831 case OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT:
832 /* PCO options as Network to MS direction: */
833 pinfo->link_dir = P2P_DIR_DL;
834 break;
835 default:
836 break;
838 subset_tvb = tvb_new_subset_length(tvb, offset, len);
839 de_sm_pco(subset_tvb, att_tree, pinfo, 0, len, NULL, 0);
840 break;
841 case OSMO_GSUP_CAUSE_IE:
842 proto_tree_add_item(att_tree, hf_gsup_cause, tvb, offset, len, ENC_NA);
843 break;
844 /* boolean flags: either they're present or not */
845 case OSMO_GSUP_PDP_INFO_COMPL_IE:
846 proto_tree_add_item(att_tree, hf_gsup_pdp_info_compl, tvb, offset, len, ENC_NA);
847 break;
848 case OSMO_GSUP_FREEZE_PTMSI_IE:
849 proto_tree_add_item(att_tree, hf_gsup_freeze_ptmsi, tvb, offset, len, ENC_NA);
850 break;
851 case OSMO_GSUP_SESSION_ID_IE:
852 proto_tree_add_item(att_tree, hf_gsup_session_id, tvb, offset, len, ENC_NA);
853 break;
854 case OSMO_GSUP_SESSION_STATE_IE:
855 proto_tree_add_item(att_tree, hf_gsup_session_state, tvb, offset, len, ENC_NA);
856 break;
857 case OSMO_GSUP_SS_INFO_IE:
858 dissect_ss_info_ie(tvb, pinfo, offset, len, att_tree);
859 break;
860 case OSMO_GSUP_SM_RP_MR_IE:
861 proto_tree_add_item(att_tree, hf_gsup_sm_rp_mr, tvb, offset, len, ENC_NA);
862 break;
863 case OSMO_GSUP_SM_RP_DA_IE:
864 dissect_sm_rp_da_ie(tvb, pinfo, offset, len, att_tree);
865 break;
866 case OSMO_GSUP_SM_RP_OA_IE:
867 dissect_sm_rp_oa_ie(tvb, pinfo, offset, len, att_tree);
868 break;
869 case OSMO_GSUP_SM_RP_UI_IE:
870 dissect_sm_rp_ui_ie(tvb, pinfo, offset, len, att_tree, msg_type);
871 break;
872 case OSMO_GSUP_SM_RP_CAUSE_IE:
873 proto_tree_add_item(att_tree, hf_gsup_sm_rp_cause, tvb, offset, len, ENC_NA);
874 break;
875 case OSMO_GSUP_SM_RP_MMS_IE:
876 proto_tree_add_item(att_tree, hf_gsup_sm_rp_mms, tvb, offset, len, ENC_NA);
877 break;
878 case OSMO_GSUP_SM_ALERT_RSN_IE:
879 proto_tree_add_item(att_tree, hf_gsup_sm_alert_rsn, tvb, offset, len, ENC_NA);
880 break;
881 case OSMO_GSUP_IMEI_IE:
882 dissect_imei_ie(tvb, pinfo, offset, len, att_tree);
883 break;
884 case OSMO_GSUP_IMEI_RESULT_IE:
885 proto_tree_add_item(att_tree, hf_gsup_imei_result, tvb, offset, len, ENC_NA);
886 break;
887 case OSMO_GSUP_NUM_VECTORS_REQ_IE:
888 proto_tree_add_item(att_tree, hf_gsup_num_vectors_req, tvb, offset, len, ENC_NA);
889 break;
890 case OSMO_GSUP_MESSAGE_CLASS_IE:
891 proto_tree_add_item_ret_uint(att_tree, hf_gsup_msg_class, tvb, offset, len, ENC_NA, &ui32);
892 proto_item_append_text(ti, ": %s", val_to_str_const(ui32, gsup_msg_class_types, "unknown"));
893 break;
894 case OSMO_GSUP_AN_APDU_IE:
895 dissect_an_apdu_ie(tvb, pinfo, offset, len, att_tree, ti);
896 break;
897 case OSMO_GSUP_SOURCE_NAME_IE:
898 case OSMO_GSUP_DESTINATION_NAME_IE:
899 dissect_name_ie(tvb, pinfo, offset, len, att_tree, ti, tag);
900 break;
901 case OSMO_GSUP_CAUSE_RR_IE:
902 de_rr_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
903 break;
904 case OSMO_GSUP_CAUSE_BSSAP_IE:
905 bssmap_dissect_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
906 break;
907 case OSMO_GSUP_CAUSE_SM_IE:
908 de_sm_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
909 break;
910 case OSMO_GSUP_PDP_ADDRESS_IE:
911 proto_tree_add_bits_item(att_tree, hf_gsup_spare_bits, tvb, (offset << 3), 4, ENC_BIG_ENDIAN);
912 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_type_org, tvb, offset, 1, ENC_BIG_ENDIAN);
913 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_type_nr, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
914 if (len > 2) {
915 switch (tvb_get_uint8(tvb, offset) & 0x0f) {
916 case 0x01: /* IETF */
917 switch (tvb_get_uint8(tvb, offset + 1)) {
918 case 0x21:
919 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v4, tvb, offset + 3, 4, ENC_BIG_ENDIAN);
920 break;
921 case 0x57:
922 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v6, tvb, offset + 3, 16, ENC_NA);
923 break;
924 case 0x8d:
925 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v4, tvb, offset + 3, 4, ENC_BIG_ENDIAN);
926 proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v6, tvb, offset + 7, 16, ENC_NA);
927 break;
928 default:
929 break;
931 break;
932 default:
933 break;
936 break;
937 case OSMO_GSUP_HLR_NUMBER_IE:
938 case OSMO_GSUP_PDP_QOS_IE:
939 default:
940 /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
941 proto_tree_add_item(att_tree, hf_gsup_ie_payload, tvb, offset, len, ENC_NA);
942 break;
944 decrement_dissection_depth(pinfo);
946 offset += len;
949 return offset;
952 static int
953 dissect_gsup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
955 int len, offset = 0;
956 proto_item *ti;
957 proto_tree *gsup_tree = NULL;
958 uint8_t msg_type;
959 const char *str;
962 len = tvb_reported_length(tvb);
963 msg_type = tvb_get_uint8(tvb, offset + 0);
965 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSUP");
967 col_clear(pinfo->cinfo, COL_INFO);
968 str = val_to_str(msg_type, gsup_msg_types, "Unknown GSUP Message Type 0x%02x");
969 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
971 ti = proto_tree_add_protocol_format(tree, proto_gsup, tvb, 0, len, "GSUP %s", str);
972 gsup_tree = proto_item_add_subtree(ti, ett_gsup);
974 proto_tree_add_item(gsup_tree, hf_gsup_msg_type,
975 tvb, offset, 1, ENC_BIG_ENDIAN);
976 offset++;
978 dissect_gsup_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
979 gsup_tree, ti, msg_type);
981 return tvb_captured_length(tvb);
984 void
985 proto_register_gsup(void)
987 static const value_string pdp_type[] = {
988 {0x00, "X.25"},
989 {0x01, "PPP"},
990 {0x02, "OSP:IHOSS"},
991 {0x21, "IPv4"},
992 {0x57, "IPv6"},
993 {0x8d, "IPv4v6"},
994 {0, NULL}
997 static const value_string pdp_org_type[] = {
998 {0, "ETSI"},
999 {1, "IETF"},
1000 {0, NULL}
1003 static hf_register_info hf[] = {
1004 { &hf_gsup_msg_type, { "Message Type", "gsup.msg_type",
1005 FT_UINT8, BASE_DEC, VALS(gsup_msg_types), 0, NULL, HFILL } },
1006 { &hf_gsup_iei, { "Information Element Identifier", "gsup.ie.iei",
1007 FT_UINT8, BASE_DEC, VALS(gsup_iei_types), 0, NULL, HFILL } },
1008 { &hf_gsup_ie_len, { "Information Element Length", "gsup.ie.len",
1009 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1010 { &hf_gsup_ie_payload, { "Information Element Payload", "gsup.ie.payload",
1011 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1013 { &hf_gsup_rand, { "RAND", "gsup.rand",
1014 FT_BYTES, BASE_NONE, NULL, 0, "Random Challenge", HFILL } },
1015 { &hf_gsup_sres, { "SRES", "gsup.sres",
1016 FT_BYTES, BASE_NONE, NULL, 0, "GSM/GPRS Authentication Result SRES Value", HFILL } },
1017 { &hf_gsup_kc, { "Kc", "gsup.kc",
1018 FT_BYTES, BASE_NONE, NULL, 0, "GSM/GPRS Ciphering Key", HFILL } },
1019 { &hf_gsup_ik, { "IK", "gsup.ik",
1020 FT_BYTES, BASE_NONE, NULL, 0, "UMTS Integrity Protection Key", HFILL } },
1021 { &hf_gsup_ck, { "CK", "gsup.ck",
1022 FT_BYTES, BASE_NONE, NULL, 0, "UMTS Ciphering Key", HFILL } },
1023 { &hf_gsup_autn, { "AUTN", "gsup.autn",
1024 FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Nonce", HFILL } },
1025 { &hf_gsup_auts, { "AUTN", "gsup.auts",
1026 FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Sync", HFILL } },
1027 { &hf_gsup_res, { "RES", "gsup.res",
1028 FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Result", HFILL } },
1030 { &hf_gsup_cn_domain, { "CN Domain Indicator", "gsup.cn_domain",
1031 FT_UINT8, BASE_DEC, VALS(gsup_cndomain_types), 0, NULL, HFILL } },
1032 { &hf_gsup_supported_rat_type, { "Supported RAT Type", "gsup.supported_rat_type",
1033 FT_UINT8, BASE_DEC, VALS(gsup_rat_types), 0, NULL, HFILL } },
1034 { &hf_gsup_current_rat_type, { "Current RAT Type", "gsup.current_rat_type",
1035 FT_UINT8, BASE_DEC, VALS(gsup_rat_types), 0, NULL, HFILL } },
1036 { &hf_gsup_cancel_type, { "Cancel Type", "gsup.cancel_type",
1037 FT_UINT8, BASE_DEC, VALS(gsup_cancel_types), 0, NULL, HFILL } },
1038 { &hf_gsup_pdp_info_compl, { "PDP Information Complete", "gsup.pdp_info_compl",
1039 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
1040 { &hf_gsup_freeze_ptmsi, { "Freeze P-TMSI", "gsup.freeze_ptmsi",
1041 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
1042 { &hf_gsup_apn, { "APN", "gsup.apn",
1043 FT_STRING, BASE_NONE, NULL, 0, "Access Point Name", HFILL } },
1044 { &hf_gsup_pdp_context_id, { "PDP Context ID", "gsup.pdp_context_id",
1045 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1046 { &hf_gsup_charg_char, { "Charging Character", "gsup.charg_char",
1047 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1048 { &hf_gsup_cause, { "Cause", "gsup.cause",
1049 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1050 { &hf_gsup_session_id, { "Session ID", "gsup.session_id",
1051 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
1052 { &hf_gsup_session_state, { "Session State", "gsup.session_state",
1053 FT_UINT8, BASE_DEC, VALS(gsup_session_states), 0, NULL, HFILL } },
1054 { &hf_gsup_sm_rp_mr, { "SM-RP-MR (Message Reference)", "gsup.sm_rp_mr",
1055 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1056 { &hf_gsup_sm_rp_da_id_type, { "Address Type", "gsup.sm_rp_da.addr_type",
1057 FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
1058 { &hf_gsup_sm_rp_oa_id_type, { "Address Type", "gsup.sm_rp_oa.addr_type",
1059 FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
1060 { &hf_gsup_sm_rp_cause, { "SM-RP Cause", "gsup.sm_rp.cause",
1061 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1062 { &hf_gsup_sm_rp_mms, { "More Messages to Send", "gsup.sm_rp.mms",
1063 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1064 { &hf_gsup_sm_alert_rsn, { "SM Alert Reason", "gsup.sm_alert_rsn",
1065 FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_alert_rsn_types), 0, NULL, HFILL } },
1066 { &hf_gsup_imei_result, { "IMEI Check Result", "gsup.imei_check_res",
1067 FT_UINT8, BASE_DEC, VALS(gsup_imei_result_types), 0, NULL, HFILL } },
1068 { &hf_gsup_num_vectors_req, { "Number of Vectors Requested", "gsup.num_vectors_req",
1069 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1070 { &hf_gsup_msg_class, { "Message Class", "gsup.msg_class",
1071 FT_UINT8, BASE_DEC, VALS(gsup_msg_class_types), 0, NULL, HFILL } },
1072 { &hf_gsup_an_type, { "Access Network Type", "gsup.an_type",
1073 FT_UINT8, BASE_DEC, VALS(gsup_an_type_vals), 0, NULL, HFILL } },
1074 { &hf_gsup_source_name, { "Source Name", "gsup.source_name",
1075 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1076 { &hf_gsup_source_name_text, { "Source Name (Text)", "gsup.source_name.text",
1077 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1078 { &hf_gsup_destination_name, { "Destination Name", "gsup.dest_name",
1079 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1080 { &hf_gsup_destination_name_text, { "Destination Name (Text)", "gsup.dest_name.text",
1081 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1082 { &hf_gsup_spare_bits, { "Spare bit(s)", "gsup.spare_bits",
1083 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1084 { &hf_gsup_pdp_addr_type_org, { "PDP organization", "gsup.pdp_organization",
1085 FT_UINT8, BASE_DEC, VALS(pdp_org_type), 0x0F, NULL, HFILL }},
1086 { &hf_gsup_pdp_addr_type_nr, { "PDP type", "gsup.pdp_type",
1087 FT_UINT8, BASE_DEC, VALS(pdp_type), 0x0, NULL, HFILL }},
1088 { &hf_gsup_pdp_addr_v4, { "PDP address", "gsup.pdp_address.ipv4",
1089 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1090 { &hf_gsup_pdp_addr_v6, { "PDP address", "gsup.pdp_address.ipv6",
1091 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1093 static int *ett[] = {
1094 &ett_gsup,
1095 &ett_gsup_ie,
1098 expert_module_t *expert_gsup;
1099 module_t *module_gsup;
1101 static ei_register_info ei[] = {
1102 { &ei_sm_rp_da_invalid,
1103 { "gsup.sm_rp_da.invalid", PI_PROTOCOL, PI_ERROR,
1104 "Malformed SM-RP-DA IE", EXPFILL } },
1105 { &ei_sm_rp_oa_invalid,
1106 { "gsup.sm_rp_oa.invalid", PI_PROTOCOL, PI_ERROR,
1107 "Malformed SM-RP-OA IE", EXPFILL } },
1108 { &ei_gsup_ie_len_invalid,
1109 { "gsup.ie.len.invalid", PI_PROTOCOL, PI_ERROR,
1110 "Invalid Information Element Length", EXPFILL } },
1113 proto_gsup = proto_register_protocol("Osmocom General Subscriber Update Protocol", "GSUP", "gsup");
1114 proto_register_field_array(proto_gsup, hf, array_length(hf));
1115 proto_register_subtree_array(ett, array_length(ett));
1117 gsup_handle = register_dissector("gsup", dissect_gsup, proto_gsup);
1119 expert_gsup = expert_register_protocol(proto_gsup);
1120 expert_register_field_array(expert_gsup, ei, array_length(ei));
1122 module_gsup = prefs_register_protocol(proto_gsup, NULL);
1123 prefs_register_bool_preference(module_gsup,
1124 "show_name_as_text",
1125 "Show Names as text",
1126 "Show GSUP Source/Destination names as text in the Packet Details pane",
1127 &show_name_as_text);
1130 void
1131 proto_reg_handoff_gsup(void)
1133 dissector_add_uint_with_preference("ipa.osmo.protocol", IPAC_PROTO_EXT_GSUP, gsup_handle);
1134 gsm_map_handle = find_dissector_add_dependency("gsm_map", proto_gsup);
1135 gsm_sms_handle = find_dissector_add_dependency("gsm_sms", proto_gsup);
1136 bssap_imei_handle = find_dissector_add_dependency("bssap.imei", proto_gsup);
1137 bssap_handle = find_dissector_add_dependency("bssap", proto_gsup);
1138 ranap_handle = find_dissector_add_dependency("ranap", proto_gsup);
1142 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1144 * Local variables:
1145 * c-basic-offset: 8
1146 * tab-width: 8
1147 * indent-tabs-mode: t
1148 * End:
1150 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1151 * :indentSize=8:tabSize=8:noTabs=false: