Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-gsm_gsup.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-gsm_gsup.c
2
 * Dissector for Osmocom Generic Subscriber Update Protocol (GSUP)
3
 *
4
 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
5
 * Contributions by sysmocom - s.f.m.c. GmbH
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
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.
15
 *
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.
20
 *
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.
24
 */
25
26
#include "config.h"
27
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>
33
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"
41
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.
46
 *
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
49
 */
50
51
/***********************************************************************
52
 * GSUP Protocol Definitions, see libosmocore/include/gsm/gsup.h
53
 ***********************************************************************/
54
55
#define OSMO_GSUP_PORT 4222
56
14
#define IPAC_PROTO_EXT_GSUP 0x05
57
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
64
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,
106
107
  OSMO_GSUP_IMEI_IE     = 0x50,
108
  OSMO_GSUP_IMEI_RESULT_IE    = 0x51,
109
  OSMO_GSUP_NUM_VECTORS_REQ_IE    = 0x52,
110
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,
118
};
119
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,
125
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,
129
130
  OSMO_GSUP_MSGT_AUTH_FAIL_REPORT   = 0x0b,
131
132
  OSMO_GSUP_MSGT_PURGE_MS_REQUEST   = 0x0c,
133
  OSMO_GSUP_MSGT_PURGE_MS_ERROR   = 0x0d,
134
  OSMO_GSUP_MSGT_PURGE_MS_RESULT    = 0x0e,
135
136
  OSMO_GSUP_MSGT_INSERT_DATA_REQUEST  = 0x10,
137
  OSMO_GSUP_MSGT_INSERT_DATA_ERROR  = 0x11,
138
  OSMO_GSUP_MSGT_INSERT_DATA_RESULT = 0x12,
139
140
  OSMO_GSUP_MSGT_DELETE_DATA_REQUEST  = 0x14,
141
  OSMO_GSUP_MSGT_DELETE_DATA_ERROR  = 0x15,
142
  OSMO_GSUP_MSGT_DELETE_DATA_RESULT = 0x16,
143
144
  OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST  = 0x1c,
145
  OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR  = 0x1d,
146
  OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT = 0x1e,
147
148
  OSMO_GSUP_MSGT_PROC_SS_REQUEST    = 0x20,
149
  OSMO_GSUP_MSGT_PROC_SS_ERROR    = 0x21,
150
  OSMO_GSUP_MSGT_PROC_SS_RESULT   = 0x22,
151
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,
155
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,
159
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,
163
164
  OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST = 0x30,
165
  OSMO_GSUP_MSGT_CHECK_IMEI_ERROR   = 0x31,
166
  OSMO_GSUP_MSGT_CHECK_IMEI_RESULT  = 0x32,
167
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,
171
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,
175
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,
179
180
  OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST  = 0x40,
181
  OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST  = 0x44,
182
183
  OSMO_GSUP_MSGT_E_CLOSE          = 0x47,
184
  OSMO_GSUP_MSGT_E_ABORT          = 0x4b,
185
186
  OSMO_GSUP_MSGT_E_ROUTING_ERROR        = 0x4e,
187
188
  OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST      = 0x50,
189
  OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR      = 0x51,
190
  OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT     = 0x52,
191
};
192
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)
196
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,
202
};
203
204
enum osmo_gsup_cancel_type {
205
  OSMO_GSUP_CANCEL_TYPE_UPDATE    = 0,
206
  OSMO_GSUP_CANCEL_TYPE_WITHDRAW    = 1,
207
};
208
209
enum osmo_gsup_cn_domain {
210
  OSMO_GSUP_CN_DOMAIN_PS      = 1,
211
  OSMO_GSUP_CN_DOMAIN_CS      = 2,
212
};
213
214
enum osmo_gsup_imei_result {
215
  OSMO_GSUP_IMEI_RESULT_ACK   = 0,
216
  OSMO_GSUP_IMEI_RESULT_NACK    = 1,
217
};
218
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,
224
};
225
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,
234
};
235
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,
241
};
242
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,
246
};
247
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,
254
};
255
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,
260
};
261
262
/***********************************************************************
263
 * Wireshark Dissector Implementation
264
 ***********************************************************************/
