blob: 78321ce0cf6df617b0041793ae0c3c62d51fb1de [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020027
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010028#include <osmocom/gprs/gprs_bssgp.h>
29
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020030#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010031#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020032
33#include <osmocom/core/application.h>
34#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010035#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020036
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020037#include <stdio.h>
38
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020039extern void *tall_msgb_ctx;
40
41void *tall_bsc_ctx;
42static struct sgsn_instance sgsn_inst = {
43 .config_file = "osmo_sgsn.cfg",
44 .cfg = {
45 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010046 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020047 },
48};
49struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010050unsigned sgsn_tx_counter = 0;
51
52/* override */
53int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
54 struct bssgp_dl_ud_par *dup)
55{
56 sgsn_tx_counter += 1;
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +010057 msgb_free(msg);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010058 return 0;
59}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020060
Jacob Erlbecke8b69682014-11-12 10:12:11 +010061/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
62void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
63void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
64 &__real_sgsn_update_subscriber_data;
65
66void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
67 struct gsm_subscriber *subscr)
68{
69 (*update_subscriber_data_cb)(mmctx, subscr);
70}
71
Jacob Erlbeck828059f2014-11-28 14:55:25 +010072/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
73int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
74int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
75 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010076
Jacob Erlbeck828059f2014-11-28 14:55:25 +010077int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
78 return (*subscr_request_update_location_cb)(mmctx);
79};
80
81/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
82int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
83int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
84 &__real_gprs_subscr_request_auth_info;
85
86int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
87 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010088};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010089
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020090static int count(struct llist_head *head)
91{
92 struct llist_head *cur;
93 int count = 0;
94
95 llist_for_each(cur, head)
96 count += 1;
97
98 return count;
99}
100
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200101static struct msgb *create_msg(const uint8_t *data, size_t len)
102{
103 struct msgb *msg = msgb_alloc(len + 8, "test message");
104 msg->l1h = msgb_put(msg, 8);
105 msg->l2h = msgb_put(msg, len);
106 memcpy(msg->l2h, data, len);
107
108 msgb_bcid(msg) = msg->l1h;
109 msgb_gmmh(msg) = msg->l2h;
110 return msg;
111}
112
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100113/*
114 * Create a context and search for it
115 */
116static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
117{
118 struct sgsn_mm_ctx *ctx, *ictx;
119 struct gprs_llc_lle *lle;
120 int old_count = count(gprs_llme_list());
121
122 lle = gprs_lle_get_or_create(tlli, 3);
123 ctx = sgsn_mm_ctx_alloc(tlli, raid);
124 ctx->mm_state = GMM_REGISTERED_NORMAL;
125 ctx->llme = lle->llme;
126
127 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
128 OSMO_ASSERT(ictx == ctx);
129
130 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
131
132 return ctx;
133}
134
Jacob Erlbeck75488292014-10-29 10:31:18 +0100135static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
136 const uint8_t *data, size_t data_len)
137{
138 struct msgb *msg;
139
140 sgsn_tx_counter = 0;
141
142 msg = create_msg(data, data_len);
143 msgb_tlli(msg) = tlli;
144 gsm0408_gprs_rcvmsg(msg, llme);
145 msgb_free(msg);
146}
147
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200148static void test_llme(void)
149{
150 struct gprs_llc_lle *lle, *lle_copy;
151 uint32_t local_tlli;
152 uint32_t foreign_tlli;
153
154 printf("Testing LLME allocations\n");
155 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
156 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
157
158 /* initial state */
159 OSMO_ASSERT(count(gprs_llme_list()) == 0);
160
161 /* Create a new entry */
162 lle = gprs_lle_get_or_create(local_tlli, 3);
163 OSMO_ASSERT(lle);
164 OSMO_ASSERT(count(gprs_llme_list()) == 1);
165
166 /* No new entry is created */
167 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
168 OSMO_ASSERT(lle == lle_copy);
169 OSMO_ASSERT(count(gprs_llme_list()) == 1);
170 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
171 OSMO_ASSERT(lle == lle_copy);
172 OSMO_ASSERT(count(gprs_llme_list()) == 1);
173
174 /* unassign which should delete it*/
175 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
176
177 /* Check that everything was cleaned up */
178 OSMO_ASSERT(count(gprs_llme_list()) == 0);
179}
180
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100181struct gsm_subscriber *last_updated_subscr = NULL;
182void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
183 struct gsm_subscriber *subscr)
184{
185 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
186 __func__, mmctx, subscr);
187 last_updated_subscr = subscr;
188}
189
Jacob Erlbecka695d242015-01-09 11:59:50 +0100190static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
191{
192 struct gsm_subscriber *sfound;
193
194 sfound = gprs_subscr_get_by_imsi(imsi);
195 OSMO_ASSERT(sfound == subscr);
196 subscr_put(sfound);
197
198 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
199}
200
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100201static void test_subscriber(void)
202{
Jacob Erlbecka695d242015-01-09 11:59:50 +0100203 struct gsm_subscriber *s1, *s2, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100204 const char *imsi1 = "1234567890";
205 const char *imsi2 = "9876543210";
206
207 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
208
209 printf("Testing core subscriber data API\n");
210
211 /* Check for emptiness */
212 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
213 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
214
215 /* Allocate entry 1 */
216 s1 = gprs_subscr_get_or_create(imsi1);
217 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100218 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100219 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100220
221 /* Allocate entry 2 */
222 s2 = gprs_subscr_get_or_create(imsi2);
223 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100224
225 /* Check entries */
226 assert_subscr(s1, imsi1);
227 assert_subscr(s2, imsi2);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100228
229 /* Update entry 1 */
230 last_updated_subscr = NULL;
231 gprs_subscr_update(s1);
232 OSMO_ASSERT(last_updated_subscr == s1);
233
234 /* Because of the update, it won't be freed on delete now */
235 gprs_subscr_delete(s1);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100236 sfound = gprs_subscr_get_by_imsi(imsi1);
237 OSMO_ASSERT(sfound != NULL);
238 s1 = sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100239
240 /* Cancel it, so that delete will free it.
241 * Refcount it to make sure s1 won't be freed here */
242 last_updated_subscr = NULL;
243 gprs_subscr_put_and_cancel(subscr_get(s1));
244 OSMO_ASSERT(last_updated_subscr == s1);
245
246 /* Cancelled entries are still being found */
Jacob Erlbecka695d242015-01-09 11:59:50 +0100247 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100248
Jacob Erlbecka695d242015-01-09 11:59:50 +0100249 /* Free entry 1 (GPRS_SUBSCRIBER_CANCELLED is set) */
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100250 gprs_subscr_delete(s1);
251 s1 = NULL;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100252 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100253 assert_subscr(s2, imsi2);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100254
Jacob Erlbecka695d242015-01-09 11:59:50 +0100255 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100256 gprs_subscr_delete(s2);
257 s2 = NULL;
258 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
259 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
260
261 OSMO_ASSERT(llist_empty(&active_subscribers));
262
263 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
264}
265
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100266static void test_auth_triplets(void)
267{
268 struct gsm_subscriber *s1, *s1found;
269 const char *imsi1 = "1234567890";
270 struct gsm_auth_tuple *at;
271 struct sgsn_mm_ctx *ctx;
272 struct gprs_ra_id raid = { 0, };
273 uint32_t local_tlli = 0xffeeddcc;
274 struct gprs_llc_llme *llme;
275
276 printf("Testing authentication triplet handling\n");
277
278 /* Check for emptiness */
279 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
280
281 /* Allocate entry 1 */
282 s1 = gprs_subscr_get_or_create(imsi1);
283 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
284 s1found = gprs_subscr_get_by_imsi(imsi1);
285 OSMO_ASSERT(s1found == s1);
286 subscr_put(s1found);
287
288 /* Create a context */
289 OSMO_ASSERT(count(gprs_llme_list()) == 0);
290 ctx = alloc_mm_ctx(local_tlli, &raid);
291
292 /* Attach s1 to ctx */
293 ctx->subscr = subscr_get(s1);
294 ctx->subscr->sgsn_data->mm = ctx;
295
296 /* Try to get auth tuple */
297 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
298 OSMO_ASSERT(at == NULL);
299
300 /* Add triplets */
301 s1->sgsn_data->auth_triplets[0].key_seq = 0;
302 s1->sgsn_data->auth_triplets[1].key_seq = 1;
303 s1->sgsn_data->auth_triplets[2].key_seq = 2;
304
305 /* Try to get auth tuple */
306 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
307 OSMO_ASSERT(at != NULL);
308 OSMO_ASSERT(at->key_seq == 0);
309 OSMO_ASSERT(at->use_count == 1);
310 at = sgsn_auth_get_tuple(ctx, at->key_seq);
311 OSMO_ASSERT(at != NULL);
312 OSMO_ASSERT(at->key_seq == 1);
313 OSMO_ASSERT(at->use_count == 1);
314 at = sgsn_auth_get_tuple(ctx, at->key_seq);
315 OSMO_ASSERT(at != NULL);
316 OSMO_ASSERT(at->key_seq == 2);
317 OSMO_ASSERT(at->use_count == 1);
318 at = sgsn_auth_get_tuple(ctx, at->key_seq);
319 OSMO_ASSERT(at == NULL);
320
321 /* Free MM context and subscriber */
322 subscr_put(s1);
323 llme = ctx->llme;
324 sgsn_mm_ctx_free(ctx);
325 s1found = gprs_subscr_get_by_imsi(imsi1);
326 OSMO_ASSERT(s1found == NULL);
327 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
328}
329
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100330#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
331
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100332static int rx_gsup_message(const uint8_t *data, size_t data_len)
333{
334 struct msgb *msg;
335 int rc;
336
337 msg = msgb_alloc(1024, __func__);
338 msg->l2h = msgb_put(msg, data_len);
339 OSMO_ASSERT(msg->l2h != NULL);
340 memcpy(msg->l2h, data, data_len);
341 rc = gprs_subscr_rx_gsup_message(msg);
342 msgb_free(msg);
343
344 return rc;
345}
346
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100347static void test_subscriber_gsup(void)
348{
349 struct gsm_subscriber *s1, *s1found;
350 const char *imsi1 = "1234567890";
351 struct sgsn_mm_ctx *ctx;
352 struct gprs_ra_id raid = { 0, };
353 uint32_t local_tlli = 0xffeeddcc;
354 struct gprs_llc_llme *llme;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100355 int rc;
356
357 static const uint8_t send_auth_info_res[] = {
358 0x0a,
359 TEST_GSUP_IMSI1_IE,
360 0x03, 0x22, /* Auth tuple */
361 0x20, 0x10,
362 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
363 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
364 0x21, 0x04,
365 0x21, 0x22, 0x23, 0x24,
366 0x22, 0x08,
367 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
368 0x03, 0x22, /* Auth tuple */
369 0x20, 0x10,
370 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
371 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
372 0x21, 0x04,
373 0xa1, 0xa2, 0xa3, 0xa4,
374 0x22, 0x08,
375 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
376 };
377
378 static const uint8_t send_auth_info_err[] = {
379 0x09,
380 TEST_GSUP_IMSI1_IE,
381 0x02, 0x01, 0x07 /* GPRS not allowed */
382 };
383
384 static const uint8_t update_location_res[] = {
385 0x06,
386 TEST_GSUP_IMSI1_IE,
387 0x04, 0x00, /* PDP info complete */
388 0x05, 0x12,
389 0x10, 0x01, 0x01,
390 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
391 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
392 0x05, 0x11,
393 0x10, 0x01, 0x02,
394 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
395 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
396 };
397
398 static const uint8_t update_location_err[] = {
399 0x05,
400 TEST_GSUP_IMSI1_IE,
401 0x02, 0x01, 0x07 /* GPRS not allowed */
402 };
403
404 static const uint8_t location_cancellation_req[] = {
405 0x1c,
406 TEST_GSUP_IMSI1_IE,
407 0x06, 0x01, 0x00,
408 };
409
410 printf("Testing subcriber GSUP handling\n");
411
412 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
413
414 /* Check for emptiness */
415 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
416
417 /* Allocate entry 1 */
418 s1 = gprs_subscr_get_or_create(imsi1);
419 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
420 s1found = gprs_subscr_get_by_imsi(imsi1);
421 OSMO_ASSERT(s1found == s1);
422 subscr_put(s1found);
423
424 /* Create a context */
425 OSMO_ASSERT(count(gprs_llme_list()) == 0);
426 ctx = alloc_mm_ctx(local_tlli, &raid);
427 llme = ctx->llme;
428
429 /* Attach s1 to ctx */
430 ctx->subscr = subscr_get(s1);
431 ctx->subscr->sgsn_data->mm = ctx;
432
433 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100434 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100435 OSMO_ASSERT(rc >= 0);
436 OSMO_ASSERT(last_updated_subscr == s1);
437
438 /* Check triplets */
439 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
440 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
441 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
442
443 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100444 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100445 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100446 OSMO_ASSERT(last_updated_subscr == s1);
447
448 /* Check triplets */
449 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
450 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
451 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
452
453 /* Inject UpdateLocReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100454 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100455 OSMO_ASSERT(rc >= 0);
456 OSMO_ASSERT(last_updated_subscr == s1);
457
458 /* Check authorization */
459 OSMO_ASSERT(s1->authorized == 1);
460
461 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100462 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100463 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100464 OSMO_ASSERT(last_updated_subscr == s1);
465
466 /* Check authorization */
467 OSMO_ASSERT(s1->authorized == 0);
468
469 /* Inject UpdateLocReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100470 rc = rx_gsup_message(location_cancellation_req,
471 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100472 OSMO_ASSERT(rc >= 0);
473 OSMO_ASSERT(last_updated_subscr == s1);
474
475 /* Check cancellation result */
476 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
477 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
478
479 /* Free MM context and subscriber */
480 subscr_put(s1);
481 s1found = gprs_subscr_get_by_imsi(imsi1);
482 OSMO_ASSERT(s1found == NULL);
483 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
484
485 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
486}
487
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200488/*
489 * Test that a GMM Detach will remove the MMCTX and the
490 * associated LLME.
491 */
492static void test_gmm_detach(void)
493{
494 struct gprs_ra_id raid = { 0, };
495 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200496 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200497
498 printf("Testing GMM detach\n");
499
500 /* DTAP - Detach Request (MO) */
501 /* normal detach, power_off = 0 */
502 static const unsigned char detach_req[] = {
503 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
504 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
505 };
506
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200507 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200508
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100509 /* Create a context */
510 OSMO_ASSERT(count(gprs_llme_list()) == 0);
511 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200512
513 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100514 send_0408_message(ctx->llme, local_tlli,
515 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200516
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100517 /* verify that a single message (hopefully the Detach Accept) has been
518 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100519 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100520
521 /* verify that things are gone */
522 OSMO_ASSERT(count(gprs_llme_list()) == 0);
523 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
524 OSMO_ASSERT(!ictx);
525}
526
527/*
528 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
529 * will not sent a Detach Accept message (power_off = 1)
530 */
531static void test_gmm_detach_power_off(void)
532{
533 struct gprs_ra_id raid = { 0, };
534 struct sgsn_mm_ctx *ctx, *ictx;
535 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100536
537 printf("Testing GMM detach (power off)\n");
538
539 /* DTAP - Detach Request (MO) */
540 /* normal detach, power_off = 1 */
541 static const unsigned char detach_req[] = {
542 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
543 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
544 };
545
546 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
547
548 /* Create a context */
549 OSMO_ASSERT(count(gprs_llme_list()) == 0);
550 ctx = alloc_mm_ctx(local_tlli, &raid);
551
552 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100553 send_0408_message(ctx->llme, local_tlli,
554 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100555
556 /* verify that no message (and therefore no Detach Accept) has been
557 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100558 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100559
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200560 /* verify that things are gone */
561 OSMO_ASSERT(count(gprs_llme_list()) == 0);
562 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200563 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200564}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200565
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200566/*
567 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
568 */
569static void test_gmm_detach_no_mmctx(void)
570{
571 struct gprs_llc_lle *lle;
572 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200573
574 printf("Testing GMM detach (no MMCTX)\n");
575
576 /* DTAP - Detach Request (MO) */
577 /* normal detach, power_off = 0 */
578 static const unsigned char detach_req[] = {
579 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
580 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
581 };
582
583 /* Create an LLME */
584 OSMO_ASSERT(count(gprs_llme_list()) == 0);
585 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
586 lle = gprs_lle_get_or_create(local_tlli, 3);
587
588 OSMO_ASSERT(count(gprs_llme_list()) == 1);
589
590 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100591 send_0408_message(lle->llme, local_tlli,
592 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200593
594 /* verify that the LLME is gone */
595 OSMO_ASSERT(count(gprs_llme_list()) == 0);
596}
597
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100598/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100599 * Test that a single GMM Detach Accept message will not cause the SGSN to send
600 * any message or leave an MM context at the SGSN.
601 */
602static void test_gmm_detach_accept_unexpected(void)
603{
604 struct gprs_llc_lle *lle;
605 uint32_t local_tlli;
606
607 printf("Testing GMM detach accept (unexpected)\n");
608
609 /* DTAP - Detach Accept (MT) */
610 /* normal detach */
611 static const unsigned char detach_acc[] = {
612 0x08, 0x06
613 };
614
615 /* Create an LLME */
616 OSMO_ASSERT(count(gprs_llme_list()) == 0);
617 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
618 lle = gprs_lle_get_or_create(local_tlli, 3);
619
620 /* inject the detach */
621 send_0408_message(lle->llme, local_tlli,
622 detach_acc, ARRAY_SIZE(detach_acc));
623
624 /* verify that no message (and therefore no Status or XID reset) has been
625 * sent by the SGSN */
626 OSMO_ASSERT(sgsn_tx_counter == 0);
627
628 /* verify that things are gone */
629 OSMO_ASSERT(count(gprs_llme_list()) == 0);
630}
631
632/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100633 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
634 */
635static void test_gmm_status_no_mmctx(void)
636{
637 struct gprs_llc_lle *lle;
638 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100639
640 printf("Testing GMM Status (no MMCTX)\n");
641
642 /* DTAP - GMM Status, protocol error */
643 static const unsigned char gmm_status[] = {
644 0x08, 0x20, 0x6f
645 };
646
647 /* Create an LLME */
648 OSMO_ASSERT(count(gprs_llme_list()) == 0);
649 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
650 lle = gprs_lle_get_or_create(local_tlli, 3);
651
652 OSMO_ASSERT(count(gprs_llme_list()) == 1);
653
654 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100655 send_0408_message(lle->llme, local_tlli,
656 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100657
658 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100659 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100660
661 /* verify that the LLME is gone */
662 OSMO_ASSERT(count(gprs_llme_list()) == 0);
663}
664
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100665/*
666 * Test the GMM Attach procedure
667 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100668static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100669{
670 struct gprs_ra_id raid = { 0, };
671 struct sgsn_mm_ctx *ctx = NULL;
672 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100673 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100674 uint32_t foreign_tlli;
675 uint32_t local_tlli = 0;
676 struct gprs_llc_lle *lle;
677
678 /* DTAP - Attach Request */
679 /* The P-TMSI is not known by the SGSN */
680 static const unsigned char attach_req[] = {
681 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
682 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
683 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
684 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
685 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
686 };
687
688 /* DTAP - Identity Response IMEI */
689 static const unsigned char ident_resp_imei[] = {
690 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
691 0x56
692 };
693
694 /* DTAP - Identity Response IMSI */
695 static const unsigned char ident_resp_imsi[] = {
696 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
697 0x54
698 };
699
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100700 /* DTAP - Authentication and Ciphering Resp */
701 static const unsigned char auth_ciph_resp[] = {
702 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
703 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
704 };
705
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100706 /* DTAP - Attach Complete */
707 static const unsigned char attach_compl[] = {
708 0x08, 0x03
709 };
710
711 /* DTAP - Detach Request (MO) */
712 /* normal detach, power_off = 0 */
713 static const unsigned char detach_req[] = {
714 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
715 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
716 };
717
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100718 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100719
720 /* reset the PRNG used by sgsn_alloc_ptmsi */
721 srand(1);
722
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100723 ptmsi1 = sgsn_alloc_ptmsi();
724 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
725
726 /* reset the PRNG, so that the same P-TMSI sequence will be generated
727 * again */
728 srand(1);
729
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100730 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
731
732 /* Create a LLE/LLME */
733 OSMO_ASSERT(count(gprs_llme_list()) == 0);
734 lle = gprs_lle_get_or_create(foreign_tlli, 3);
735 OSMO_ASSERT(count(gprs_llme_list()) == 1);
736
737 /* inject the attach request */
738 send_0408_message(lle->llme, foreign_tlli,
739 attach_req, ARRAY_SIZE(attach_req));
740
741 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
742 OSMO_ASSERT(ctx != NULL);
743 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
744
745 /* we expect an identity request (IMEI) */
746 OSMO_ASSERT(sgsn_tx_counter == 1);
747
748 /* inject the identity response (IMEI) */
749 send_0408_message(ctx->llme, foreign_tlli,
750 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
751
752 /* we expect an identity request (IMSI) */
753 OSMO_ASSERT(sgsn_tx_counter == 1);
754
755 /* inject the identity response (IMSI) */
756 send_0408_message(ctx->llme, foreign_tlli,
757 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
758
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100759 /* check that the MM context has not been removed due to a failed
760 * authorization */
761 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
762
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100763 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100764
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100765retry_attach_req:
766
767 if (retry && sgsn_tx_counter == 0) {
768 fprintf(stderr, "Retrying attach request\n");
769 /* re-inject the attach request */
770 send_0408_message(lle->llme, foreign_tlli,
771 attach_req, ARRAY_SIZE(attach_req));
772 }
773
774 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
775 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100776
777 /* inject the auth & ciph response */
778 send_0408_message(ctx->llme, foreign_tlli,
779 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
780
781 /* check that the MM context has not been removed due to a
782 * failed authorization */
783 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
784 }
785
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100786 if (retry && sgsn_tx_counter == 0)
787 goto retry_attach_req;
788
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100789 /* we expect an attach accept/reject */
790 OSMO_ASSERT(sgsn_tx_counter == 1);
791
792 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100793 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100794
795 /* inject the attach complete */
796 send_0408_message(ctx->llme, local_tlli,
797 attach_compl, ARRAY_SIZE(attach_compl));
798
799 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
800
801 /* we don't expect a response */
802 OSMO_ASSERT(sgsn_tx_counter == 0);
803
804 /* inject the detach */
805 send_0408_message(ctx->llme, local_tlli,
806 detach_req, ARRAY_SIZE(detach_req));
807
808 /* verify that things are gone */
809 OSMO_ASSERT(count(gprs_llme_list()) == 0);
810 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
811 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100812}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100813
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100814static void test_gmm_attach_acl(void)
815{
816 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
817
818 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
819 sgsn_acl_add("123456789012345", &sgsn->cfg);
820 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100821 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100822 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100823
824 sgsn->cfg.auth_policy = saved_auth_policy;
825}
826
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100827int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100828 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100829 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100830 if (rc == -ENOTSUP) {
831 OSMO_ASSERT(mmctx->subscr);
832 gprs_subscr_update(mmctx->subscr);
833 }
834 return rc;
835};
836
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100837int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
838 gprs_subscr_update(mmctx->subscr);
839 return 0;
840};
841
Jacob Erlbeck03386f62015-01-08 14:08:16 +0100842static void cleanup_subscr_by_imsi(const char *imsi)
843{
844 struct gsm_subscriber *subscr;
845
846 subscr = gprs_subscr_get_by_imsi(imsi);
847 OSMO_ASSERT(subscr != NULL);
Jacob Erlbeckdc7e8b92015-01-08 14:13:46 +0100848 subscr->keep_in_ram = 0;
849 subscr_put(subscr);
850 subscr = gprs_subscr_get_by_imsi(imsi);
851 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck03386f62015-01-08 14:08:16 +0100852}
853
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100854static void test_gmm_attach_subscr(void)
855{
856 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
857 struct gsm_subscriber *subscr;
858
859 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100860 subscr_request_update_location_cb = my_subscr_request_update_location;
861 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100862
863 subscr = gprs_subscr_get_or_create("123456789012345");
864 subscr->authorized = 1;
865 subscr_put(subscr);
866
867 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100868 test_gmm_attach(0);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100869
Jacob Erlbeck03386f62015-01-08 14:08:16 +0100870 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100871
872 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100873 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
874 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100875}
876
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100877int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
878{
879 /* Fake an authentication */
880 OSMO_ASSERT(mmctx->subscr);
881 mmctx->is_authenticated = 1;
882 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100883
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100884 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100885};
886
887static void test_gmm_attach_subscr_fake_auth(void)
888{
889 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
890 struct gsm_subscriber *subscr;
891
892 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100893 subscr_request_update_location_cb = my_subscr_request_update_location;
894 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100895
896 subscr = gprs_subscr_get_or_create("123456789012345");
897 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100898 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100899 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100900 subscr_put(subscr);
901
902 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100903 test_gmm_attach(0);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100904
Jacob Erlbeck03386f62015-01-08 14:08:16 +0100905 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100906
907 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100908 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
909 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
910}
911
912int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
913{
914 struct gsm_auth_tuple at = {
915 .sres = {0x51, 0xe5, 0x51, 0xe5},
916 .key_seq = 0
917 };
918
919 /* Fake an authentication */
920 OSMO_ASSERT(mmctx->subscr);
921 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
922
923 gprs_subscr_update_auth_info(mmctx->subscr);
924
925 return 0;
926};
927
928static void test_gmm_attach_subscr_real_auth(void)
929{
930 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
931 struct gsm_subscriber *subscr;
932
933 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
934 subscr_request_update_location_cb = my_subscr_request_update_location;
935 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
936
937 subscr = gprs_subscr_get_or_create("123456789012345");
938 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100939 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100940 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100941 subscr_put(subscr);
942
943 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100944 test_gmm_attach(0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100945
Jacob Erlbeck03386f62015-01-08 14:08:16 +0100946 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100947
948 sgsn->cfg.auth_policy = saved_auth_policy;
949 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
950 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100951}
952
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100953#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
954 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
955
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100956static int auth_info_skip = 0;
957static int upd_loc_skip = 0;
958
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100959int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
960{
961 static const uint8_t send_auth_info_res[] = {
962 0x0a,
963 TEST_GSUP_IMSI_LONG_IE,
964 0x03, 0x22, /* Auth tuple */
965 0x20, 0x10,
966 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
967 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
968 0x21, 0x04,
969 0x51, 0xe5, 0x51, 0xe5,
970 0x22, 0x08,
971 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
972 };
973
974 OSMO_ASSERT(mmctx->subscr);
975
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100976 if (auth_info_skip > 0) {
977 auth_info_skip -= 1;
978 return -EAGAIN;
979 }
980
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100981 /* Fake an SendAuthInfoRes */
982 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
983
984 return 0;
985};
986
987int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
988 static const uint8_t update_location_res[] = {
989 0x06,
990 TEST_GSUP_IMSI_LONG_IE,
991 0x04, 0x00, /* PDP info complete */
992 0x05, 0x12,
993 0x10, 0x01, 0x01,
994 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
995 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
996 };
997
998 OSMO_ASSERT(mmctx->subscr);
999
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001000 if (upd_loc_skip > 0) {
1001 upd_loc_skip -= 1;
1002 return -EAGAIN;
1003 }
1004
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001005 /* Fake an UpdateLocRes */
1006 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1007};
1008
1009
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001010static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001011{
1012 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1013 struct gsm_subscriber *subscr;
1014
1015 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1016 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1017 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001018 if (retry) {
1019 upd_loc_skip = 3;
1020 auth_info_skip = 3;
1021 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001022
1023 subscr = gprs_subscr_get_or_create("123456789012345");
1024 subscr->authorized = 1;
1025 sgsn->cfg.require_authentication = 1;
1026 sgsn->cfg.require_update_location = 1;
1027 subscr_put(subscr);
1028
1029 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001030 test_gmm_attach(retry);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001031
1032 subscr = gprs_subscr_get_by_imsi("123456789012345");
1033 OSMO_ASSERT(subscr != NULL);
1034 gprs_subscr_delete(subscr);
1035
1036 sgsn->cfg.auth_policy = saved_auth_policy;
1037 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1038 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001039 upd_loc_skip = 0;
1040 auth_info_skip = 0;
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001041}
1042
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001043/*
1044 * Test the GMM Rejects
1045 */
1046static void test_gmm_reject(void)
1047{
1048 struct gprs_ra_id raid = { 0, };
1049 struct sgsn_mm_ctx *ctx = NULL;
1050 uint32_t foreign_tlli;
1051 struct gprs_llc_lle *lle;
1052 int idx;
1053
1054 /* DTAP - Attach Request */
1055 /* Invalid MI length */
1056 static const unsigned char attach_req_inv_mi_len[] = {
1057 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1058 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1059 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1060 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1061 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1062 };
1063
1064 /* DTAP - Attach Request */
1065 /* Invalid MI type (IMEI) */
1066 static const unsigned char attach_req_inv_mi_type[] = {
1067 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1068 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1069 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1070 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1071 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1072 };
1073
1074 /* DTAP - Routing Area Update Request */
1075 static const unsigned char dtap_ra_upd_req[] = {
1076 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1077 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1078 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1079 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1080 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1081 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1082 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1083 };
1084
1085 /* DTAP - Routing Area Update Request */
1086 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1087 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1088 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1089 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1090 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1091 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1092 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1093 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1094 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1095 };
1096
1097 /* DTAP - Routing Area Update Request */
1098 /* Invalid cap length */
1099 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1100 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1101 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1102 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1104 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1105 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1106 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1107 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1108 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1109 };
1110
1111 struct test {
1112 const char *title;
1113 const unsigned char *msg;
1114 unsigned msg_len;
1115 unsigned num_resp;
1116
1117 };
1118 static struct test tests[] = {
1119 {
1120 .title = "Attach Request (invalid MI length)",
1121 .msg = attach_req_inv_mi_len,
1122 .msg_len = sizeof(attach_req_inv_mi_len),
1123 .num_resp = 1 /* Reject */
1124
1125 },
1126 {
1127 .title = "Attach Request (invalid MI type)",
1128 .msg = attach_req_inv_mi_type,
1129 .msg_len = sizeof(attach_req_inv_mi_type),
1130 .num_resp = 1 /* Reject */
1131 },
1132 {
1133 .title = "Routing Area Update Request (valid)",
1134 .msg = dtap_ra_upd_req,
1135 .msg_len = sizeof(dtap_ra_upd_req),
1136 .num_resp = 2 /* XID Reset + Reject */
1137 },
1138 {
1139 .title = "Routing Area Update Request (invalid type)",
1140 .msg = dtap_ra_upd_req_inv_type,
1141 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1142 .num_resp = 1 /* Reject */
1143 },
1144 {
1145 .title = "Routing Area Update Request (invalid CAP length)",
1146 .msg = dtap_ra_upd_req_inv_cap_len,
1147 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1148 .num_resp = 1 /* Reject */
1149 },
1150 };
1151
1152 printf("Testing GMM reject\n");
1153
1154 /* reset the PRNG used by sgsn_alloc_ptmsi */
1155 srand(1);
1156
1157 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1158
1159 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1160
1161 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1162 const struct test *test = &tests[idx];
1163 printf(" - %s\n", test->title);
1164
1165 /* Create a LLE/LLME */
1166 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1167 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1168
1169 /* Inject the Request message */
1170 send_0408_message(lle->llme, foreign_tlli,
1171 test->msg, test->msg_len);
1172
1173 /* We expect a Reject message */
1174 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1175 sgsn_tx_counter, test->num_resp);
1176 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1177
1178 /* verify that LLME/MM are removed */
1179 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1180 OSMO_ASSERT(ctx == NULL);
1181 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1182 }
1183}
1184
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001185/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001186 * Test cancellation of attached MM contexts
1187 */
1188static void test_gmm_cancel(void)
1189{
1190 struct gprs_ra_id raid = { 0, };
1191 struct sgsn_mm_ctx *ctx = NULL;
1192 struct sgsn_mm_ctx *ictx;
1193 uint32_t ptmsi1;
1194 uint32_t foreign_tlli;
1195 uint32_t local_tlli = 0;
1196 struct gprs_llc_lle *lle;
1197 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1198
1199 /* DTAP - Attach Request */
1200 /* The P-TMSI is not known by the SGSN */
1201 static const unsigned char attach_req[] = {
1202 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1203 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1204 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1205 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1206 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1207 };
1208
1209 /* DTAP - Identity Response IMEI */
1210 static const unsigned char ident_resp_imei[] = {
1211 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1212 0x56
1213 };
1214
1215 /* DTAP - Identity Response IMSI */
1216 static const unsigned char ident_resp_imsi[] = {
1217 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1218 0x54
1219 };
1220
1221 /* DTAP - Attach Complete */
1222 static const unsigned char attach_compl[] = {
1223 0x08, 0x03
1224 };
1225
1226 printf("Testing cancellation\n");
1227
1228 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1229
1230 /* reset the PRNG used by sgsn_alloc_ptmsi */
1231 srand(1);
1232
1233 ptmsi1 = sgsn_alloc_ptmsi();
1234 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1235
1236 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1237 * again */
1238 srand(1);
1239
1240 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1241
1242 /* Create a LLE/LLME */
1243 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1244 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1245 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1246
1247 /* inject the attach request */
1248 send_0408_message(lle->llme, foreign_tlli,
1249 attach_req, ARRAY_SIZE(attach_req));
1250
1251 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1252 OSMO_ASSERT(ctx != NULL);
1253 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1254
1255 /* we expect an identity request (IMEI) */
1256 OSMO_ASSERT(sgsn_tx_counter == 1);
1257
1258 /* inject the identity response (IMEI) */
1259 send_0408_message(ctx->llme, foreign_tlli,
1260 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1261
1262 /* we expect an identity request (IMSI) */
1263 OSMO_ASSERT(sgsn_tx_counter == 1);
1264
1265 /* inject the identity response (IMSI) */
1266 send_0408_message(ctx->llme, foreign_tlli,
1267 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1268
1269 /* check that the MM context has not been removed due to a failed
1270 * authorization */
1271 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1272
1273 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1274
1275 /* we expect an attach accept/reject */
1276 OSMO_ASSERT(sgsn_tx_counter == 1);
1277
1278 /* this has been randomly assigned by the SGSN */
1279 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1280
1281 /* inject the attach complete */
1282 send_0408_message(ctx->llme, local_tlli,
1283 attach_compl, ARRAY_SIZE(attach_compl));
1284
1285 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1286
1287 /* we don't expect a response */
1288 OSMO_ASSERT(sgsn_tx_counter == 0);
1289
1290 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001291 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001292
1293 /* verify that things are gone */
1294 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1295 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1296 OSMO_ASSERT(!ictx);
1297
1298 sgsn->cfg.auth_policy = saved_auth_policy;
1299}
1300
1301/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001302 * Test the dynamic allocation of P-TMSIs
1303 */
1304static void test_gmm_ptmsi_allocation(void)
1305{
1306 struct gprs_ra_id raid = { 0, };
1307 struct sgsn_mm_ctx *ctx = NULL;
1308 struct sgsn_mm_ctx *ictx;
1309 uint32_t foreign_tlli;
1310 uint32_t ptmsi1;
1311 uint32_t ptmsi2;
1312 uint32_t old_ptmsi;
1313 uint32_t local_tlli = 0;
1314 struct gprs_llc_lle *lle;
1315 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1316
1317 /* DTAP - Attach Request (IMSI 12131415161718) */
1318 static const unsigned char attach_req[] = {
1319 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1320 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1321 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1322 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1323 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1324 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1325 0x00,
1326 };
1327
1328 /* DTAP - Identity Response IMEI */
1329 static const unsigned char ident_resp_imei[] = {
1330 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1331 0x56
1332 };
1333
1334 /* DTAP - Attach Complete */
1335 static const unsigned char attach_compl[] = {
1336 0x08, 0x03
1337 };
1338
1339 /* DTAP - Routing Area Update Request */
1340 static const unsigned char ra_upd_req[] = {
1341 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1342 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1343 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1344 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1345 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1346 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1347 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1348 };
1349
1350 /* DTAP - Routing Area Update Complete */
1351 static const unsigned char ra_upd_complete[] = {
1352 0x08, 0x0a
1353 };
1354
1355 /* DTAP - Detach Request (MO) */
1356 /* normal detach, power_off = 1 */
1357 static const unsigned char detach_req[] = {
1358 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1359 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1360 };
1361
1362 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1363
1364 printf("Testing P-TMSI allocation\n");
1365
1366 printf(" - sgsn_alloc_ptmsi\n");
1367
1368 /* reset the PRNG used by sgsn_alloc_ptmsi */
1369 srand(1);
1370
1371 ptmsi1 = sgsn_alloc_ptmsi();
1372 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1373
1374 ptmsi2 = sgsn_alloc_ptmsi();
1375 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1376
1377 OSMO_ASSERT(ptmsi1 != ptmsi2);
1378
1379 printf(" - Repeated Attach Request\n");
1380
1381 /* reset the PRNG, so that the same P-TMSI will be generated
1382 * again */
1383 srand(1);
1384
1385 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1386
1387 /* Create a LLE/LLME */
1388 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1389 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1390 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1391
1392 /* inject the attach request */
1393 send_0408_message(lle->llme, foreign_tlli,
1394 attach_req, ARRAY_SIZE(attach_req));
1395
1396 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1397 OSMO_ASSERT(ctx != NULL);
1398 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1399 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1400
1401 old_ptmsi = ctx->p_tmsi_old;
1402
1403 /* we expect an identity request (IMEI) */
1404 OSMO_ASSERT(sgsn_tx_counter == 1);
1405
1406 /* inject the identity response (IMEI) */
1407 send_0408_message(ctx->llme, foreign_tlli,
1408 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1409
1410 /* check that the MM context has not been removed due to a failed
1411 * authorization */
1412 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1413
1414 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1415 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1416
1417 /* we expect an attach accept */
1418 OSMO_ASSERT(sgsn_tx_counter == 1);
1419
1420 /* we ignore this and send the attach again */
1421 send_0408_message(lle->llme, foreign_tlli,
1422 attach_req, ARRAY_SIZE(attach_req));
1423
1424 /* the allocated P-TMSI should be the same */
1425 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1426 OSMO_ASSERT(ctx != NULL);
1427 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1428 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1429 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1430
1431 /* inject the attach complete */
1432 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1433 send_0408_message(ctx->llme, local_tlli,
1434 attach_compl, ARRAY_SIZE(attach_compl));
1435
1436 /* we don't expect a response */
1437 OSMO_ASSERT(sgsn_tx_counter == 0);
1438
1439 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1440 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1441 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1442
1443 printf(" - Repeated RA Update Request\n");
1444
1445 /* inject the RA update request */
1446 send_0408_message(ctx->llme, local_tlli,
1447 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1448
1449 /* we expect an RA update accept */
1450 OSMO_ASSERT(sgsn_tx_counter == 1);
1451
1452 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1453 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1454 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1455
1456 /* repeat the RA update request */
1457 send_0408_message(ctx->llme, local_tlli,
1458 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1459
1460 /* we expect an RA update accept */
1461 OSMO_ASSERT(sgsn_tx_counter == 1);
1462
1463 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1464 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1465 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1466
1467 /* inject the RA update complete */
1468 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1469 send_0408_message(ctx->llme, local_tlli,
1470 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1471
1472 /* we don't expect a response */
1473 OSMO_ASSERT(sgsn_tx_counter == 0);
1474
1475 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1476 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1477 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1478
1479 /* inject the detach */
1480 send_0408_message(ctx->llme, local_tlli,
1481 detach_req, ARRAY_SIZE(detach_req));
1482
1483 /* verify that things are gone */
1484 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1485 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1486 OSMO_ASSERT(!ictx);
1487
1488 sgsn->cfg.auth_policy = saved_auth_policy;
1489}
1490
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001491static struct log_info_cat gprs_categories[] = {
1492 [DMM] = {
1493 .name = "DMM",
1494 .description = "Layer3 Mobility Management (MM)",
1495 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001496 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001497 },
1498 [DPAG] = {
1499 .name = "DPAG",
1500 .description = "Paging Subsystem",
1501 .color = "\033[1;38m",
1502 .enabled = 1, .loglevel = LOGL_NOTICE,
1503 },
1504 [DMEAS] = {
1505 .name = "DMEAS",
1506 .description = "Radio Measurement Processing",
1507 .enabled = 0, .loglevel = LOGL_NOTICE,
1508 },
1509 [DREF] = {
1510 .name = "DREF",
1511 .description = "Reference Counting",
1512 .enabled = 0, .loglevel = LOGL_NOTICE,
1513 },
1514 [DGPRS] = {
1515 .name = "DGPRS",
1516 .description = "GPRS Packet Service",
1517 .enabled = 1, .loglevel = LOGL_DEBUG,
1518 },
1519 [DNS] = {
1520 .name = "DNS",
1521 .description = "GPRS Network Service (NS)",
1522 .enabled = 1, .loglevel = LOGL_INFO,
1523 },
1524 [DBSSGP] = {
1525 .name = "DBSSGP",
1526 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1527 .enabled = 1, .loglevel = LOGL_DEBUG,
1528 },
1529 [DLLC] = {
1530 .name = "DLLC",
1531 .description = "GPRS Logical Link Control Protocol (LLC)",
1532 .enabled = 1, .loglevel = LOGL_DEBUG,
1533 },
1534 [DSNDCP] = {
1535 .name = "DSNDCP",
1536 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1537 .enabled = 1, .loglevel = LOGL_DEBUG,
1538 },
1539};
1540
1541static struct log_info info = {
1542 .cat = gprs_categories,
1543 .num_cat = ARRAY_SIZE(gprs_categories),
1544};
1545
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001546int main(int argc, char **argv)
1547{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001548 osmo_init_logging(&info);
1549 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1550 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1551
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001552 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001553 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001554
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001555 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001556 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001557 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001558 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001559 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001560 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001561 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001562 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001563 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001564 test_gmm_attach_acl();
1565 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001566 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001567 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001568 test_gmm_attach_subscr_gsup_auth(0);
1569 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001570 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001571 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001572 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001573 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001574
1575 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001576 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001577 return 0;
1578}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001579
1580
1581/* stubs */
1582struct osmo_prim_hdr;
1583int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1584{
1585 abort();
1586}