blob: d66983040fe939b3c9bb9145d475ec95cc60cd73 [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>
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck3400f112015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020030
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010031#include <osmocom/gprs/gprs_bssgp.h>
32
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020033#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010034#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020035
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020039
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020040#include <stdio.h>
41
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020042extern void *tall_msgb_ctx;
43
44void *tall_bsc_ctx;
45static struct sgsn_instance sgsn_inst = {
46 .config_file = "osmo_sgsn.cfg",
47 .cfg = {
48 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010049 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
54
Jacob Erlbeck515fc332015-10-12 19:36:31 +020055static void cleanup_test()
56{
57}
58
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010059/* override */
60int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
61 struct bssgp_dl_ud_par *dup)
62{
63 sgsn_tx_counter += 1;
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +010064 msgb_free(msg);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010065 return 0;
66}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020067
Jacob Erlbecke8b69682014-11-12 10:12:11 +010068/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +010069void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
70void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbecke8b69682014-11-12 10:12:11 +010071 &__real_sgsn_update_subscriber_data;
72
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +010073void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +010074{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +010075 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +010076}
77
Jacob Erlbeck828059f2014-11-28 14:55:25 +010078/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
79int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
80int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
81 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010082
Jacob Erlbeck828059f2014-11-28 14:55:25 +010083int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
84 return (*subscr_request_update_location_cb)(mmctx);
85};
86
87/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
88int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
89int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
90 &__real_gprs_subscr_request_auth_info;
91
92int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
93 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010094};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010095
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010096/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
97int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
98int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
99 &__real_gprs_gsup_client_send;
100
101int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
102{
103 return (*gprs_gsup_client_send_cb)(gsupc, msg);
104};
105
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200106static int count(struct llist_head *head)
107{
108 struct llist_head *cur;
109 int count = 0;
110
111 llist_for_each(cur, head)
112 count += 1;
113
114 return count;
115}
116
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200117static struct msgb *create_msg(const uint8_t *data, size_t len)
118{
119 struct msgb *msg = msgb_alloc(len + 8, "test message");
120 msg->l1h = msgb_put(msg, 8);
121 msg->l2h = msgb_put(msg, len);
122 memcpy(msg->l2h, data, len);
123
124 msgb_bcid(msg) = msg->l1h;
125 msgb_gmmh(msg) = msg->l2h;
126 return msg;
127}
128
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100129/*
130 * Create a context and search for it
131 */
132static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
133{
134 struct sgsn_mm_ctx *ctx, *ictx;
135 struct gprs_llc_lle *lle;
136 int old_count = count(gprs_llme_list());
137
138 lle = gprs_lle_get_or_create(tlli, 3);
139 ctx = sgsn_mm_ctx_alloc(tlli, raid);
140 ctx->mm_state = GMM_REGISTERED_NORMAL;
141 ctx->llme = lle->llme;
142
143 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
144 OSMO_ASSERT(ictx == ctx);
145
146 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
147
148 return ctx;
149}
150
Jacob Erlbeck75488292014-10-29 10:31:18 +0100151static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
152 const uint8_t *data, size_t data_len)
153{
154 struct msgb *msg;
155
156 sgsn_tx_counter = 0;
157
158 msg = create_msg(data, data_len);
159 msgb_tlli(msg) = tlli;
160 gsm0408_gprs_rcvmsg(msg, llme);
161 msgb_free(msg);
162}
163
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200164static void test_llme(void)
165{
166 struct gprs_llc_lle *lle, *lle_copy;
167 uint32_t local_tlli;
168 uint32_t foreign_tlli;
169
170 printf("Testing LLME allocations\n");
171 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
172 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
173
174 /* initial state */
175 OSMO_ASSERT(count(gprs_llme_list()) == 0);
176
177 /* Create a new entry */
178 lle = gprs_lle_get_or_create(local_tlli, 3);
179 OSMO_ASSERT(lle);
180 OSMO_ASSERT(count(gprs_llme_list()) == 1);
181
182 /* No new entry is created */
183 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
184 OSMO_ASSERT(lle == lle_copy);
185 OSMO_ASSERT(count(gprs_llme_list()) == 1);
186 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
187 OSMO_ASSERT(lle == lle_copy);
188 OSMO_ASSERT(count(gprs_llme_list()) == 1);
189
190 /* unassign which should delete it*/
191 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
192
193 /* Check that everything was cleaned up */
194 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200195
196 cleanup_test();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200197}
198
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100199struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100200void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100201{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100202 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100203 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100204 __func__, mmctx, mmctx->subscr);
205 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100206}
207
Jacob Erlbecka695d242015-01-09 11:59:50 +0100208static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
209{
210 struct gsm_subscriber *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100211 OSMO_ASSERT(subscr);
212 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100213
214 sfound = gprs_subscr_get_by_imsi(imsi);
215 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100216
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100217 subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100218}
219
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100220static void show_subscrs(FILE *out)
221{
222 struct gsm_subscriber *subscr;
223
224 llist_for_each_entry(subscr, &active_subscribers, entry) {
225 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100226 "use count: %d\n",
227 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100228 }
229}
230
231static void assert_no_subscrs()
232{
233 show_subscrs(stdout);
234 fflush(stdout);
235 OSMO_ASSERT(llist_empty(&active_subscribers));
236}
237
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100238static void test_subscriber(void)
239{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100240 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100241 const char *imsi1 = "1234567890";
242 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100243 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100244
245 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
246
247 printf("Testing core subscriber data API\n");
248
249 /* Check for emptiness */
250 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
251 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100252 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100253
254 /* Allocate entry 1 */
255 s1 = gprs_subscr_get_or_create(imsi1);
256 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100257 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100258 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100259
260 /* Allocate entry 2 */
261 s2 = gprs_subscr_get_or_create(imsi2);
262 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100263
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100264 /* Allocate entry 3 */
265 s3 = gprs_subscr_get_or_create(imsi3);
266
Jacob Erlbecka695d242015-01-09 11:59:50 +0100267 /* Check entries */
268 assert_subscr(s1, imsi1);
269 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100270 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100271
272 /* Update entry 1 */
273 last_updated_subscr = NULL;
274 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100275 OSMO_ASSERT(last_updated_subscr == NULL);
276 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
277 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100278
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100279 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100280 gprs_subscr_cleanup(s1);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100281 subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100282 s1 = NULL;
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100283 sfound = gprs_subscr_get_by_imsi(imsi1);
284 OSMO_ASSERT(sfound == NULL);
285
Jacob Erlbecka695d242015-01-09 11:59:50 +0100286 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100287 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100288
Jacob Erlbecka695d242015-01-09 11:59:50 +0100289 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100290 gprs_subscr_cleanup(s2);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100291 subscr_put(s2);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100292 s2 = NULL;
293 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
294 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100295 assert_subscr(s3, imsi3);
296
297 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100298 gprs_subscr_cleanup(s3);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100299 subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100300 s3 = NULL;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100301 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100302
303 OSMO_ASSERT(llist_empty(&active_subscribers));
304
305 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200306
307 cleanup_test();
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100308}
309
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100310static void test_auth_triplets(void)
311{
312 struct gsm_subscriber *s1, *s1found;
313 const char *imsi1 = "1234567890";
314 struct gsm_auth_tuple *at;
315 struct sgsn_mm_ctx *ctx;
316 struct gprs_ra_id raid = { 0, };
317 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100318
319 printf("Testing authentication triplet handling\n");
320
321 /* Check for emptiness */
322 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
323
324 /* Allocate entry 1 */
325 s1 = gprs_subscr_get_or_create(imsi1);
326 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
327 s1found = gprs_subscr_get_by_imsi(imsi1);
328 OSMO_ASSERT(s1found == s1);
329 subscr_put(s1found);
330
331 /* Create a context */
332 OSMO_ASSERT(count(gprs_llme_list()) == 0);
333 ctx = alloc_mm_ctx(local_tlli, &raid);
334
335 /* Attach s1 to ctx */
336 ctx->subscr = subscr_get(s1);
337 ctx->subscr->sgsn_data->mm = ctx;
338
339 /* Try to get auth tuple */
340 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
341 OSMO_ASSERT(at == NULL);
342
343 /* Add triplets */
344 s1->sgsn_data->auth_triplets[0].key_seq = 0;
345 s1->sgsn_data->auth_triplets[1].key_seq = 1;
346 s1->sgsn_data->auth_triplets[2].key_seq = 2;
347
348 /* Try to get auth tuple */
349 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
350 OSMO_ASSERT(at != NULL);
351 OSMO_ASSERT(at->key_seq == 0);
352 OSMO_ASSERT(at->use_count == 1);
353 at = sgsn_auth_get_tuple(ctx, at->key_seq);
354 OSMO_ASSERT(at != NULL);
355 OSMO_ASSERT(at->key_seq == 1);
356 OSMO_ASSERT(at->use_count == 1);
357 at = sgsn_auth_get_tuple(ctx, at->key_seq);
358 OSMO_ASSERT(at != NULL);
359 OSMO_ASSERT(at->key_seq == 2);
360 OSMO_ASSERT(at->use_count == 1);
361 at = sgsn_auth_get_tuple(ctx, at->key_seq);
362 OSMO_ASSERT(at == NULL);
363
364 /* Free MM context and subscriber */
365 subscr_put(s1);
Jacob Erlbeck70c177a2015-01-26 14:43:07 +0100366 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100367 s1found = gprs_subscr_get_by_imsi(imsi1);
368 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200369
370 cleanup_test();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100371}
372
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100373#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
374
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100375static int rx_gsup_message(const uint8_t *data, size_t data_len)
376{
377 struct msgb *msg;
378 int rc;
379
380 msg = msgb_alloc(1024, __func__);
381 msg->l2h = msgb_put(msg, data_len);
382 OSMO_ASSERT(msg->l2h != NULL);
383 memcpy(msg->l2h, data, data_len);
384 rc = gprs_subscr_rx_gsup_message(msg);
385 msgb_free(msg);
386
387 return rc;
388}
389
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100390static void test_subscriber_gsup(void)
391{
392 struct gsm_subscriber *s1, *s1found;
393 const char *imsi1 = "1234567890";
394 struct sgsn_mm_ctx *ctx;
395 struct gprs_ra_id raid = { 0, };
396 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100397 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100398 int rc;
399
400 static const uint8_t send_auth_info_res[] = {
401 0x0a,
402 TEST_GSUP_IMSI1_IE,
403 0x03, 0x22, /* Auth tuple */
404 0x20, 0x10,
405 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
406 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
407 0x21, 0x04,
408 0x21, 0x22, 0x23, 0x24,
409 0x22, 0x08,
410 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
411 0x03, 0x22, /* Auth tuple */
412 0x20, 0x10,
413 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
414 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
415 0x21, 0x04,
416 0xa1, 0xa2, 0xa3, 0xa4,
417 0x22, 0x08,
418 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
419 };
420
421 static const uint8_t send_auth_info_err[] = {
422 0x09,
423 TEST_GSUP_IMSI1_IE,
424 0x02, 0x01, 0x07 /* GPRS not allowed */
425 };
426
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400427#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
428
429 static const uint8_t s1_msisdn[] = { MSISDN };
430
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100431 static const uint8_t update_location_res[] = {
432 0x06,
433 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400434 0x08, 0x09, MSISDN,
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100435 0x04, 0x00, /* PDP info complete */
436 0x05, 0x12,
437 0x10, 0x01, 0x01,
438 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
439 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
440 0x05, 0x11,
441 0x10, 0x01, 0x02,
442 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
443 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
444 };
445
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400446#undef MSISDN
447
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100448 static const uint8_t update_location_err[] = {
449 0x05,
450 TEST_GSUP_IMSI1_IE,
451 0x02, 0x01, 0x07 /* GPRS not allowed */
452 };
453
454 static const uint8_t location_cancellation_req[] = {
455 0x1c,
456 TEST_GSUP_IMSI1_IE,
457 0x06, 0x01, 0x00,
458 };
459
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200460 static const uint8_t location_cancellation_req_withdraw[] = {
461 0x1c,
462 TEST_GSUP_IMSI1_IE,
463 0x06, 0x01, 0x01,
464 };
465
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100466 static const uint8_t location_cancellation_req_other[] = {
467 0x1c,
468 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
469 0x06, 0x01, 0x00,
470 };
471
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100472 static const uint8_t purge_ms_err[] = {
473 0x0d,
474 TEST_GSUP_IMSI1_IE,
475 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
476 };
477
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100478 static const uint8_t purge_ms_err_no_cause[] = {
479 0x0d,
480 TEST_GSUP_IMSI1_IE,
481 };
482
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100483 static const uint8_t purge_ms_res[] = {
484 0x0e,
485 TEST_GSUP_IMSI1_IE,
486 0x07, 0x00,
487 };
488
489
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100490 static const uint8_t insert_data_req[] = {
491 0x10,
492 TEST_GSUP_IMSI1_IE,
493 0x05, 0x11,
494 0x10, 0x01, 0x03,
495 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
496 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
497 };
498
499 static const uint8_t delete_data_req[] = {
500 0x14,
501 TEST_GSUP_IMSI1_IE,
502 0x10, 0x01, 0x03,
503 };
504
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100505 printf("Testing subcriber GSUP handling\n");
506
507 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
508
509 /* Check for emptiness */
510 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
511
512 /* Allocate entry 1 */
513 s1 = gprs_subscr_get_or_create(imsi1);
514 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
515 s1found = gprs_subscr_get_by_imsi(imsi1);
516 OSMO_ASSERT(s1found == s1);
517 subscr_put(s1found);
518
519 /* Create a context */
520 OSMO_ASSERT(count(gprs_llme_list()) == 0);
521 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100522
523 /* Attach s1 to ctx */
524 ctx->subscr = subscr_get(s1);
525 ctx->subscr->sgsn_data->mm = ctx;
526
527 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100528 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100529 OSMO_ASSERT(rc >= 0);
530 OSMO_ASSERT(last_updated_subscr == s1);
531
532 /* Check triplets */
533 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
534 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
535 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
536
537 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100538 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100539 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100540 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100541 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100542
543 /* Check triplets */
544 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
545 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
546 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
547
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100548 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100549 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100550 OSMO_ASSERT(rc >= 0);
551 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100552 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100553 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400554 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
555 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100556 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
557 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
558 struct sgsn_subscriber_pdp_data, list);
559 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
560 pdpd = llist_entry(pdpd->list.next,
561 struct sgsn_subscriber_pdp_data, list);
562 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100563
564 /* Check authorization */
565 OSMO_ASSERT(s1->authorized == 1);
566
567 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100568 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100569 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100570 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100571 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100572
573 /* Check authorization */
574 OSMO_ASSERT(s1->authorized == 0);
575
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100576 /* Inject InsertSubscrData GSUP message */
577 last_updated_subscr = NULL;
578 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
579 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
580 OSMO_ASSERT(last_updated_subscr == NULL);
581
582 /* Inject DeleteSubscrData GSUP message */
583 last_updated_subscr = NULL;
584 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
585 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
586 OSMO_ASSERT(last_updated_subscr == NULL);
587
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100588 /* Inject wrong LocCancelReq GSUP message */
589 last_updated_subscr = NULL;
590 rc = rx_gsup_message(location_cancellation_req_other,
591 sizeof(location_cancellation_req_other));
592 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
593 OSMO_ASSERT(last_updated_subscr == NULL);
594
595 /* Check cancellation result */
596 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
597 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
598
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100599 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100600 rc = rx_gsup_message(location_cancellation_req,
601 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100602 OSMO_ASSERT(rc >= 0);
603 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100604 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100605
606 /* Check cancellation result */
607 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
608 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
609
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200610 /* Inject LocCancelReq(withdraw) GSUP message */
611 rc = rx_gsup_message(location_cancellation_req_withdraw,
612 sizeof(location_cancellation_req_withdraw));
613 OSMO_ASSERT(rc >= 0);
614 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
615
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100616 /* Inject PurgeMsRes GSUP message */
617 rc = rx_gsup_message(purge_ms_res,
618 sizeof(purge_ms_res));
619 OSMO_ASSERT(rc >= 0);
620 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
621
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100622 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100623 OSMO_ASSERT(ctx->subscr == NULL);
624 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100625 subscr_put(s1);
626 s1found = gprs_subscr_get_by_imsi(imsi1);
627 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100628
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100629 /* Inject PurgeMsRes GSUP message */
630 rc = rx_gsup_message(purge_ms_res,
631 sizeof(purge_ms_res));
632 OSMO_ASSERT(rc >= 0);
633
634 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
635 rc = rx_gsup_message(purge_ms_err,
636 sizeof(purge_ms_err));
637 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
638
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100639 /* Inject PurgeMsErr() GSUP message */
640 rc = rx_gsup_message(purge_ms_err_no_cause,
641 sizeof(purge_ms_err_no_cause));
642 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
643
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100644 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
645 last_updated_subscr = NULL;
646 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100647 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100648 OSMO_ASSERT(last_updated_subscr == NULL);
649
650 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
651 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
652 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
653 OSMO_ASSERT(last_updated_subscr == NULL);
654
655 /* Inject LocCancelReq GSUP message (unknown IMSI) */
656 rc = rx_gsup_message(location_cancellation_req,
657 sizeof(location_cancellation_req));
658 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
659 OSMO_ASSERT(last_updated_subscr == NULL);
660
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100661 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200662
663 cleanup_test();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100664}
665
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100666int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
667{
668 msgb_free(msg);
669 return 0;
670};
671
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200672/*
673 * Test that a GMM Detach will remove the MMCTX and the
674 * associated LLME.
675 */
676static void test_gmm_detach(void)
677{
678 struct gprs_ra_id raid = { 0, };
679 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200680 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200681
682 printf("Testing GMM detach\n");
683
684 /* DTAP - Detach Request (MO) */
685 /* normal detach, power_off = 0 */
686 static const unsigned char detach_req[] = {
687 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
688 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
689 };
690
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200691 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200692
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100693 /* Create a context */
694 OSMO_ASSERT(count(gprs_llme_list()) == 0);
695 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200696
697 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100698 send_0408_message(ctx->llme, local_tlli,
699 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200700
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100701 /* verify that a single message (hopefully the Detach Accept) has been
702 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100703 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100704
705 /* verify that things are gone */
706 OSMO_ASSERT(count(gprs_llme_list()) == 0);
707 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
708 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200709
710 cleanup_test();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100711}
712
713/*
714 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
715 * will not sent a Detach Accept message (power_off = 1)
716 */
717static void test_gmm_detach_power_off(void)
718{
719 struct gprs_ra_id raid = { 0, };
720 struct sgsn_mm_ctx *ctx, *ictx;
721 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100722
723 printf("Testing GMM detach (power off)\n");
724
725 /* DTAP - Detach Request (MO) */
726 /* normal detach, power_off = 1 */
727 static const unsigned char detach_req[] = {
728 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
729 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
730 };
731
732 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
733
734 /* Create a context */
735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
736 ctx = alloc_mm_ctx(local_tlli, &raid);
737
738 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100739 send_0408_message(ctx->llme, local_tlli,
740 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100741
742 /* verify that no message (and therefore no Detach Accept) has been
743 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100744 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100745
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200746 /* verify that things are gone */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200749 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200750
751 cleanup_test();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200752}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200753
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200754/*
755 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
756 */
757static void test_gmm_detach_no_mmctx(void)
758{
759 struct gprs_llc_lle *lle;
760 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200761
762 printf("Testing GMM detach (no MMCTX)\n");
763
764 /* DTAP - Detach Request (MO) */
765 /* normal detach, power_off = 0 */
766 static const unsigned char detach_req[] = {
767 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
768 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
769 };
770
771 /* Create an LLME */
772 OSMO_ASSERT(count(gprs_llme_list()) == 0);
773 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
774 lle = gprs_lle_get_or_create(local_tlli, 3);
775
776 OSMO_ASSERT(count(gprs_llme_list()) == 1);
777
778 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100779 send_0408_message(lle->llme, local_tlli,
780 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200781
782 /* verify that the LLME is gone */
783 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200784
785 cleanup_test();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200786}
787
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100788/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100789 * Test that a single GMM Detach Accept message will not cause the SGSN to send
790 * any message or leave an MM context at the SGSN.
791 */
792static void test_gmm_detach_accept_unexpected(void)
793{
794 struct gprs_llc_lle *lle;
795 uint32_t local_tlli;
796
797 printf("Testing GMM detach accept (unexpected)\n");
798
799 /* DTAP - Detach Accept (MT) */
800 /* normal detach */
801 static const unsigned char detach_acc[] = {
802 0x08, 0x06
803 };
804
805 /* Create an LLME */
806 OSMO_ASSERT(count(gprs_llme_list()) == 0);
807 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
808 lle = gprs_lle_get_or_create(local_tlli, 3);
809
810 /* inject the detach */
811 send_0408_message(lle->llme, local_tlli,
812 detach_acc, ARRAY_SIZE(detach_acc));
813
814 /* verify that no message (and therefore no Status or XID reset) has been
815 * sent by the SGSN */
816 OSMO_ASSERT(sgsn_tx_counter == 0);
817
818 /* verify that things are gone */
819 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200820
821 cleanup_test();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100822}
823
824/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100825 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
826 */
827static void test_gmm_status_no_mmctx(void)
828{
829 struct gprs_llc_lle *lle;
830 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100831
832 printf("Testing GMM Status (no MMCTX)\n");
833
834 /* DTAP - GMM Status, protocol error */
835 static const unsigned char gmm_status[] = {
836 0x08, 0x20, 0x6f
837 };
838
839 /* Create an LLME */
840 OSMO_ASSERT(count(gprs_llme_list()) == 0);
841 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
842 lle = gprs_lle_get_or_create(local_tlli, 3);
843
844 OSMO_ASSERT(count(gprs_llme_list()) == 1);
845
846 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100847 send_0408_message(lle->llme, local_tlli,
848 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100849
850 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100851 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100852
853 /* verify that the LLME is gone */
854 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200855
856 cleanup_test();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100857}
858
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100859/*
860 * Test the GMM Attach procedure
861 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100862static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100863{
864 struct gprs_ra_id raid = { 0, };
865 struct sgsn_mm_ctx *ctx = NULL;
866 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100867 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100868 uint32_t foreign_tlli;
869 uint32_t local_tlli = 0;
870 struct gprs_llc_lle *lle;
871
872 /* DTAP - Attach Request */
873 /* The P-TMSI is not known by the SGSN */
874 static const unsigned char attach_req[] = {
875 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
876 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
877 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
878 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
879 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
880 };
881
882 /* DTAP - Identity Response IMEI */
883 static const unsigned char ident_resp_imei[] = {
884 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
885 0x56
886 };
887
888 /* DTAP - Identity Response IMSI */
889 static const unsigned char ident_resp_imsi[] = {
890 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
891 0x54
892 };
893
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100894 /* DTAP - Authentication and Ciphering Resp */
895 static const unsigned char auth_ciph_resp[] = {
896 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
897 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
898 };
899
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100900 /* DTAP - Attach Complete */
901 static const unsigned char attach_compl[] = {
902 0x08, 0x03
903 };
904
905 /* DTAP - Detach Request (MO) */
906 /* normal detach, power_off = 0 */
907 static const unsigned char detach_req[] = {
908 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
909 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
910 };
911
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100912 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100913
914 /* reset the PRNG used by sgsn_alloc_ptmsi */
915 srand(1);
916
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100917 ptmsi1 = sgsn_alloc_ptmsi();
918 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
919
920 /* reset the PRNG, so that the same P-TMSI sequence will be generated
921 * again */
922 srand(1);
923
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100924 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
925
926 /* Create a LLE/LLME */
927 OSMO_ASSERT(count(gprs_llme_list()) == 0);
928 lle = gprs_lle_get_or_create(foreign_tlli, 3);
929 OSMO_ASSERT(count(gprs_llme_list()) == 1);
930
931 /* inject the attach request */
932 send_0408_message(lle->llme, foreign_tlli,
933 attach_req, ARRAY_SIZE(attach_req));
934
935 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
936 OSMO_ASSERT(ctx != NULL);
937 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
938
939 /* we expect an identity request (IMEI) */
940 OSMO_ASSERT(sgsn_tx_counter == 1);
941
942 /* inject the identity response (IMEI) */
943 send_0408_message(ctx->llme, foreign_tlli,
944 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
945
946 /* we expect an identity request (IMSI) */
947 OSMO_ASSERT(sgsn_tx_counter == 1);
948
949 /* inject the identity response (IMSI) */
950 send_0408_message(ctx->llme, foreign_tlli,
951 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
952
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100953 /* check that the MM context has not been removed due to a failed
954 * authorization */
955 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
956
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100957 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100958
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100959retry_attach_req:
960
961 if (retry && sgsn_tx_counter == 0) {
962 fprintf(stderr, "Retrying attach request\n");
963 /* re-inject the attach request */
964 send_0408_message(lle->llme, foreign_tlli,
965 attach_req, ARRAY_SIZE(attach_req));
966 }
967
968 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
969 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100970
971 /* inject the auth & ciph response */
972 send_0408_message(ctx->llme, foreign_tlli,
973 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
974
975 /* check that the MM context has not been removed due to a
976 * failed authorization */
977 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +0200978 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
979 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100980 }
981
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100982 if (retry && sgsn_tx_counter == 0)
983 goto retry_attach_req;
984
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100985 /* we expect an attach accept/reject */
986 OSMO_ASSERT(sgsn_tx_counter == 1);
987
988 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100989 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100990
991 /* inject the attach complete */
992 send_0408_message(ctx->llme, local_tlli,
993 attach_compl, ARRAY_SIZE(attach_compl));
994
995 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
996
997 /* we don't expect a response */
998 OSMO_ASSERT(sgsn_tx_counter == 0);
999
1000 /* inject the detach */
1001 send_0408_message(ctx->llme, local_tlli,
1002 detach_req, ARRAY_SIZE(detach_req));
1003
1004 /* verify that things are gone */
1005 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1006 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1007 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001008
1009 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001010}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001011
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001012static void test_gmm_attach_acl(void)
1013{
1014 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1015
1016 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1017 sgsn_acl_add("123456789012345", &sgsn->cfg);
1018 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001019 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001020 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001021
1022 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001023
1024 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001025}
1026
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001027int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001028 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001029 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001030 if (rc == -ENOTSUP) {
1031 OSMO_ASSERT(mmctx->subscr);
1032 gprs_subscr_update(mmctx->subscr);
1033 }
1034 return rc;
1035};
1036
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001037int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1038 gprs_subscr_update(mmctx->subscr);
1039 return 0;
1040};
1041
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001042static void test_gmm_attach_subscr(void)
1043{
1044 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1045 struct gsm_subscriber *subscr;
1046
1047 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001048 subscr_request_update_location_cb = my_subscr_request_update_location;
1049 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001050
1051 subscr = gprs_subscr_get_or_create("123456789012345");
1052 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001053
1054 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001055 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001056 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001057 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001058
1059 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001060 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1061 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001062
1063 cleanup_test();
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001064}
1065
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001066int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1067{
1068 /* Fake an authentication */
1069 OSMO_ASSERT(mmctx->subscr);
1070 mmctx->is_authenticated = 1;
1071 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001072
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001073 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001074};
1075
1076static void test_gmm_attach_subscr_fake_auth(void)
1077{
1078 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1079 struct gsm_subscriber *subscr;
1080
1081 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001082 subscr_request_update_location_cb = my_subscr_request_update_location;
1083 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001084
1085 subscr = gprs_subscr_get_or_create("123456789012345");
1086 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001087 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001088 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001089
1090 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001091 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001092 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001093 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001094
1095 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001096 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1097 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001098
1099 cleanup_test();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001100}
1101
1102int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1103{
1104 struct gsm_auth_tuple at = {
1105 .sres = {0x51, 0xe5, 0x51, 0xe5},
1106 .key_seq = 0
1107 };
1108
1109 /* Fake an authentication */
1110 OSMO_ASSERT(mmctx->subscr);
1111 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1112
1113 gprs_subscr_update_auth_info(mmctx->subscr);
1114
1115 return 0;
1116};
1117
1118static void test_gmm_attach_subscr_real_auth(void)
1119{
1120 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1121 struct gsm_subscriber *subscr;
1122
1123 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1124 subscr_request_update_location_cb = my_subscr_request_update_location;
1125 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1126
1127 subscr = gprs_subscr_get_or_create("123456789012345");
1128 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001129 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001130 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001131
1132 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001133
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001134 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001135 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001136 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001137
1138 sgsn->cfg.auth_policy = saved_auth_policy;
1139 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1140 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001141
1142 cleanup_test();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001143}
1144
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001145#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1146 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1147
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001148static int auth_info_skip = 0;
1149static int upd_loc_skip = 0;
1150
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001151int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1152{
1153 static const uint8_t send_auth_info_res[] = {
1154 0x0a,
1155 TEST_GSUP_IMSI_LONG_IE,
1156 0x03, 0x22, /* Auth tuple */
1157 0x20, 0x10,
1158 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1159 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1160 0x21, 0x04,
1161 0x51, 0xe5, 0x51, 0xe5,
1162 0x22, 0x08,
1163 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1164 };
1165
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001166 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001167
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001168 if (auth_info_skip > 0) {
1169 auth_info_skip -= 1;
1170 return -EAGAIN;
1171 }
1172
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001173 /* Fake an SendAuthInfoRes */
1174 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1175
1176 return 0;
1177};
1178
1179int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1180 static const uint8_t update_location_res[] = {
1181 0x06,
1182 TEST_GSUP_IMSI_LONG_IE,
1183 0x04, 0x00, /* PDP info complete */
1184 0x05, 0x12,
1185 0x10, 0x01, 0x01,
1186 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1187 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001188 0x08, 0x07, /* MSISDN 49166213323 encoded */
1189 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freytherfe4a9f62015-05-17 20:58:40 +02001190 0x09, 0x07, /* MSISDN 38166213323 encoded */
1191 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001192 };
1193
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001194 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001195
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001196 if (upd_loc_skip > 0) {
1197 upd_loc_skip -= 1;
1198 return -EAGAIN;
1199 }
1200
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001201 /* Fake an UpdateLocRes */
1202 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1203};
1204
1205
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001206static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001207{
1208 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1209 struct gsm_subscriber *subscr;
1210
1211 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1212 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1213 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001214 if (retry) {
1215 upd_loc_skip = 3;
1216 auth_info_skip = 3;
1217 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001218
1219 subscr = gprs_subscr_get_or_create("123456789012345");
1220 subscr->authorized = 1;
1221 sgsn->cfg.require_authentication = 1;
1222 sgsn->cfg.require_update_location = 1;
1223 subscr_put(subscr);
1224
1225 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001226 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001227 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001228
1229 sgsn->cfg.auth_policy = saved_auth_policy;
1230 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1231 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001232 upd_loc_skip = 0;
1233 auth_info_skip = 0;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001234
1235 cleanup_test();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001236}
1237
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001238int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1239{
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001240 struct gprs_gsup_message to_peer = {0};
1241 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001242 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001243 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001244
1245 /* Simulate the GSUP peer */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001246 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1247 OSMO_ASSERT(rc >= 0);
1248 OSMO_ASSERT(to_peer.imsi[0] != 0);
1249 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001250
1251 /* This invalidates the pointers in to_peer */
1252 msgb_free(msg);
1253
1254 switch (to_peer.message_type) {
1255 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1256 /* Send UPDATE_LOCATION_RESULT */
1257 return my_subscr_request_update_gsup_auth(NULL);
1258
1259 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1260 /* Send SEND_AUTH_INFO_RESULT */
1261 return my_subscr_request_auth_info_gsup_auth(NULL);
1262
1263 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001264 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1265 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001266
1267 default:
1268 if ((to_peer.message_type & 0b00000011) == 0) {
1269 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001270 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001271 from_peer.message_type = to_peer.message_type + 1;
1272 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1273 break;
1274 }
1275
1276 /* Ignore it */
1277 return 0;
1278 }
1279
1280 reply_msg = gprs_gsup_msgb_alloc();
1281 reply_msg->l2h = reply_msg->data;
1282 gprs_gsup_encode(reply_msg, &from_peer);
1283 gprs_subscr_rx_gsup_message(reply_msg);
1284 msgb_free(reply_msg);
1285
1286 return 0;
1287};
1288
1289static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1290{
1291 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1292 struct gsm_subscriber *subscr;
1293
1294 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001295 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1296
1297 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1298
1299 if (retry) {
1300 upd_loc_skip = 3;
1301 auth_info_skip = 3;
1302 }
1303
1304 printf("Auth policy 'remote', real GSUP based auth: ");
1305 test_gmm_attach(retry);
1306
1307 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001308 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001309 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001310
1311 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001312 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1313 upd_loc_skip = 0;
1314 auth_info_skip = 0;
1315 talloc_free(sgsn->gsup_client);
1316 sgsn->gsup_client = NULL;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001317
1318 cleanup_test();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001319}
1320
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001321/*
1322 * Test the GMM Rejects
1323 */
1324static void test_gmm_reject(void)
1325{
1326 struct gprs_ra_id raid = { 0, };
1327 struct sgsn_mm_ctx *ctx = NULL;
1328 uint32_t foreign_tlli;
1329 struct gprs_llc_lle *lle;
1330 int idx;
1331
1332 /* DTAP - Attach Request */
1333 /* Invalid MI length */
1334 static const unsigned char attach_req_inv_mi_len[] = {
1335 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1336 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1337 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1338 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1339 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1340 };
1341
1342 /* DTAP - Attach Request */
1343 /* Invalid MI type (IMEI) */
1344 static const unsigned char attach_req_inv_mi_type[] = {
1345 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1346 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1347 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1348 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1349 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1350 };
1351
1352 /* DTAP - Routing Area Update Request */
1353 static const unsigned char dtap_ra_upd_req[] = {
1354 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1355 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1356 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1357 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1358 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1359 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1360 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1361 };
1362
1363 /* DTAP - Routing Area Update Request */
1364 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1365 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1366 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1367 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1368 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1369 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1370 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1371 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1372 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1373 };
1374
1375 /* DTAP - Routing Area Update Request */
1376 /* Invalid cap length */
1377 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1378 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1379 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1380 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1381 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1382 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1383 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1384 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1385 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1386 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1387 };
1388
1389 struct test {
1390 const char *title;
1391 const unsigned char *msg;
1392 unsigned msg_len;
1393 unsigned num_resp;
1394
1395 };
1396 static struct test tests[] = {
1397 {
1398 .title = "Attach Request (invalid MI length)",
1399 .msg = attach_req_inv_mi_len,
1400 .msg_len = sizeof(attach_req_inv_mi_len),
1401 .num_resp = 1 /* Reject */
1402
1403 },
1404 {
1405 .title = "Attach Request (invalid MI type)",
1406 .msg = attach_req_inv_mi_type,
1407 .msg_len = sizeof(attach_req_inv_mi_type),
1408 .num_resp = 1 /* Reject */
1409 },
1410 {
1411 .title = "Routing Area Update Request (valid)",
1412 .msg = dtap_ra_upd_req,
1413 .msg_len = sizeof(dtap_ra_upd_req),
1414 .num_resp = 2 /* XID Reset + Reject */
1415 },
1416 {
1417 .title = "Routing Area Update Request (invalid type)",
1418 .msg = dtap_ra_upd_req_inv_type,
1419 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1420 .num_resp = 1 /* Reject */
1421 },
1422 {
1423 .title = "Routing Area Update Request (invalid CAP length)",
1424 .msg = dtap_ra_upd_req_inv_cap_len,
1425 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1426 .num_resp = 1 /* Reject */
1427 },
1428 };
1429
1430 printf("Testing GMM reject\n");
1431
1432 /* reset the PRNG used by sgsn_alloc_ptmsi */
1433 srand(1);
1434
1435 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1436
1437 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1438
1439 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1440 const struct test *test = &tests[idx];
1441 printf(" - %s\n", test->title);
1442
1443 /* Create a LLE/LLME */
1444 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1445 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1446
1447 /* Inject the Request message */
1448 send_0408_message(lle->llme, foreign_tlli,
1449 test->msg, test->msg_len);
1450
1451 /* We expect a Reject message */
1452 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1453 sgsn_tx_counter, test->num_resp);
1454 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1455
1456 /* verify that LLME/MM are removed */
1457 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1458 OSMO_ASSERT(ctx == NULL);
1459 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1460 }
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001461
1462 cleanup_test();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001463}
1464
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001465/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001466 * Test cancellation of attached MM contexts
1467 */
1468static void test_gmm_cancel(void)
1469{
1470 struct gprs_ra_id raid = { 0, };
1471 struct sgsn_mm_ctx *ctx = NULL;
1472 struct sgsn_mm_ctx *ictx;
1473 uint32_t ptmsi1;
1474 uint32_t foreign_tlli;
1475 uint32_t local_tlli = 0;
1476 struct gprs_llc_lle *lle;
1477 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1478
1479 /* DTAP - Attach Request */
1480 /* The P-TMSI is not known by the SGSN */
1481 static const unsigned char attach_req[] = {
1482 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1483 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1484 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1485 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1486 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1487 };
1488
1489 /* DTAP - Identity Response IMEI */
1490 static const unsigned char ident_resp_imei[] = {
1491 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1492 0x56
1493 };
1494
1495 /* DTAP - Identity Response IMSI */
1496 static const unsigned char ident_resp_imsi[] = {
1497 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1498 0x54
1499 };
1500
1501 /* DTAP - Attach Complete */
1502 static const unsigned char attach_compl[] = {
1503 0x08, 0x03
1504 };
1505
1506 printf("Testing cancellation\n");
1507
1508 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1509
1510 /* reset the PRNG used by sgsn_alloc_ptmsi */
1511 srand(1);
1512
1513 ptmsi1 = sgsn_alloc_ptmsi();
1514 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1515
1516 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1517 * again */
1518 srand(1);
1519
1520 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1521
1522 /* Create a LLE/LLME */
1523 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1524 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1525 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1526
1527 /* inject the attach request */
1528 send_0408_message(lle->llme, foreign_tlli,
1529 attach_req, ARRAY_SIZE(attach_req));
1530
1531 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1532 OSMO_ASSERT(ctx != NULL);
1533 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1534
1535 /* we expect an identity request (IMEI) */
1536 OSMO_ASSERT(sgsn_tx_counter == 1);
1537
1538 /* inject the identity response (IMEI) */
1539 send_0408_message(ctx->llme, foreign_tlli,
1540 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1541
1542 /* we expect an identity request (IMSI) */
1543 OSMO_ASSERT(sgsn_tx_counter == 1);
1544
1545 /* inject the identity response (IMSI) */
1546 send_0408_message(ctx->llme, foreign_tlli,
1547 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1548
1549 /* check that the MM context has not been removed due to a failed
1550 * authorization */
1551 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1552
1553 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1554
1555 /* we expect an attach accept/reject */
1556 OSMO_ASSERT(sgsn_tx_counter == 1);
1557
1558 /* this has been randomly assigned by the SGSN */
1559 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1560
1561 /* inject the attach complete */
1562 send_0408_message(ctx->llme, local_tlli,
1563 attach_compl, ARRAY_SIZE(attach_compl));
1564
1565 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1566
1567 /* we don't expect a response */
1568 OSMO_ASSERT(sgsn_tx_counter == 0);
1569
1570 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001571 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001572
1573 /* verify that things are gone */
1574 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1575 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1576 OSMO_ASSERT(!ictx);
1577
1578 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001579
1580 cleanup_test();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001581}
1582
1583/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001584 * Test the dynamic allocation of P-TMSIs
1585 */
1586static void test_gmm_ptmsi_allocation(void)
1587{
1588 struct gprs_ra_id raid = { 0, };
1589 struct sgsn_mm_ctx *ctx = NULL;
1590 struct sgsn_mm_ctx *ictx;
1591 uint32_t foreign_tlli;
1592 uint32_t ptmsi1;
1593 uint32_t ptmsi2;
1594 uint32_t old_ptmsi;
1595 uint32_t local_tlli = 0;
1596 struct gprs_llc_lle *lle;
1597 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1598
1599 /* DTAP - Attach Request (IMSI 12131415161718) */
1600 static const unsigned char attach_req[] = {
1601 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1602 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1603 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1604 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1605 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1606 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1607 0x00,
1608 };
1609
1610 /* DTAP - Identity Response IMEI */
1611 static const unsigned char ident_resp_imei[] = {
1612 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1613 0x56
1614 };
1615
1616 /* DTAP - Attach Complete */
1617 static const unsigned char attach_compl[] = {
1618 0x08, 0x03
1619 };
1620
1621 /* DTAP - Routing Area Update Request */
1622 static const unsigned char ra_upd_req[] = {
1623 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1624 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1625 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1626 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1627 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1628 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1629 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1630 };
1631
1632 /* DTAP - Routing Area Update Complete */
1633 static const unsigned char ra_upd_complete[] = {
1634 0x08, 0x0a
1635 };
1636
1637 /* DTAP - Detach Request (MO) */
1638 /* normal detach, power_off = 1 */
1639 static const unsigned char detach_req[] = {
1640 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1641 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1642 };
1643
1644 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1645
1646 printf("Testing P-TMSI allocation\n");
1647
1648 printf(" - sgsn_alloc_ptmsi\n");
1649
1650 /* reset the PRNG used by sgsn_alloc_ptmsi */
1651 srand(1);
1652
1653 ptmsi1 = sgsn_alloc_ptmsi();
1654 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1655
1656 ptmsi2 = sgsn_alloc_ptmsi();
1657 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1658
1659 OSMO_ASSERT(ptmsi1 != ptmsi2);
1660
1661 printf(" - Repeated Attach Request\n");
1662
1663 /* reset the PRNG, so that the same P-TMSI will be generated
1664 * again */
1665 srand(1);
1666
1667 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1668
1669 /* Create a LLE/LLME */
1670 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1671 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1672 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1673
1674 /* inject the attach request */
1675 send_0408_message(lle->llme, foreign_tlli,
1676 attach_req, ARRAY_SIZE(attach_req));
1677
1678 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1679 OSMO_ASSERT(ctx != NULL);
1680 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1681 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1682
1683 old_ptmsi = ctx->p_tmsi_old;
1684
1685 /* we expect an identity request (IMEI) */
1686 OSMO_ASSERT(sgsn_tx_counter == 1);
1687
1688 /* inject the identity response (IMEI) */
1689 send_0408_message(ctx->llme, foreign_tlli,
1690 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1691
1692 /* check that the MM context has not been removed due to a failed
1693 * authorization */
1694 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1695
1696 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1697 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1698
1699 /* we expect an attach accept */
1700 OSMO_ASSERT(sgsn_tx_counter == 1);
1701
1702 /* we ignore this and send the attach again */
1703 send_0408_message(lle->llme, foreign_tlli,
1704 attach_req, ARRAY_SIZE(attach_req));
1705
1706 /* the allocated P-TMSI should be the same */
1707 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1708 OSMO_ASSERT(ctx != NULL);
1709 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1710 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1711 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1712
1713 /* inject the attach complete */
1714 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1715 send_0408_message(ctx->llme, local_tlli,
1716 attach_compl, ARRAY_SIZE(attach_compl));
1717
1718 /* we don't expect a response */
1719 OSMO_ASSERT(sgsn_tx_counter == 0);
1720
1721 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1722 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1723 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1724
1725 printf(" - Repeated RA Update Request\n");
1726
1727 /* inject the RA update request */
1728 send_0408_message(ctx->llme, local_tlli,
1729 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1730
1731 /* we expect an RA update accept */
1732 OSMO_ASSERT(sgsn_tx_counter == 1);
1733
1734 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1735 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1736 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1737
1738 /* repeat the RA update request */
1739 send_0408_message(ctx->llme, local_tlli,
1740 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1741
1742 /* we expect an RA update accept */
1743 OSMO_ASSERT(sgsn_tx_counter == 1);
1744
1745 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1746 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1747 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1748
1749 /* inject the RA update complete */
1750 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1751 send_0408_message(ctx->llme, local_tlli,
1752 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1753
1754 /* we don't expect a response */
1755 OSMO_ASSERT(sgsn_tx_counter == 0);
1756
1757 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1758 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1759 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1760
1761 /* inject the detach */
1762 send_0408_message(ctx->llme, local_tlli,
1763 detach_req, ARRAY_SIZE(detach_req));
1764
1765 /* verify that things are gone */
1766 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1767 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1768 OSMO_ASSERT(!ictx);
1769
1770 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001771
1772 cleanup_test();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001773}
1774
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001775static void test_apn_matching(void)
1776{
1777 struct apn_ctx *actx, *actxs[9];
1778
1779 printf("Testing APN matching\n");
1780
1781 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1782 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1783 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1784 actxs[3] = NULL;
1785
1786 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1787 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1788 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1789 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1790
1791 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1792
1793 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1794 OSMO_ASSERT(actx == actxs[2]);
1795 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1796 OSMO_ASSERT(actx == actxs[2]);
1797 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1798 OSMO_ASSERT(actx == actxs[1]);
1799 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1800 OSMO_ASSERT(actx == actxs[1]);
1801 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1802 OSMO_ASSERT(actx == actxs[0]);
1803 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1804 OSMO_ASSERT(actx == NULL);
1805
1806 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1807 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1808 OSMO_ASSERT(actx == actxs[3]);
1809
1810 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1811 OSMO_ASSERT(actx == actxs[4]);
1812
1813 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1814 OSMO_ASSERT(actx == actxs[6]);
1815
1816 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1817 OSMO_ASSERT(actx == actxs[5]);
1818
1819 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1820 OSMO_ASSERT(actx == actxs[7]);
1821
1822 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1823 OSMO_ASSERT(actx == actxs[8]);
1824
1825 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1826 OSMO_ASSERT(actx == actxs[7]);
1827
1828 /* Free APN contexts and check how the matching changes */
1829
1830 sgsn_apn_ctx_free(actxs[7]);
1831 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1832 OSMO_ASSERT(actx == actxs[8]);
1833
1834 sgsn_apn_ctx_free(actxs[8]);
1835 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1836 OSMO_ASSERT(actx == actxs[6]);
1837
1838 sgsn_apn_ctx_free(actxs[6]);
1839 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1840 OSMO_ASSERT(actx == actxs[1]);
1841
1842 sgsn_apn_ctx_free(actxs[5]);
1843 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1844 OSMO_ASSERT(actx == actxs[4]);
1845
1846 sgsn_apn_ctx_free(actxs[4]);
1847 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1848 OSMO_ASSERT(actx == actxs[2]);
1849
1850 sgsn_apn_ctx_free(actxs[2]);
1851 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1852 OSMO_ASSERT(actx == actxs[1]);
1853
1854 sgsn_apn_ctx_free(actxs[1]);
1855 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1856 OSMO_ASSERT(actx == actxs[0]);
1857
1858 sgsn_apn_ctx_free(actxs[0]);
1859 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1860 OSMO_ASSERT(actx == actxs[3]);
1861
1862 sgsn_apn_ctx_free(actxs[3]);
1863 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1864 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001865
1866 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001867}
1868
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001869struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1870 struct sgsn_subscriber_data *sdata);
1871
1872static void test_ggsn_selection(void)
1873{
1874 struct apn_ctx *actxs[4];
1875 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1876 struct gsm_subscriber *s1;
1877 const char *imsi1 = "1234567890";
1878 struct sgsn_mm_ctx *ctx;
1879 struct gprs_ra_id raid = { 0, };
1880 uint32_t local_tlli = 0xffeeddcc;
1881 enum gsm48_gsm_cause gsm_cause;
1882 struct tlv_parsed tp;
1883 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1884 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001885 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001886
1887 printf("Testing GGSN selection\n");
1888
1889 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1890
1891 /* Check for emptiness */
1892 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1893
1894 /* Create a context */
1895 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1896 ctx = alloc_mm_ctx(local_tlli, &raid);
1897 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1898
1899 /* Allocate and attach a subscriber */
1900 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1901 assert_subscr(s1, imsi1);
1902
1903 tp.lv[GSM48_IE_GSM_APN].len = 0;
1904 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1905
1906 /* TODO: Add PDP info entries to s1 */
1907
1908 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1909 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1910 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1911
1912 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1913 actxs[0]->ggsn = ggcs[0];
1914 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1915 actxs[1]->ggsn = ggcs[1];
1916 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1917 actxs[2]->ggsn = ggcs[2];
1918
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08001919 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1920 pdp_data->context_id = 1;
1921 pdp_data->pdp_type = 0x0121;
1922 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
1923
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001924 /* Resolve GGSNs */
1925
1926 tp.lv[GSM48_IE_GSM_APN].len =
1927 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1928
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001929 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001930 OSMO_ASSERT(ggc != NULL);
1931 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001932 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001933
1934 tp.lv[GSM48_IE_GSM_APN].len =
1935 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1936
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001937 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001938 OSMO_ASSERT(ggc != NULL);
1939 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001940 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001941
1942 tp.lv[GSM48_IE_GSM_APN].len = 0;
1943 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1944
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001945 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001946 OSMO_ASSERT(ggc != NULL);
1947 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001948 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001949
1950 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1951 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001952 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001953 OSMO_ASSERT(ggc != NULL);
1954 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001955 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001956
1957 sgsn_apn_ctx_free(actxs[3]);
1958 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1959
1960 tp.lv[GSM48_IE_GSM_APN].len =
1961 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1962
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001963 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001964 OSMO_ASSERT(ggc == NULL);
1965 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001966 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001967
1968 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001969 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001970 OSMO_ASSERT(ggc == NULL);
1971 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
1972
1973 /* Add PDP data entry to subscriber */
1974
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001975 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
1976
1977 tp.lv[GSM48_IE_GSM_APN].len =
1978 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1979
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001980 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001981 OSMO_ASSERT(ggc != NULL);
1982 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001983 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001984
1985 tp.lv[GSM48_IE_GSM_APN].len =
1986 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1987
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001988 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001989 OSMO_ASSERT(ggc == NULL);
1990 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001991 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001992
1993 /* Cleanup */
1994
1995 subscr_put(s1);
1996 sgsn_mm_ctx_cleanup_free(ctx);
1997
1998 assert_no_subscrs();
1999
2000 sgsn_apn_ctx_free(actxs[0]);
2001 sgsn_apn_ctx_free(actxs[1]);
2002 sgsn_apn_ctx_free(actxs[2]);
2003
2004 sgsn_ggsn_ctx_free(ggcs[0]);
2005 sgsn_ggsn_ctx_free(ggcs[1]);
2006 sgsn_ggsn_ctx_free(ggcs[2]);
2007
2008 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002009
2010 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002011}
2012
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002013static struct log_info_cat gprs_categories[] = {
2014 [DMM] = {
2015 .name = "DMM",
2016 .description = "Layer3 Mobility Management (MM)",
2017 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002018 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002019 },
2020 [DPAG] = {
2021 .name = "DPAG",
2022 .description = "Paging Subsystem",
2023 .color = "\033[1;38m",
2024 .enabled = 1, .loglevel = LOGL_NOTICE,
2025 },
2026 [DMEAS] = {
2027 .name = "DMEAS",
2028 .description = "Radio Measurement Processing",
2029 .enabled = 0, .loglevel = LOGL_NOTICE,
2030 },
2031 [DREF] = {
2032 .name = "DREF",
2033 .description = "Reference Counting",
2034 .enabled = 0, .loglevel = LOGL_NOTICE,
2035 },
2036 [DGPRS] = {
2037 .name = "DGPRS",
2038 .description = "GPRS Packet Service",
2039 .enabled = 1, .loglevel = LOGL_DEBUG,
2040 },
2041 [DNS] = {
2042 .name = "DNS",
2043 .description = "GPRS Network Service (NS)",
2044 .enabled = 1, .loglevel = LOGL_INFO,
2045 },
2046 [DBSSGP] = {
2047 .name = "DBSSGP",
2048 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2049 .enabled = 1, .loglevel = LOGL_DEBUG,
2050 },
2051 [DLLC] = {
2052 .name = "DLLC",
2053 .description = "GPRS Logical Link Control Protocol (LLC)",
2054 .enabled = 1, .loglevel = LOGL_DEBUG,
2055 },
2056 [DSNDCP] = {
2057 .name = "DSNDCP",
2058 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2059 .enabled = 1, .loglevel = LOGL_DEBUG,
2060 },
2061};
2062
2063static struct log_info info = {
2064 .cat = gprs_categories,
2065 .num_cat = ARRAY_SIZE(gprs_categories),
2066};
2067
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002068int main(int argc, char **argv)
2069{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002070 void *osmo_sgsn_ctx;
2071
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002072 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002073 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2074 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2075 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002076
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002077 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002078 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002079
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002080 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002081 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002082 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002083 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002084 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002085 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002086 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002087 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002088 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002089 test_gmm_attach_acl();
2090 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002091 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002092 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002093 test_gmm_attach_subscr_gsup_auth(0);
2094 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002095 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002096 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002097 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002098 test_gmm_ptmsi_allocation();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002099 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002100 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002101 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002102
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002103 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01002104 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002105 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002106 return 0;
2107}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002108
2109
2110/* stubs */
2111struct osmo_prim_hdr;
2112int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2113{
2114 abort();
2115}