265
266
void proto_register_gsup(void);
267
void proto_reg_handoff_gsup(void);
268
269
static int proto_gsup;
270
271
/* show GSUP source/destination names as text (true) or only binary (false) */
272
static bool show_name_as_text = true;
273
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;
317
318
static int ett_gsup;
319
static int ett_gsup_ie;
320
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;
324
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;
331
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 }
380
};
381
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 }
435
};
436
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 }
443
};
444
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 }
449
};
450
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 }
455
};
456
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 }
463
};
464
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 }
472
};
473
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 }
479
};
480
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 }
485
};
486
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 }
494
};
495
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 }
500
};
501
502
503
static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, unsigned len, proto_tree *tree)
504
4
{
505
4
  unsigned saved_offset;
506
4
  int8_t appclass;
507
4
  bool pc;
508
4
  bool ind = false;
509
4
  uint32_t component_len = 0;
510
4
  uint32_t header_end_offset;
511
4
  uint32_t header_len;
512
4
  asn1_ctx_t asn1_ctx;
513
4
  tvbuff_t *ss_tvb = NULL;
514
4
  static int comp_type_tag;
515
516
4
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
517
4
  saved_offset = offset;
518
4
  col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
519
4
  col_set_fence(pinfo->cinfo, COL_PROTOCOL);
520
19
  while (len > (offset - saved_offset)) {
521
    /* get the length of the component. there can be multiple components in one message */
522
15
    header_end_offset = get_ber_identifier(tvb, offset, &appclass, &pc, &comp_type_tag);
523
15
    header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind);
524
15
    header_len = header_end_offset -offset;
525
15
    component_len += header_len;
526
527
15
    ss_tvb = tvb_new_subset_length(tvb, offset, component_len);
528
15
    col_append_str(pinfo->cinfo, COL_INFO, "(GSM MAP) ");
529
15
    col_set_fence(pinfo->cinfo, COL_INFO);
530
15
    call_dissector(gsm_map_handle, ss_tvb, pinfo, tree);
531
15
    offset += component_len;
532
15
  }
533
4
}
534
535
static void dissect_sm_rp_da_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
536
        unsigned ie_len, proto_tree *tree)
537
2
{
538
2
  tvbuff_t *addr_tvb;
539
2
  proto_item *ti;
540
2
  uint8_t id_type;
541
542
  /* Identity type is mandatory */
543
2
  if (ie_len < 1) {
544
0
    expert_add_info_format(pinfo, NULL, &ei_sm_rp_da_invalid,
545
0
      "Missing mandatory SM-RP-DA ID type (IE len < 1)");
546
0
    return;
547
0
  }
548
549
  /* Parse ID type */
550
2
  ti = proto_tree_add_item(tree, hf_gsup_sm_rp_da_id_type, tvb, offset, 1, ENC_NA);
551
2
  id_type = tvb_get_uint8(tvb, offset);
552
553
2
  switch (id_type) {
554
0
  case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:
555
0
    dissect_e212_imsi(tvb, pinfo, tree,
556
0
      offset + 1, ie_len - 1, false);
557
0
    break;
558
0
  case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
559
0
  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
560
0
    addr_tvb = tvb_new_subset_length(tvb, offset + 1, ie_len - 1);
561
0
    dissect_gsm_map_msisdn(addr_tvb, pinfo, tree);
562
0
    break;
563
564
  /* Special case for noSM-RP-DA and noSM-RP-OA */
565
0
  case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
566
0
    if (ie_len > 1) {
567
0
      expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
568
0
        "Unexpected ID length=%u for noSM-RP-DA", ie_len - 1);
569
0
      return;
570
0
    }
571
0
    break;
572
573
0
  case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
574
2
  default:
575
2
    expert_add_info_format(pinfo, ti, &ei_sm_rp_da_invalid,
576
2
      "Unexpected SM-RP-DA ID (type=0x%02x)", id_type);
577
2
    return;
578
2
  }
579
2
}
580
581
static void dissect_sm_rp_oa_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
582
        unsigned ie_len, proto_tree *tree)
583
3
{
584
3
  tvbuff_t *addr_tvb;
585
3
  proto_item *ti;
586
3
  uint8_t id_type;
587
588
  /* Identity type is mandatory */
589
3
  if (ie_len < 1) {
590
2
    expert_add_info_format(pinfo, NULL, &ei_sm_rp_oa_invalid,
591
2
      "Missing mandatory SM-RP-OA ID type (IE len < 1)");
592
2
    return;
593
2
  }
594
595
  /* Parse ID type */
596
1
  ti = proto_tree_add_item(tree, hf_gsup_sm_rp_oa_id_type, tvb, offset, 1, ENC_NA);
597
1
  id_type = tvb_get_uint8(tvb, offset);
598
599
1
  switch (id_type) {
600
0
  case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:
601
0
  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:
602
0
    addr_tvb = tvb_new_subset_length(tvb, offset + 1, ie_len - 1);
603
0
    dissect_gsm_map_msisdn(addr_tvb, pinfo, tree);
604
0
    break;
605
606
  /* Special case for noSM-RP-DA and noSM-RP-OA */
607
0
  case OSMO_GSUP_SMS_SM_RP_ODA_NULL:
608
0
    if (ie_len > 1) {
609
0
      expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
610
0
        "Unexpected ID length=%u for noSM-RP-OA", ie_len - 1);
611
0
      return;
612
0
    }
613
0
    break;
614
615
1
  case OSMO_GSUP_SMS_SM_RP_ODA_NONE:
616
1
  default:
617
1
    expert_add_info_format(pinfo, ti, &ei_sm_rp_oa_invalid,
618
1
      "Unexpected SM-RP-OA ID (type=0x%02x)", id_type);
619
1
    return;
620
1
  }
621
1
}
622
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)
625
123
{
626
123
  tvbuff_t *ss_tvb;
627
628
  /* Choose direction: RECV for MO, SENT for MT */
629
123
  switch (msg_type) {
630
0
  case OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST:
631
0
  case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
632
121
  case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
633
121
    pinfo->p2p_dir = P2P_DIR_RECV;
634
121
    break;
635
0
  case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
636
0
  case OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR:
637
0
  case OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT:
638
0
    pinfo->p2p_dir = P2P_DIR_SENT;
639
0
    break;
640
2
  default:
641
    /* Just to be sure */
642
2
    DISSECTOR_ASSERT(0);
643
2
    break;
644
123
  }
645
646
121
  ss_tvb = tvb_new_subset_length(tvb, offset, ie_len);
647
121
  call_dissector(gsm_sms_handle, ss_tvb, pinfo, tree);
648
121
}
649
650
static void dissect_imei_ie(tvbuff_t *tvb, packet_info *pinfo, unsigned offset,
651
          unsigned ie_len, proto_tree *tree)
652
4
{
653
4
  tvbuff_t *ss_tvb = tvb_new_subset_length(tvb, offset-1, ie_len+1);
654
4
  if(bssap_imei_handle)
655
4
    call_dissector(bssap_imei_handle, ss_tvb, pinfo, tree);
656
4
}
657
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)
660
11
{
661
11
  tvbuff_t *ss_tvb = tvb_new_subset_length(tvb, offset+1, ie_len-1);
662
11
  uint32_t an_type;
663
664
11
  proto_tree_add_item_ret_uint(tree, hf_gsup_an_type, tvb, offset, 1, ENC_NA, &an_type);
665
11
  proto_item_append_text(parent_ti, ": %s", val_to_str_const(an_type, gsup_msg_class_types, "unknown"));
666
667
11
  switch (an_type) {
668
0
  case OSMO_GSUP_AN_TYPE_BSSAP:
669
0
    call_dissector(bssap_handle, ss_tvb, pinfo, tree);
670
0
    break;
671
2
  case OSMO_GSUP_AN_TYPE_RANAP:
672
2
    call_dissector(ranap_handle, ss_tvb, pinfo, tree);
673
2
    break;
674
9
  default:
675
9
    proto_tree_add_item(tree, hf_gsup_ie_payload, ss_tvb, 0, -1, ENC_NA);
676
9
    break;
677
11
  }
678
11
}
679
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)
682
19
{
683
19
  proto_item *ti;
684
685
19
  if (show_name_as_text) {
686
19
    uint8_t *str;
687
19
    str = tvb_get_stringzpad(pinfo->pool, tvb, offset, ie_len,  ENC_ASCII|ENC_NA);
688
19
    proto_item_append_text(parent_ti, ": %s", (char *)str);
689
19
  }
690
691
19
  switch (tag) {
692
3
  case OSMO_GSUP_SOURCE_NAME_IE:
693
3
    ti = proto_tree_add_item(tree, hf_gsup_source_name, tvb, offset, ie_len, ENC_NA);
694
3
    if (show_name_as_text) {
695
3
      proto_item_set_hidden(ti);
696
3
      proto_tree_add_item(tree, hf_gsup_source_name_text, tvb, offset, ie_len, ENC_ASCII);
697
3
    }
698
3
    break;
699
13
  case OSMO_GSUP_DESTINATION_NAME_IE:
700
13
    ti = proto_tree_add_item(tree, hf_gsup_destination_name, tvb, offset, ie_len, ENC_NA);
701
13
    if (show_name_as_text) {
702
13
      proto_item_set_hidden(ti);
703
13
      proto_tree_add_item(tree, hf_gsup_destination_name_text, tvb, offset, ie_len, ENC_ASCII);
704
13
    }
705
13
    break;
706
19
  }
707
19
}
708
709
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)
714
357
{
715
357
  int offset = base_offs;
716
717
3.17k
  while (offset - base_offs < length) {
718
3.16k
    uint8_t tag;
719
3.16k
    uint8_t len;
720
3.16k
    proto_item *ti;
721
3.16k
    proto_tree *att_tree;
722
3.16k
    const char *apn;
723
3.16k
    const char *str;
724
3.16k
    int apn_len;
725
3.16k
    uint32_t ui32;
726
3.16k
    uint8_t i;
727
3.16k
    tvbuff_t *subset_tvb;
728
729
3.16k
    tag = tvb_get_uint8(tvb, offset);
730
3.16k
    offset++;
731
732
3.16k
    len = tvb_get_uint8(tvb, offset);
733
3.16k
    offset++;
734
735
3.16k
    if (offset - base_offs + len > length) {
736
196
      expert_add_info(pinfo, gsup_ti, &ei_gsup_ie_len_invalid);
737
196
      return offset - 2;
738
196
    }
739
740
2.97k
    att_tree = proto_tree_add_subtree_format(tree, tvb, offset-2, len+2, ett_gsup_ie, &ti,
741
2.97k
            "IE: %s",
742
2.97k
            val_to_str(tag, gsup_iei_types, "Unknown 0x%02x"));
743
2.97k
    proto_tree_add_item(att_tree, hf_gsup_iei, tvb, offset-2, 1, ENC_BIG_ENDIAN);
744
2.97k
    proto_tree_add_uint(att_tree, hf_gsup_ie_len, tvb, offset-1, 1, len);
745
746
2.97k
    increment_dissection_depth(pinfo);
747
2.97k
    switch (tag) {
748
    /* Nested TLVs */
749
43
    case OSMO_GSUP_AUTH_TUPLE_IE:
750
203
    case OSMO_GSUP_PDP_INFO_IE:
751
203
      dissect_gsup_tlvs(tvb, offset, len, pinfo, att_tree, gsup_ti, msg_type);
752
203
      break;
753
    /* Normal IEs */
754
13
    case OSMO_GSUP_RAND_IE:
755
13
      proto_tree_add_item(att_tree, hf_gsup_rand, tvb, offset, len, ENC_NA);
756
13
      break;
757
4
    case OSMO_GSUP_SRES_IE:
758
4
      proto_tree_add_item(att_tree, hf_gsup_sres, tvb, offset, len, ENC_NA);
759
4
      break;
760
9
    case OSMO_GSUP_KC_IE:
761
9
      proto_tree_add_item(att_tree, hf_gsup_kc, tvb, offset, len, ENC_NA);
762
9
      break;
763
13
    case OSMO_GSUP_IK_IE:
764
13
      proto_tree_add_item(att_tree, hf_gsup_ik, tvb, offset, len, ENC_NA);
765
13
      break;
766
9
    case OSMO_GSUP_CK_IE:
767
9
      proto_tree_add_item(att_tree, hf_gsup_ck, tvb, offset, len, ENC_NA);
768
9
      break;
769
9
    case OSMO_GSUP_AUTN_IE:
770
9
      proto_tree_add_item(att_tree, hf_gsup_autn, tvb, offset, len, ENC_NA);
771
9
      break;
772
6
    case OSMO_GSUP_AUTS_IE:
773
6
      proto_tree_add_item(att_tree, hf_gsup_auts, tvb, offset, len, ENC_NA);
774
6
      break;
775
5
    case OSMO_GSUP_RES_IE:
776
5
      proto_tree_add_item(att_tree, hf_gsup_res, tvb, offset, len, ENC_NA);
777
5
      break;
778
9
    case OSMO_GSUP_CN_DOMAIN_IE:
779
9
      proto_tree_add_item(att_tree, hf_gsup_cn_domain, tvb, offset, len, ENC_NA);
780
9
      break;
781
3
    case OSMO_GSUP_SUPPORTED_RAT_TYPES_IE:
782
54
      for (i = 0; i < len; i++) {
783
51
        proto_tree_add_item(att_tree, hf_gsup_supported_rat_type,
784
51
                tvb, offset + i, 1, ENC_NA);
785
51
      }
786
3
      break;
787
3
    case OSMO_GSUP_CURRENT_RAT_TYPE_IE:
788
3
      proto_tree_add_item(att_tree, hf_gsup_current_rat_type, tvb, offset, len, ENC_NA);
789
3
      break;
790
25
    case OSMO_GSUP_CANCEL_TYPE_IE:
791
25
      proto_tree_add_item(att_tree, hf_gsup_cancel_type, tvb, offset, len, ENC_NA);
792
25
      break;
793
466
    case OSMO_GSUP_IMSI_IE:
794
466
      str = dissect_e212_imsi(tvb, pinfo, att_tree, offset, len, false);
795
466
      proto_item_append_text(ti, ", %s", str);
796
466
      proto_item_append_text(gsup_ti, ", IMSI: %s", str);
797
466
      break;
798
194
    case OSMO_GSUP_MSISDN_IE:
799
194
      str = dissect_e164_msisdn(tvb, att_tree, offset+1, len-1, E164_ENC_BCD);
800
194
      proto_item_append_text(ti, ", %s", str);
801
194
      proto_item_append_text(gsup_ti, ", MSISDN: %s", str);
802
194
      break;
803
9
    case OSMO_GSUP_ACCESS_POINT_NAME_IE:
804
9
      if (len == 1) {
805
0
        uint8_t ch = tvb_get_uint8(tvb, offset);
806
0
        proto_tree_add_item(att_tree, hf_gsup_ie_payload, tvb, offset, len, ENC_NA);
807
0
        if (ch == '*')
808
0
          proto_item_append_text(ti, ", '*' (Wildcard)");
809
9
      } else {
810
9
                                char *name_out;
811
812
9
        get_dns_name(tvb, offset, len, 0, &apn, &apn_len);
813
9
        name_out = format_text(pinfo->pool, apn, apn_len);
814
9
        proto_tree_add_string(att_tree, hf_gsup_apn, tvb, offset, len, name_out);
815
9
        proto_item_append_text(ti, ", %s", name_out);
816
9
      }
817
9
      break;
818
8
    case OSMO_GSUP_PDP_CONTEXT_ID_IE:
819
8
      proto_tree_add_item(att_tree, hf_gsup_pdp_context_id, tvb, offset, len, ENC_NA);
820
8
      break;
821
4
    case OSMO_GSUP_CHARG_CHAR_IE:
822
4
      proto_tree_add_item(att_tree, hf_gsup_charg_char, tvb, offset, len, ENC_ASCII);
823
4
      break;
824
8
    case OSMO_GSUP_PCO_IE:
825
8
      switch (msg_type) {
826
0
      case OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST:
827
        /* PCO options as MS to network direction */
828
0
        pinfo->link_dir = P2P_DIR_UL;
829
0
        break;
830
0
      case OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR:
831
0
      case OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT:
832
        /* PCO options as Network to MS direction: */
833
0
        pinfo->link_dir = P2P_DIR_DL;
834
0
        break;
835
8
      default:
836
8
        break;
837
8
      }
838
8
      subset_tvb = tvb_new_subset_length(tvb, offset, len);
839
8
      de_sm_pco(subset_tvb, att_tree, pinfo, 0, len, NULL, 0);
840
8
      break;
841
228
    case OSMO_GSUP_CAUSE_IE:
842
228
      proto_tree_add_item(att_tree, hf_gsup_cause, tvb, offset, len, ENC_NA);
843
228
      break;
844
    /* boolean flags: either they're present or not */
845
56
    case OSMO_GSUP_PDP_INFO_COMPL_IE:
846
56
      proto_tree_add_item(att_tree, hf_gsup_pdp_info_compl, tvb, offset, len, ENC_NA);
847
56
      break;
848
32
    case OSMO_GSUP_FREEZE_PTMSI_IE:
849
32
      proto_tree_add_item(att_tree, hf_gsup_freeze_ptmsi, tvb, offset, len, ENC_NA);
850
32
      break;
851
9
    case OSMO_GSUP_SESSION_ID_IE:
852
9
      proto_tree_add_item(att_tree, hf_gsup_session_id, tvb, offset, len, ENC_NA);
853
9
      break;
854
4
    case OSMO_GSUP_SESSION_STATE_IE:
855
4
      proto_tree_add_item(att_tree, hf_gsup_session_state, tvb, offset, len, ENC_NA);
856
4
      break;
857
4
    case OSMO_GSUP_SS_INFO_IE:
858
4
      dissect_ss_info_ie(tvb, pinfo, offset, len, att_tree);
859
4
      break;
860
7
    case OSMO_GSUP_SM_RP_MR_IE:
861
7
      proto_tree_add_item(att_tree, hf_gsup_sm_rp_mr, tvb, offset, len, ENC_NA);
862
7
      break;
863
2
    case OSMO_GSUP_SM_RP_DA_IE:
864
2
      dissect_sm_rp_da_ie(tvb, pinfo, offset, len, att_tree);
865
2
      break;
866
3
    case OSMO_GSUP_SM_RP_OA_IE:
867
3
      dissect_sm_rp_oa_ie(tvb, pinfo, offset, len, att_tree);
868
3
      break;
869
123
    case OSMO_GSUP_SM_RP_UI_IE:
870
123
      dissect_sm_rp_ui_ie(tvb, pinfo, offset, len, att_tree, msg_type);
871
123
      break;
872
14
    case OSMO_GSUP_SM_RP_CAUSE_IE:
873
14
      proto_tree_add_item(att_tree, hf_gsup_sm_rp_cause, tvb, offset, len, ENC_NA);
874
14
      break;
875
16
    case OSMO_GSUP_SM_RP_MMS_IE:
876
16
      proto_tree_add_item(att_tree, hf_gsup_sm_rp_mms, tvb, offset, len, ENC_NA);
877
16
      break;
878
3
    case OSMO_GSUP_SM_ALERT_RSN_IE:
879
3
      proto_tree_add_item(att_tree, hf_gsup_sm_alert_rsn, tvb, offset, len, ENC_NA);
880
3
      break;
881
4
    case OSMO_GSUP_IMEI_IE:
882
4
      dissect_imei_ie(tvb, pinfo, offset, len, att_tree);
883
4
      break;
884
4
    case OSMO_GSUP_IMEI_RESULT_IE:
885
4
      proto_tree_add_item(att_tree, hf_gsup_imei_result, tvb, offset, len, ENC_NA);
886
4
      break;
887
4
    case OSMO_GSUP_NUM_VECTORS_REQ_IE:
888
4
      proto_tree_add_item(att_tree, hf_gsup_num_vectors_req, tvb, offset, len, ENC_NA);
889
4
      break;
890
32
    case OSMO_GSUP_MESSAGE_CLASS_IE:
891
32
      proto_tree_add_item_ret_uint(att_tree, hf_gsup_msg_class, tvb, offset, len, ENC_NA, &ui32);
892
32
      proto_item_append_text(ti, ": %s", val_to_str_const(ui32, gsup_msg_class_types, "unknown"));
893
32
      break;
894
11
    case OSMO_GSUP_AN_APDU_IE:
895
11
      dissect_an_apdu_ie(tvb, pinfo, offset, len, att_tree, ti);
896
11
      break;
897
4
    case OSMO_GSUP_SOURCE_NAME_IE:
898
19
    case OSMO_GSUP_DESTINATION_NAME_IE:
899
19
      dissect_name_ie(tvb, pinfo, offset, len, att_tree, ti, tag);
900
19
      break;
901
15
    case OSMO_GSUP_CAUSE_RR_IE:
902
15
      de_rr_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
903
15
      break;
904
2
    case OSMO_GSUP_CAUSE_BSSAP_IE:
905
2
      bssmap_dissect_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
906
2
      break;
907
6
    case OSMO_GSUP_CAUSE_SM_IE:
908
6
      de_sm_cause(tvb, att_tree, pinfo, offset, len, NULL, 0);
909
6
      break;
910
14
    case OSMO_GSUP_PDP_ADDRESS_IE:
911
14
      proto_tree_add_bits_item(att_tree, hf_gsup_spare_bits, tvb, (offset << 3), 4, ENC_BIG_ENDIAN);
912
14
      proto_tree_add_item(att_tree, hf_gsup_pdp_addr_type_org, tvb, offset, 1, ENC_BIG_ENDIAN);
913
14
      proto_tree_add_item(att_tree, hf_gsup_pdp_addr_type_nr, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
914
14
      if (len > 2) {
915
10
        switch (tvb_get_uint8(tvb, offset) & 0x0f) {
916
4
        case 0x01: /* IETF */
917
4
          switch (tvb_get_uint8(tvb, offset + 1)) {
918
0
          case 0x21:
919
0
            proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v4, tvb, offset + 3, 4, ENC_BIG_ENDIAN);
920
0
            break;
921
0
          case 0x57:
922
0
            proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v6, tvb, offset + 3, 16, ENC_NA);
923
0
            break;
924
0
          case 0x8d:
925
0
            proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v4, tvb, offset + 3, 4, ENC_BIG_ENDIAN);
926
0
            proto_tree_add_item(att_tree, hf_gsup_pdp_addr_v6, tvb, offset + 7, 16, ENC_NA);
927
0
            break;
928
4
          default:
929
4
            break;
930
4
          }
931
4
          break;
932
6
        default:
933
6
          break;
934
10
        }
935
10
      }
936
14
      break;
937
14
    case OSMO_GSUP_HLR_NUMBER_IE:
938
8
    case OSMO_GSUP_PDP_QOS_IE:
939
1.33k
    default:
940
      /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
941
1.33k
      proto_tree_add_item(att_tree, hf_gsup_ie_payload, tvb, offset, len, ENC_NA);
942
1.33k
      break;
943
2.97k
    }
944
2.81k
    decrement_dissection_depth(pinfo);
945
946
2.81k
    offset += len;
947
2.81k
  }
948
949
6
  return offset;
950
357
}
951
952
static int
953
dissect_gsup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
954
154
{
955
154
  int len, offset = 0;
956
154
  proto_item *ti;
957
154
  proto_tree *gsup_tree = NULL;
958
154
  uint8_t msg_type;
959
154
  const char *str;
960
961
962
154
  len = tvb_reported_length(tvb);
963
154
  msg_type = tvb_get_uint8(tvb, offset + 0);
964
965
154
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSUP");
966
967
154
  col_clear(pinfo->cinfo, COL_INFO);
968
154
  str = val_to_str(msg_type, gsup_msg_types, "Unknown GSUP Message Type 0x%02x");
969
154
  col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
970
971
154
  ti = proto_tree_add_protocol_format(tree, proto_gsup, tvb, 0, len, "GSUP %s", str);
972
154
  gsup_tree = proto_item_add_subtree(ti, ett_gsup);
973
974
154
  proto_tree_add_item(gsup_tree, hf_gsup_msg_type,
975
154
          tvb, offset, 1, ENC_BIG_ENDIAN);
976
154
  offset++;
977
978
154
  dissect_gsup_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
979
154
        gsup_tree, ti, msg_type);
980
981
154
  return tvb_captured_length(tvb);
982
154
}
983
984
void
985
proto_register_gsup(void)
986
14
{
987
14
  static const value_string pdp_type[] = {
988
14
    {0x00, "X.25"},
989
14
    {0x01, "PPP"},
990
14
    {0x02, "OSP:IHOSS"},
991
14
    {0x21, "IPv4"},
992
14
    {0x57, "IPv6"},
993
14
    {0x8d, "IPv4v6"},
994
14
    {0, NULL}
995
14
  };
996
997
14
  static const value_string pdp_org_type[] = {
998
14
    {0, "ETSI"},
999
14
    {1, "IETF"},
1000
14
    {0, NULL}
1001
14
  };
1002
1003
14
  static hf_register_info hf[] = {
1004
14
    { &hf_gsup_msg_type, { "Message Type", "gsup.msg_type",
1005
14
      FT_UINT8, BASE_DEC, VALS(gsup_msg_types), 0, NULL, HFILL } },
1006
14
    { &hf_gsup_iei, { "Information Element Identifier", "gsup.ie.iei",
1007
14
      FT_UINT8, BASE_DEC, VALS(gsup_iei_types), 0, NULL, HFILL } },
1008
14
    { &hf_gsup_ie_len, { "Information Element Length", "gsup.ie.len",
1009
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1010
14
    { &hf_gsup_ie_payload, { "Information Element Payload", "gsup.ie.payload",
1011
14
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1012
1013
14
    { &hf_gsup_rand, { "RAND", "gsup.rand",
1014
14
      FT_BYTES, BASE_NONE, NULL, 0, "Random Challenge", HFILL } },
1015
14
    { &hf_gsup_sres, { "SRES", "gsup.sres",
1016
14
      FT_BYTES, BASE_NONE, NULL, 0, "GSM/GPRS Authentication Result SRES Value", HFILL } },
1017
14
    { &hf_gsup_kc, { "Kc", "gsup.kc",
1018
14
      FT_BYTES, BASE_NONE, NULL, 0, "GSM/GPRS Ciphering Key", HFILL } },
1019
14
    { &hf_gsup_ik, { "IK", "gsup.ik",
1020
14
      FT_BYTES, BASE_NONE, NULL, 0, "UMTS Integrity Protection Key", HFILL } },
1021
14
    { &hf_gsup_ck, { "CK", "gsup.ck",
1022
14
      FT_BYTES, BASE_NONE, NULL, 0, "UMTS Ciphering Key", HFILL } },
1023
14
    { &hf_gsup_autn, { "AUTN", "gsup.autn",
1024
14
      FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Nonce", HFILL } },
1025
14
    { &hf_gsup_auts, { "AUTN", "gsup.auts",
1026
14
      FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Sync", HFILL } },
1027
14
    { &hf_gsup_res, { "RES", "gsup.res",
1028
14
      FT_BYTES, BASE_NONE, NULL, 0, "UMTS Authentication Result", HFILL } },
1029
1030
14
    { &hf_gsup_cn_domain, { "CN Domain Indicator", "gsup.cn_domain",
1031
14
      FT_UINT8, BASE_DEC, VALS(gsup_cndomain_types), 0, NULL, HFILL } },
1032
14
    { &hf_gsup_supported_rat_type, { "Supported RAT Type", "gsup.supported_rat_type",
1033
14
      FT_UINT8, BASE_DEC, VALS(gsup_rat_types), 0, NULL, HFILL } },
1034
14
    { &hf_gsup_current_rat_type, { "Current RAT Type", "gsup.current_rat_type",
1035
14
      FT_UINT8, BASE_DEC, VALS(gsup_rat_types), 0, NULL, HFILL } },
1036
14
    { &hf_gsup_cancel_type, { "Cancel Type", "gsup.cancel_type",
1037
14
      FT_UINT8, BASE_DEC, VALS(gsup_cancel_types), 0, NULL, HFILL } },
1038
14
    { &hf_gsup_pdp_info_compl, { "PDP Information Complete", "gsup.pdp_info_compl",
1039
14
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
1040
14
    { &hf_gsup_freeze_ptmsi, { "Freeze P-TMSI", "gsup.freeze_ptmsi",
1041
14
      FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } },
1042
14
    { &hf_gsup_apn, { "APN", "gsup.apn",
1043
14
      FT_STRING, BASE_NONE, NULL, 0, "Access Point Name", HFILL } },
1044
14
    { &hf_gsup_pdp_context_id, { "PDP Context ID", "gsup.pdp_context_id",
1045
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1046
14
    { &hf_gsup_charg_char, { "Charging Character", "gsup.charg_char",
1047
14
      FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1048
14
    { &hf_gsup_cause, { "Cause", "gsup.cause",
1049
14
      FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1050
14
    { &hf_gsup_session_id, { "Session ID", "gsup.session_id",
1051
14
      FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
1052
14
    { &hf_gsup_session_state, { "Session State", "gsup.session_state",
1053
14
      FT_UINT8, BASE_DEC, VALS(gsup_session_states), 0, NULL, HFILL } },
1054
14
    { &hf_gsup_sm_rp_mr, { "SM-RP-MR (Message Reference)", "gsup.sm_rp_mr",
1055
14
      FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1056
14
    { &hf_gsup_sm_rp_da_id_type, { "Address Type", "gsup.sm_rp_da.addr_type",
1057
14
      FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
1058
14
    { &hf_gsup_sm_rp_oa_id_type, { "Address Type", "gsup.sm_rp_oa.addr_type",
1059
14
      FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_rp_oda_types), 0, NULL, HFILL } },
1060
14
    { &hf_gsup_sm_rp_cause, { "SM-RP Cause", "gsup.sm_rp.cause",
1061
14
      FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
1062
14
    { &hf_gsup_sm_rp_mms, { "More Messages to Send", "gsup.sm_rp.mms",
1063
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1064
14
    { &hf_gsup_sm_alert_rsn, { "SM Alert Reason", "gsup.sm_alert_rsn",
1065
14
      FT_UINT8, BASE_DEC, VALS(osmo_gsup_sms_sm_alert_rsn_types), 0, NULL, HFILL } },
1066
14
    { &hf_gsup_imei_result, { "IMEI Check Result", "gsup.imei_check_res",
1067
14
      FT_UINT8, BASE_DEC, VALS(gsup_imei_result_types), 0, NULL, HFILL } },
1068
14
    { &hf_gsup_num_vectors_req, { "Number of Vectors Requested", "gsup.num_vectors_req",
1069
14
      FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
1070
14
    { &hf_gsup_msg_class, { "Message Class", "gsup.msg_class",
1071
14
      FT_UINT8, BASE_DEC, VALS(gsup_msg_class_types), 0, NULL, HFILL } },
1072
14
    { &hf_gsup_an_type, { "Access Network Type", "gsup.an_type",
1073
14
      FT_UINT8, BASE_DEC, VALS(gsup_an_type_vals), 0, NULL, HFILL } },
1074
14
    { &hf_gsup_source_name, { "Source Name", "gsup.source_name",
1075
14
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1076
14
    { &hf_gsup_source_name_text, { "Source Name (Text)", "gsup.source_name.text",
1077
14
      FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1078
14
    { &hf_gsup_destination_name, { "Destination Name", "gsup.dest_name",
1079
14
      FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
1080
14
    { &hf_gsup_destination_name_text, { "Destination Name (Text)", "gsup.dest_name.text",
1081
14
      FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
1082
14
    { &hf_gsup_spare_bits, { "Spare bit(s)", "gsup.spare_bits",
1083
14
      FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1084
14
    { &hf_gsup_pdp_addr_type_org, { "PDP organization", "gsup.pdp_organization",
1085
14
      FT_UINT8, BASE_DEC, VALS(pdp_org_type), 0x0F, NULL, HFILL }},
1086
14
    { &hf_gsup_pdp_addr_type_nr, { "PDP type", "gsup.pdp_type",
1087
14
      FT_UINT8, BASE_DEC, VALS(pdp_type), 0x0, NULL, HFILL }},
1088
14
    { &hf_gsup_pdp_addr_v4, { "PDP address", "gsup.pdp_address.ipv4",
1089
14
      FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1090
14
    { &hf_gsup_pdp_addr_v6, { "PDP address", "gsup.pdp_address.ipv6",
1091
14
      FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1092
14
  };
1093
14
  static int *ett[] = {
1094
14
    &ett_gsup,
1095
14
    &ett_gsup_ie,
1096
14
  };
1097
1098
14
  expert_module_t *expert_gsup;
1099
14
  module_t *module_gsup;
1100
1101
14
  static ei_register_info ei[] = {
1102
14
    { &ei_sm_rp_da_invalid,
1103
14
      { "gsup.sm_rp_da.invalid", PI_PROTOCOL, PI_ERROR,
1104
14
        "Malformed SM-RP-DA IE", EXPFILL } },
1105
14
    { &ei_sm_rp_oa_invalid,
1106
14
      { "gsup.sm_rp_oa.invalid", PI_PROTOCOL, PI_ERROR,
1107
14
        "Malformed SM-RP-OA IE", EXPFILL } },
1108
14
    { &ei_gsup_ie_len_invalid,
1109
14
      { "gsup.ie.len.invalid", PI_PROTOCOL, PI_ERROR,
1110
14
        "Invalid Information Element Length", EXPFILL } },
1111
14
  };
1112
1113
14
  proto_gsup = proto_register_protocol("Osmocom General Subscriber Update Protocol", "GSUP", "gsup");
1114
14
  proto_register_field_array(proto_gsup, hf, array_length(hf));
1115
14
  proto_register_subtree_array(ett, array_length(ett));
1116
1117
14
  gsup_handle = register_dissector("gsup", dissect_gsup, proto_gsup);
1118
1119
14
  expert_gsup = expert_register_protocol(proto_gsup);
1120
14
  expert_register_field_array(expert_gsup, ei, array_length(ei));
1121
1122
14
  module_gsup = prefs_register_protocol(proto_gsup, NULL);
1123
14
  prefs_register_bool_preference(module_gsup,
1124
14
      "show_name_as_text",
1125
14
      "Show Names as text",
1126
14
      "Show GSUP Source/Destination names as text in the Packet Details pane",
1127
14
      &show_name_as_text);
1128
14
}
1129
1130
void
1131
proto_reg_handoff_gsup(void)
1132
14
{
1133
14
  dissector_add_uint_with_preference("ipa.osmo.protocol", IPAC_PROTO_EXT_GSUP, gsup_handle);
1134
14
  gsm_map_handle = find_dissector_add_dependency("gsm_map", proto_gsup);
1135
14
  gsm_sms_handle = find_dissector_add_dependency("gsm_sms", proto_gsup);
1136
14
  bssap_imei_handle = find_dissector_add_dependency("bssap.imei", proto_gsup);
1137
14
  bssap_handle = find_dissector_add_dependency("bssap", proto_gsup);
1138
14
  ranap_handle = find_dissector_add_dependency("ranap", proto_gsup);
1139
14
}
1140
1141
/*
1142
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1143
 *
1144
 * Local variables:
1145
 * c-basic-offset: 8
1146
 * tab-width: 8
1147
 * indent-tabs-mode: t
1148
 * End:
1149
 *
1150
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1151
 * :indentSize=8:tabSize=8:noTabs=false:
1152
 */