blob: 197be9da435839fe3bac7ea7ae8abd3a7591d5ca [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-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 Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020030
Jacob Erlbeck189999d2014-10-27 14:34:13 +010031#include <osmocom/gprs/gprs_bssgp.h>
32
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020033#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010034#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020035
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020039
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020040#include <stdio.h>
41
Holger Hans Peter Freyther4299c052014-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 Erlbeck106f5472014-11-04 10:08:37 +010049 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
54
55/* override */
56int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
57 struct bssgp_dl_ud_par *dup)
58{
59 sgsn_tx_counter += 1;
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +010060 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010061 return 0;
62}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020063
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010064/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010065void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
66void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010067 &__real_sgsn_update_subscriber_data;
68
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010069void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010070{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010071 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010072}
73
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010074/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
75int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
76int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
77 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010078
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010079int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
80 return (*subscr_request_update_location_cb)(mmctx);
81};
82
83/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
84int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
85int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
86 &__real_gprs_subscr_request_auth_info;
87
88int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
89 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010090};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010091
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010092/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
93int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
94int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
95 &__real_gprs_gsup_client_send;
96
97int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
98{
99 return (*gprs_gsup_client_send_cb)(gsupc, msg);
100};
101
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102static int count(struct llist_head *head)
103{
104 struct llist_head *cur;
105 int count = 0;
106
107 llist_for_each(cur, head)
108 count += 1;
109
110 return count;
111}
112
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200113static struct msgb *create_msg(const uint8_t *data, size_t len)
114{
115 struct msgb *msg = msgb_alloc(len + 8, "test message");
116 msg->l1h = msgb_put(msg, 8);
117 msg->l2h = msgb_put(msg, len);
118 memcpy(msg->l2h, data, len);
119
120 msgb_bcid(msg) = msg->l1h;
121 msgb_gmmh(msg) = msg->l2h;
122 return msg;
123}
124
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100125/*
126 * Create a context and search for it
127 */
128static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
129{
130 struct sgsn_mm_ctx *ctx, *ictx;
131 struct gprs_llc_lle *lle;
132 int old_count = count(gprs_llme_list());
133
134 lle = gprs_lle_get_or_create(tlli, 3);
135 ctx = sgsn_mm_ctx_alloc(tlli, raid);
136 ctx->mm_state = GMM_REGISTERED_NORMAL;
137 ctx->llme = lle->llme;
138
139 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
140 OSMO_ASSERT(ictx == ctx);
141
142 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
143
144 return ctx;
145}
146
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100147static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
148 const uint8_t *data, size_t data_len)
149{
150 struct msgb *msg;
151
152 sgsn_tx_counter = 0;
153
154 msg = create_msg(data, data_len);
155 msgb_tlli(msg) = tlli;
156 gsm0408_gprs_rcvmsg(msg, llme);
157 msgb_free(msg);
158}
159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200160static void test_llme(void)
161{
162 struct gprs_llc_lle *lle, *lle_copy;
163 uint32_t local_tlli;
164 uint32_t foreign_tlli;
165
166 printf("Testing LLME allocations\n");
167 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
168 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
169
170 /* initial state */
171 OSMO_ASSERT(count(gprs_llme_list()) == 0);
172
173 /* Create a new entry */
174 lle = gprs_lle_get_or_create(local_tlli, 3);
175 OSMO_ASSERT(lle);
176 OSMO_ASSERT(count(gprs_llme_list()) == 1);
177
178 /* No new entry is created */
179 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
180 OSMO_ASSERT(lle == lle_copy);
181 OSMO_ASSERT(count(gprs_llme_list()) == 1);
182 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
183 OSMO_ASSERT(lle == lle_copy);
184 OSMO_ASSERT(count(gprs_llme_list()) == 1);
185
186 /* unassign which should delete it*/
187 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
188
189 /* Check that everything was cleaned up */
190 OSMO_ASSERT(count(gprs_llme_list()) == 0);
191}
192
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100193struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100194void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100195{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100196 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100197 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100198 __func__, mmctx, mmctx->subscr);
199 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100200}
201
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100202static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
203{
204 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100205 OSMO_ASSERT(subscr);
206 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100207
208 sfound = gprs_subscr_get_by_imsi(imsi);
209 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100210
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100211 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100212}
213
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100214static void show_subscrs(FILE *out)
215{
216 struct gsm_subscriber *subscr;
217
218 llist_for_each_entry(subscr, &active_subscribers, entry) {
219 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100220 "use count: %d\n",
221 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100222 }
223}
224
225static void assert_no_subscrs()
226{
227 show_subscrs(stdout);
228 fflush(stdout);
229 OSMO_ASSERT(llist_empty(&active_subscribers));
230}
231
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100232static void test_subscriber(void)
233{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100234 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100235 const char *imsi1 = "1234567890";
236 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100237 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100238
239 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
240
241 printf("Testing core subscriber data API\n");
242
243 /* Check for emptiness */
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100246 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100247
248 /* Allocate entry 1 */
249 s1 = gprs_subscr_get_or_create(imsi1);
250 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100251 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253
254 /* Allocate entry 2 */
255 s2 = gprs_subscr_get_or_create(imsi2);
256 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100257
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100258 /* Allocate entry 3 */
259 s3 = gprs_subscr_get_or_create(imsi3);
260
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261 /* Check entries */
262 assert_subscr(s1, imsi1);
263 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100264 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100265
266 /* Update entry 1 */
267 last_updated_subscr = NULL;
268 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100269 OSMO_ASSERT(last_updated_subscr == NULL);
270 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
271 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100272
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100273 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100274 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100275 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100276 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100277 sfound = gprs_subscr_get_by_imsi(imsi1);
278 OSMO_ASSERT(sfound == NULL);
279
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100280 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100281 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100282
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100283 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100284 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100285 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100286 s2 = NULL;
287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
288 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100289 assert_subscr(s3, imsi3);
290
291 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100292 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100293 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100294 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100295 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100296
297 OSMO_ASSERT(llist_empty(&active_subscribers));
298
299 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
300}
301
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100302static void test_auth_triplets(void)
303{
304 struct gsm_subscriber *s1, *s1found;
305 const char *imsi1 = "1234567890";
306 struct gsm_auth_tuple *at;
307 struct sgsn_mm_ctx *ctx;
308 struct gprs_ra_id raid = { 0, };
309 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100310
311 printf("Testing authentication triplet handling\n");
312
313 /* Check for emptiness */
314 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
315
316 /* Allocate entry 1 */
317 s1 = gprs_subscr_get_or_create(imsi1);
318 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
319 s1found = gprs_subscr_get_by_imsi(imsi1);
320 OSMO_ASSERT(s1found == s1);
321 subscr_put(s1found);
322
323 /* Create a context */
324 OSMO_ASSERT(count(gprs_llme_list()) == 0);
325 ctx = alloc_mm_ctx(local_tlli, &raid);
326
327 /* Attach s1 to ctx */
328 ctx->subscr = subscr_get(s1);
329 ctx->subscr->sgsn_data->mm = ctx;
330
331 /* Try to get auth tuple */
332 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
333 OSMO_ASSERT(at == NULL);
334
335 /* Add triplets */
336 s1->sgsn_data->auth_triplets[0].key_seq = 0;
337 s1->sgsn_data->auth_triplets[1].key_seq = 1;
338 s1->sgsn_data->auth_triplets[2].key_seq = 2;
339
340 /* Try to get auth tuple */
341 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
342 OSMO_ASSERT(at != NULL);
343 OSMO_ASSERT(at->key_seq == 0);
344 OSMO_ASSERT(at->use_count == 1);
345 at = sgsn_auth_get_tuple(ctx, at->key_seq);
346 OSMO_ASSERT(at != NULL);
347 OSMO_ASSERT(at->key_seq == 1);
348 OSMO_ASSERT(at->use_count == 1);
349 at = sgsn_auth_get_tuple(ctx, at->key_seq);
350 OSMO_ASSERT(at != NULL);
351 OSMO_ASSERT(at->key_seq == 2);
352 OSMO_ASSERT(at->use_count == 1);
353 at = sgsn_auth_get_tuple(ctx, at->key_seq);
354 OSMO_ASSERT(at == NULL);
355
356 /* Free MM context and subscriber */
357 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100358 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100359 s1found = gprs_subscr_get_by_imsi(imsi1);
360 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100361}
362
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100363#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
364
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100365static int rx_gsup_message(const uint8_t *data, size_t data_len)
366{
367 struct msgb *msg;
368 int rc;
369
370 msg = msgb_alloc(1024, __func__);
371 msg->l2h = msgb_put(msg, data_len);
372 OSMO_ASSERT(msg->l2h != NULL);
373 memcpy(msg->l2h, data, data_len);
374 rc = gprs_subscr_rx_gsup_message(msg);
375 msgb_free(msg);
376
377 return rc;
378}
379
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100380static void test_subscriber_gsup(void)
381{
382 struct gsm_subscriber *s1, *s1found;
383 const char *imsi1 = "1234567890";
384 struct sgsn_mm_ctx *ctx;
385 struct gprs_ra_id raid = { 0, };
386 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100387 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100388 int rc;
389
390 static const uint8_t send_auth_info_res[] = {
391 0x0a,
392 TEST_GSUP_IMSI1_IE,
393 0x03, 0x22, /* Auth tuple */
394 0x20, 0x10,
395 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
396 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
397 0x21, 0x04,
398 0x21, 0x22, 0x23, 0x24,
399 0x22, 0x08,
400 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
401 0x03, 0x22, /* Auth tuple */
402 0x20, 0x10,
403 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
404 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
405 0x21, 0x04,
406 0xa1, 0xa2, 0xa3, 0xa4,
407 0x22, 0x08,
408 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
409 };
410
411 static const uint8_t send_auth_info_err[] = {
412 0x09,
413 TEST_GSUP_IMSI1_IE,
414 0x02, 0x01, 0x07 /* GPRS not allowed */
415 };
416
417 static const uint8_t update_location_res[] = {
418 0x06,
419 TEST_GSUP_IMSI1_IE,
420 0x04, 0x00, /* PDP info complete */
421 0x05, 0x12,
422 0x10, 0x01, 0x01,
423 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
424 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
425 0x05, 0x11,
426 0x10, 0x01, 0x02,
427 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
428 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
429 };
430
431 static const uint8_t update_location_err[] = {
432 0x05,
433 TEST_GSUP_IMSI1_IE,
434 0x02, 0x01, 0x07 /* GPRS not allowed */
435 };
436
437 static const uint8_t location_cancellation_req[] = {
438 0x1c,
439 TEST_GSUP_IMSI1_IE,
440 0x06, 0x01, 0x00,
441 };
442
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200443 static const uint8_t location_cancellation_req_withdraw[] = {
444 0x1c,
445 TEST_GSUP_IMSI1_IE,
446 0x06, 0x01, 0x01,
447 };
448
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100449 static const uint8_t location_cancellation_req_other[] = {
450 0x1c,
451 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
452 0x06, 0x01, 0x00,
453 };
454
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100455 static const uint8_t purge_ms_err[] = {
456 0x0d,
457 TEST_GSUP_IMSI1_IE,
458 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
459 };
460
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100461 static const uint8_t purge_ms_err_no_cause[] = {
462 0x0d,
463 TEST_GSUP_IMSI1_IE,
464 };
465
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100466 static const uint8_t purge_ms_res[] = {
467 0x0e,
468 TEST_GSUP_IMSI1_IE,
469 0x07, 0x00,
470 };
471
472
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100473 static const uint8_t insert_data_req[] = {
474 0x10,
475 TEST_GSUP_IMSI1_IE,
476 0x05, 0x11,
477 0x10, 0x01, 0x03,
478 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
479 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
480 };
481
482 static const uint8_t delete_data_req[] = {
483 0x14,
484 TEST_GSUP_IMSI1_IE,
485 0x10, 0x01, 0x03,
486 };
487
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100488 printf("Testing subcriber GSUP handling\n");
489
490 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
491
492 /* Check for emptiness */
493 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
494
495 /* Allocate entry 1 */
496 s1 = gprs_subscr_get_or_create(imsi1);
497 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
498 s1found = gprs_subscr_get_by_imsi(imsi1);
499 OSMO_ASSERT(s1found == s1);
500 subscr_put(s1found);
501
502 /* Create a context */
503 OSMO_ASSERT(count(gprs_llme_list()) == 0);
504 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100505
506 /* Attach s1 to ctx */
507 ctx->subscr = subscr_get(s1);
508 ctx->subscr->sgsn_data->mm = ctx;
509
510 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100511 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100512 OSMO_ASSERT(rc >= 0);
513 OSMO_ASSERT(last_updated_subscr == s1);
514
515 /* Check triplets */
516 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
517 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
518 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
519
520 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100521 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100522 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100523 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100524 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100525
526 /* Check triplets */
527 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
528 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
529 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
530
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100531 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100532 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100533 OSMO_ASSERT(rc >= 0);
534 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100535 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100536 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100537 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
538 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
539 struct sgsn_subscriber_pdp_data, list);
540 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
541 pdpd = llist_entry(pdpd->list.next,
542 struct sgsn_subscriber_pdp_data, list);
543 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100544
545 /* Check authorization */
546 OSMO_ASSERT(s1->authorized == 1);
547
548 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100549 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100550 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100551 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100552 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100553
554 /* Check authorization */
555 OSMO_ASSERT(s1->authorized == 0);
556
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100557 /* Inject InsertSubscrData GSUP message */
558 last_updated_subscr = NULL;
559 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
560 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
561 OSMO_ASSERT(last_updated_subscr == NULL);
562
563 /* Inject DeleteSubscrData GSUP message */
564 last_updated_subscr = NULL;
565 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
566 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
567 OSMO_ASSERT(last_updated_subscr == NULL);
568
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100569 /* Inject wrong LocCancelReq GSUP message */
570 last_updated_subscr = NULL;
571 rc = rx_gsup_message(location_cancellation_req_other,
572 sizeof(location_cancellation_req_other));
573 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
574 OSMO_ASSERT(last_updated_subscr == NULL);
575
576 /* Check cancellation result */
577 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
578 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
579
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100580 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100581 rc = rx_gsup_message(location_cancellation_req,
582 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100583 OSMO_ASSERT(rc >= 0);
584 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100585 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100586
587 /* Check cancellation result */
588 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
589 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
590
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200591 /* Inject LocCancelReq(withdraw) GSUP message */
592 rc = rx_gsup_message(location_cancellation_req_withdraw,
593 sizeof(location_cancellation_req_withdraw));
594 OSMO_ASSERT(rc >= 0);
595 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
596
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100597 /* Inject PurgeMsRes GSUP message */
598 rc = rx_gsup_message(purge_ms_res,
599 sizeof(purge_ms_res));
600 OSMO_ASSERT(rc >= 0);
601 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
602
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100603 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100604 OSMO_ASSERT(ctx->subscr == NULL);
605 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100606 subscr_put(s1);
607 s1found = gprs_subscr_get_by_imsi(imsi1);
608 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100609
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100610 /* Inject PurgeMsRes GSUP message */
611 rc = rx_gsup_message(purge_ms_res,
612 sizeof(purge_ms_res));
613 OSMO_ASSERT(rc >= 0);
614
615 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
616 rc = rx_gsup_message(purge_ms_err,
617 sizeof(purge_ms_err));
618 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
619
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100620 /* Inject PurgeMsErr() GSUP message */
621 rc = rx_gsup_message(purge_ms_err_no_cause,
622 sizeof(purge_ms_err_no_cause));
623 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
624
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100625 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
626 last_updated_subscr = NULL;
627 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100628 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100629 OSMO_ASSERT(last_updated_subscr == NULL);
630
631 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
632 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
633 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
634 OSMO_ASSERT(last_updated_subscr == NULL);
635
636 /* Inject LocCancelReq GSUP message (unknown IMSI) */
637 rc = rx_gsup_message(location_cancellation_req,
638 sizeof(location_cancellation_req));
639 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
640 OSMO_ASSERT(last_updated_subscr == NULL);
641
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100642 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
643}
644
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100645int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
646{
647 msgb_free(msg);
648 return 0;
649};
650
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200651/*
652 * Test that a GMM Detach will remove the MMCTX and the
653 * associated LLME.
654 */
655static void test_gmm_detach(void)
656{
657 struct gprs_ra_id raid = { 0, };
658 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200659 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200660
661 printf("Testing GMM detach\n");
662
663 /* DTAP - Detach Request (MO) */
664 /* normal detach, power_off = 0 */
665 static const unsigned char detach_req[] = {
666 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
667 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
668 };
669
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200670 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200671
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100672 /* Create a context */
673 OSMO_ASSERT(count(gprs_llme_list()) == 0);
674 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200675
676 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100677 send_0408_message(ctx->llme, local_tlli,
678 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200679
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100680 /* verify that a single message (hopefully the Detach Accept) has been
681 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100682 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100683
684 /* verify that things are gone */
685 OSMO_ASSERT(count(gprs_llme_list()) == 0);
686 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
687 OSMO_ASSERT(!ictx);
688}
689
690/*
691 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
692 * will not sent a Detach Accept message (power_off = 1)
693 */
694static void test_gmm_detach_power_off(void)
695{
696 struct gprs_ra_id raid = { 0, };
697 struct sgsn_mm_ctx *ctx, *ictx;
698 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100699
700 printf("Testing GMM detach (power off)\n");
701
702 /* DTAP - Detach Request (MO) */
703 /* normal detach, power_off = 1 */
704 static const unsigned char detach_req[] = {
705 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
706 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
707 };
708
709 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
710
711 /* Create a context */
712 OSMO_ASSERT(count(gprs_llme_list()) == 0);
713 ctx = alloc_mm_ctx(local_tlli, &raid);
714
715 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100716 send_0408_message(ctx->llme, local_tlli,
717 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100718
719 /* verify that no message (and therefore no Detach Accept) has been
720 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100721 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100722
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200723 /* verify that things are gone */
724 OSMO_ASSERT(count(gprs_llme_list()) == 0);
725 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200726 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200727}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200728
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200729/*
730 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
731 */
732static void test_gmm_detach_no_mmctx(void)
733{
734 struct gprs_llc_lle *lle;
735 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200736
737 printf("Testing GMM detach (no MMCTX)\n");
738
739 /* DTAP - Detach Request (MO) */
740 /* normal detach, power_off = 0 */
741 static const unsigned char detach_req[] = {
742 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
743 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
744 };
745
746 /* Create an LLME */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
749 lle = gprs_lle_get_or_create(local_tlli, 3);
750
751 OSMO_ASSERT(count(gprs_llme_list()) == 1);
752
753 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100754 send_0408_message(lle->llme, local_tlli,
755 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200756
757 /* verify that the LLME is gone */
758 OSMO_ASSERT(count(gprs_llme_list()) == 0);
759}
760
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100761/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100762 * Test that a single GMM Detach Accept message will not cause the SGSN to send
763 * any message or leave an MM context at the SGSN.
764 */
765static void test_gmm_detach_accept_unexpected(void)
766{
767 struct gprs_llc_lle *lle;
768 uint32_t local_tlli;
769
770 printf("Testing GMM detach accept (unexpected)\n");
771
772 /* DTAP - Detach Accept (MT) */
773 /* normal detach */
774 static const unsigned char detach_acc[] = {
775 0x08, 0x06
776 };
777
778 /* Create an LLME */
779 OSMO_ASSERT(count(gprs_llme_list()) == 0);
780 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
781 lle = gprs_lle_get_or_create(local_tlli, 3);
782
783 /* inject the detach */
784 send_0408_message(lle->llme, local_tlli,
785 detach_acc, ARRAY_SIZE(detach_acc));
786
787 /* verify that no message (and therefore no Status or XID reset) has been
788 * sent by the SGSN */
789 OSMO_ASSERT(sgsn_tx_counter == 0);
790
791 /* verify that things are gone */
792 OSMO_ASSERT(count(gprs_llme_list()) == 0);
793}
794
795/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100796 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
797 */
798static void test_gmm_status_no_mmctx(void)
799{
800 struct gprs_llc_lle *lle;
801 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100802
803 printf("Testing GMM Status (no MMCTX)\n");
804
805 /* DTAP - GMM Status, protocol error */
806 static const unsigned char gmm_status[] = {
807 0x08, 0x20, 0x6f
808 };
809
810 /* Create an LLME */
811 OSMO_ASSERT(count(gprs_llme_list()) == 0);
812 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
813 lle = gprs_lle_get_or_create(local_tlli, 3);
814
815 OSMO_ASSERT(count(gprs_llme_list()) == 1);
816
817 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100818 send_0408_message(lle->llme, local_tlli,
819 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100820
821 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100822 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100823
824 /* verify that the LLME is gone */
825 OSMO_ASSERT(count(gprs_llme_list()) == 0);
826}
827
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100828/*
829 * Test the GMM Attach procedure
830 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100831static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100832{
833 struct gprs_ra_id raid = { 0, };
834 struct sgsn_mm_ctx *ctx = NULL;
835 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100836 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100837 uint32_t foreign_tlli;
838 uint32_t local_tlli = 0;
839 struct gprs_llc_lle *lle;
840
841 /* DTAP - Attach Request */
842 /* The P-TMSI is not known by the SGSN */
843 static const unsigned char attach_req[] = {
844 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
845 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
846 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
847 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
848 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
849 };
850
851 /* DTAP - Identity Response IMEI */
852 static const unsigned char ident_resp_imei[] = {
853 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
854 0x56
855 };
856
857 /* DTAP - Identity Response IMSI */
858 static const unsigned char ident_resp_imsi[] = {
859 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
860 0x54
861 };
862
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100863 /* DTAP - Authentication and Ciphering Resp */
864 static const unsigned char auth_ciph_resp[] = {
865 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
866 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
867 };
868
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100869 /* DTAP - Attach Complete */
870 static const unsigned char attach_compl[] = {
871 0x08, 0x03
872 };
873
874 /* DTAP - Detach Request (MO) */
875 /* normal detach, power_off = 0 */
876 static const unsigned char detach_req[] = {
877 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
878 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
879 };
880
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100881 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100882
883 /* reset the PRNG used by sgsn_alloc_ptmsi */
884 srand(1);
885
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100886 ptmsi1 = sgsn_alloc_ptmsi();
887 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
888
889 /* reset the PRNG, so that the same P-TMSI sequence will be generated
890 * again */
891 srand(1);
892
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100893 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
894
895 /* Create a LLE/LLME */
896 OSMO_ASSERT(count(gprs_llme_list()) == 0);
897 lle = gprs_lle_get_or_create(foreign_tlli, 3);
898 OSMO_ASSERT(count(gprs_llme_list()) == 1);
899
900 /* inject the attach request */
901 send_0408_message(lle->llme, foreign_tlli,
902 attach_req, ARRAY_SIZE(attach_req));
903
904 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
905 OSMO_ASSERT(ctx != NULL);
906 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
907
908 /* we expect an identity request (IMEI) */
909 OSMO_ASSERT(sgsn_tx_counter == 1);
910
911 /* inject the identity response (IMEI) */
912 send_0408_message(ctx->llme, foreign_tlli,
913 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
914
915 /* we expect an identity request (IMSI) */
916 OSMO_ASSERT(sgsn_tx_counter == 1);
917
918 /* inject the identity response (IMSI) */
919 send_0408_message(ctx->llme, foreign_tlli,
920 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
921
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100922 /* check that the MM context has not been removed due to a failed
923 * authorization */
924 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
925
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100926 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100927
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100928retry_attach_req:
929
930 if (retry && sgsn_tx_counter == 0) {
931 fprintf(stderr, "Retrying attach request\n");
932 /* re-inject the attach request */
933 send_0408_message(lle->llme, foreign_tlli,
934 attach_req, ARRAY_SIZE(attach_req));
935 }
936
937 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
938 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100939
940 /* inject the auth & ciph response */
941 send_0408_message(ctx->llme, foreign_tlli,
942 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
943
944 /* check that the MM context has not been removed due to a
945 * failed authorization */
946 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
947 }
948
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100949 if (retry && sgsn_tx_counter == 0)
950 goto retry_attach_req;
951
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100952 /* we expect an attach accept/reject */
953 OSMO_ASSERT(sgsn_tx_counter == 1);
954
955 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100956 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100957
958 /* inject the attach complete */
959 send_0408_message(ctx->llme, local_tlli,
960 attach_compl, ARRAY_SIZE(attach_compl));
961
962 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
963
964 /* we don't expect a response */
965 OSMO_ASSERT(sgsn_tx_counter == 0);
966
967 /* inject the detach */
968 send_0408_message(ctx->llme, local_tlli,
969 detach_req, ARRAY_SIZE(detach_req));
970
971 /* verify that things are gone */
972 OSMO_ASSERT(count(gprs_llme_list()) == 0);
973 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
974 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100975}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100976
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100977static void test_gmm_attach_acl(void)
978{
979 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
980
981 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
982 sgsn_acl_add("123456789012345", &sgsn->cfg);
983 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100984 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100985 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100986
987 sgsn->cfg.auth_policy = saved_auth_policy;
988}
989
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100990int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100991 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100992 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100993 if (rc == -ENOTSUP) {
994 OSMO_ASSERT(mmctx->subscr);
995 gprs_subscr_update(mmctx->subscr);
996 }
997 return rc;
998};
999
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001000int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1001 gprs_subscr_update(mmctx->subscr);
1002 return 0;
1003};
1004
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001005static void test_gmm_attach_subscr(void)
1006{
1007 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1008 struct gsm_subscriber *subscr;
1009
1010 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001011 subscr_request_update_location_cb = my_subscr_request_update_location;
1012 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001013
1014 subscr = gprs_subscr_get_or_create("123456789012345");
1015 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001016
1017 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001018 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001019 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001020 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001021
1022 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001023 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1024 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001025}
1026
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001027int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1028{
1029 /* Fake an authentication */
1030 OSMO_ASSERT(mmctx->subscr);
1031 mmctx->is_authenticated = 1;
1032 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001033
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001034 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001035};
1036
1037static void test_gmm_attach_subscr_fake_auth(void)
1038{
1039 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1040 struct gsm_subscriber *subscr;
1041
1042 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001043 subscr_request_update_location_cb = my_subscr_request_update_location;
1044 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001045
1046 subscr = gprs_subscr_get_or_create("123456789012345");
1047 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001048 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001049 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001050
1051 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001052 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001053 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001054 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001055
1056 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001057 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1058 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1059}
1060
1061int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1062{
1063 struct gsm_auth_tuple at = {
1064 .sres = {0x51, 0xe5, 0x51, 0xe5},
1065 .key_seq = 0
1066 };
1067
1068 /* Fake an authentication */
1069 OSMO_ASSERT(mmctx->subscr);
1070 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1071
1072 gprs_subscr_update_auth_info(mmctx->subscr);
1073
1074 return 0;
1075};
1076
1077static void test_gmm_attach_subscr_real_auth(void)
1078{
1079 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1080 struct gsm_subscriber *subscr;
1081
1082 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1083 subscr_request_update_location_cb = my_subscr_request_update_location;
1084 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1085
1086 subscr = gprs_subscr_get_or_create("123456789012345");
1087 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001088 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001089 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001090
1091 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001092
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001093 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001094 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001095 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001096
1097 sgsn->cfg.auth_policy = saved_auth_policy;
1098 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1099 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001100}
1101
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001102#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1103 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1104
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001105static int auth_info_skip = 0;
1106static int upd_loc_skip = 0;
1107
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001108int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1109{
1110 static const uint8_t send_auth_info_res[] = {
1111 0x0a,
1112 TEST_GSUP_IMSI_LONG_IE,
1113 0x03, 0x22, /* Auth tuple */
1114 0x20, 0x10,
1115 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1116 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1117 0x21, 0x04,
1118 0x51, 0xe5, 0x51, 0xe5,
1119 0x22, 0x08,
1120 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1121 };
1122
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001123 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001124
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001125 if (auth_info_skip > 0) {
1126 auth_info_skip -= 1;
1127 return -EAGAIN;
1128 }
1129
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001130 /* Fake an SendAuthInfoRes */
1131 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1132
1133 return 0;
1134};
1135
1136int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1137 static const uint8_t update_location_res[] = {
1138 0x06,
1139 TEST_GSUP_IMSI_LONG_IE,
1140 0x04, 0x00, /* PDP info complete */
1141 0x05, 0x12,
1142 0x10, 0x01, 0x01,
1143 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1144 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1145 };
1146
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001147 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001148
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001149 if (upd_loc_skip > 0) {
1150 upd_loc_skip -= 1;
1151 return -EAGAIN;
1152 }
1153
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001154 /* Fake an UpdateLocRes */
1155 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1156};
1157
1158
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001159static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001160{
1161 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1162 struct gsm_subscriber *subscr;
1163
1164 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1165 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1166 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001167 if (retry) {
1168 upd_loc_skip = 3;
1169 auth_info_skip = 3;
1170 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001171
1172 subscr = gprs_subscr_get_or_create("123456789012345");
1173 subscr->authorized = 1;
1174 sgsn->cfg.require_authentication = 1;
1175 sgsn->cfg.require_update_location = 1;
1176 subscr_put(subscr);
1177
1178 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001179 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001180 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001181
1182 sgsn->cfg.auth_policy = saved_auth_policy;
1183 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1184 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001185 upd_loc_skip = 0;
1186 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001187}
1188
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001189int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1190{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001191 struct gprs_gsup_message to_peer = {0};
1192 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001193 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001194 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001195
1196 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001197 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1198 OSMO_ASSERT(rc >= 0);
1199 OSMO_ASSERT(to_peer.imsi[0] != 0);
1200 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001201
1202 /* This invalidates the pointers in to_peer */
1203 msgb_free(msg);
1204
1205 switch (to_peer.message_type) {
1206 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1207 /* Send UPDATE_LOCATION_RESULT */
1208 return my_subscr_request_update_gsup_auth(NULL);
1209
1210 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1211 /* Send SEND_AUTH_INFO_RESULT */
1212 return my_subscr_request_auth_info_gsup_auth(NULL);
1213
1214 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001215 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1216 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001217
1218 default:
1219 if ((to_peer.message_type & 0b00000011) == 0) {
1220 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001221 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001222 from_peer.message_type = to_peer.message_type + 1;
1223 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1224 break;
1225 }
1226
1227 /* Ignore it */
1228 return 0;
1229 }
1230
1231 reply_msg = gprs_gsup_msgb_alloc();
1232 reply_msg->l2h = reply_msg->data;
1233 gprs_gsup_encode(reply_msg, &from_peer);
1234 gprs_subscr_rx_gsup_message(reply_msg);
1235 msgb_free(reply_msg);
1236
1237 return 0;
1238};
1239
1240static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1241{
1242 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1243 struct gsm_subscriber *subscr;
1244
1245 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001246 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1247
1248 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1249
1250 if (retry) {
1251 upd_loc_skip = 3;
1252 auth_info_skip = 3;
1253 }
1254
1255 printf("Auth policy 'remote', real GSUP based auth: ");
1256 test_gmm_attach(retry);
1257
1258 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001259 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001260 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001261
1262 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001263 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1264 upd_loc_skip = 0;
1265 auth_info_skip = 0;
1266 talloc_free(sgsn->gsup_client);
1267 sgsn->gsup_client = NULL;
1268}
1269
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001270/*
1271 * Test the GMM Rejects
1272 */
1273static void test_gmm_reject(void)
1274{
1275 struct gprs_ra_id raid = { 0, };
1276 struct sgsn_mm_ctx *ctx = NULL;
1277 uint32_t foreign_tlli;
1278 struct gprs_llc_lle *lle;
1279 int idx;
1280
1281 /* DTAP - Attach Request */
1282 /* Invalid MI length */
1283 static const unsigned char attach_req_inv_mi_len[] = {
1284 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1285 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1286 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1287 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1288 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1289 };
1290
1291 /* DTAP - Attach Request */
1292 /* Invalid MI type (IMEI) */
1293 static const unsigned char attach_req_inv_mi_type[] = {
1294 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1295 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1296 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1297 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1298 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1299 };
1300
1301 /* DTAP - Routing Area Update Request */
1302 static const unsigned char dtap_ra_upd_req[] = {
1303 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1304 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1305 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1306 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1307 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1308 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1309 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1310 };
1311
1312 /* DTAP - Routing Area Update Request */
1313 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1314 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1315 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1316 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1317 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1318 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1319 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1320 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1321 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1322 };
1323
1324 /* DTAP - Routing Area Update Request */
1325 /* Invalid cap length */
1326 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1327 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1328 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1329 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1330 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1331 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1332 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1333 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1334 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1335 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1336 };
1337
1338 struct test {
1339 const char *title;
1340 const unsigned char *msg;
1341 unsigned msg_len;
1342 unsigned num_resp;
1343
1344 };
1345 static struct test tests[] = {
1346 {
1347 .title = "Attach Request (invalid MI length)",
1348 .msg = attach_req_inv_mi_len,
1349 .msg_len = sizeof(attach_req_inv_mi_len),
1350 .num_resp = 1 /* Reject */
1351
1352 },
1353 {
1354 .title = "Attach Request (invalid MI type)",
1355 .msg = attach_req_inv_mi_type,
1356 .msg_len = sizeof(attach_req_inv_mi_type),
1357 .num_resp = 1 /* Reject */
1358 },
1359 {
1360 .title = "Routing Area Update Request (valid)",
1361 .msg = dtap_ra_upd_req,
1362 .msg_len = sizeof(dtap_ra_upd_req),
1363 .num_resp = 2 /* XID Reset + Reject */
1364 },
1365 {
1366 .title = "Routing Area Update Request (invalid type)",
1367 .msg = dtap_ra_upd_req_inv_type,
1368 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1369 .num_resp = 1 /* Reject */
1370 },
1371 {
1372 .title = "Routing Area Update Request (invalid CAP length)",
1373 .msg = dtap_ra_upd_req_inv_cap_len,
1374 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1375 .num_resp = 1 /* Reject */
1376 },
1377 };
1378
1379 printf("Testing GMM reject\n");
1380
1381 /* reset the PRNG used by sgsn_alloc_ptmsi */
1382 srand(1);
1383
1384 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1385
1386 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1387
1388 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1389 const struct test *test = &tests[idx];
1390 printf(" - %s\n", test->title);
1391
1392 /* Create a LLE/LLME */
1393 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1394 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1395
1396 /* Inject the Request message */
1397 send_0408_message(lle->llme, foreign_tlli,
1398 test->msg, test->msg_len);
1399
1400 /* We expect a Reject message */
1401 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1402 sgsn_tx_counter, test->num_resp);
1403 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1404
1405 /* verify that LLME/MM are removed */
1406 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1407 OSMO_ASSERT(ctx == NULL);
1408 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1409 }
1410}
1411
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001412/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001413 * Test cancellation of attached MM contexts
1414 */
1415static void test_gmm_cancel(void)
1416{
1417 struct gprs_ra_id raid = { 0, };
1418 struct sgsn_mm_ctx *ctx = NULL;
1419 struct sgsn_mm_ctx *ictx;
1420 uint32_t ptmsi1;
1421 uint32_t foreign_tlli;
1422 uint32_t local_tlli = 0;
1423 struct gprs_llc_lle *lle;
1424 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1425
1426 /* DTAP - Attach Request */
1427 /* The P-TMSI is not known by the SGSN */
1428 static const unsigned char attach_req[] = {
1429 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1430 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1431 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1432 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1433 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1434 };
1435
1436 /* DTAP - Identity Response IMEI */
1437 static const unsigned char ident_resp_imei[] = {
1438 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1439 0x56
1440 };
1441
1442 /* DTAP - Identity Response IMSI */
1443 static const unsigned char ident_resp_imsi[] = {
1444 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1445 0x54
1446 };
1447
1448 /* DTAP - Attach Complete */
1449 static const unsigned char attach_compl[] = {
1450 0x08, 0x03
1451 };
1452
1453 printf("Testing cancellation\n");
1454
1455 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1456
1457 /* reset the PRNG used by sgsn_alloc_ptmsi */
1458 srand(1);
1459
1460 ptmsi1 = sgsn_alloc_ptmsi();
1461 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1462
1463 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1464 * again */
1465 srand(1);
1466
1467 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1468
1469 /* Create a LLE/LLME */
1470 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1471 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1472 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1473
1474 /* inject the attach request */
1475 send_0408_message(lle->llme, foreign_tlli,
1476 attach_req, ARRAY_SIZE(attach_req));
1477
1478 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1479 OSMO_ASSERT(ctx != NULL);
1480 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1481
1482 /* we expect an identity request (IMEI) */
1483 OSMO_ASSERT(sgsn_tx_counter == 1);
1484
1485 /* inject the identity response (IMEI) */
1486 send_0408_message(ctx->llme, foreign_tlli,
1487 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1488
1489 /* we expect an identity request (IMSI) */
1490 OSMO_ASSERT(sgsn_tx_counter == 1);
1491
1492 /* inject the identity response (IMSI) */
1493 send_0408_message(ctx->llme, foreign_tlli,
1494 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1495
1496 /* check that the MM context has not been removed due to a failed
1497 * authorization */
1498 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1499
1500 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1501
1502 /* we expect an attach accept/reject */
1503 OSMO_ASSERT(sgsn_tx_counter == 1);
1504
1505 /* this has been randomly assigned by the SGSN */
1506 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1507
1508 /* inject the attach complete */
1509 send_0408_message(ctx->llme, local_tlli,
1510 attach_compl, ARRAY_SIZE(attach_compl));
1511
1512 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1513
1514 /* we don't expect a response */
1515 OSMO_ASSERT(sgsn_tx_counter == 0);
1516
1517 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001518 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001519
1520 /* verify that things are gone */
1521 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1522 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1523 OSMO_ASSERT(!ictx);
1524
1525 sgsn->cfg.auth_policy = saved_auth_policy;
1526}
1527
1528/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001529 * Test the dynamic allocation of P-TMSIs
1530 */
1531static void test_gmm_ptmsi_allocation(void)
1532{
1533 struct gprs_ra_id raid = { 0, };
1534 struct sgsn_mm_ctx *ctx = NULL;
1535 struct sgsn_mm_ctx *ictx;
1536 uint32_t foreign_tlli;
1537 uint32_t ptmsi1;
1538 uint32_t ptmsi2;
1539 uint32_t old_ptmsi;
1540 uint32_t local_tlli = 0;
1541 struct gprs_llc_lle *lle;
1542 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1543
1544 /* DTAP - Attach Request (IMSI 12131415161718) */
1545 static const unsigned char attach_req[] = {
1546 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1547 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1548 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1549 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1550 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1551 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1552 0x00,
1553 };
1554
1555 /* DTAP - Identity Response IMEI */
1556 static const unsigned char ident_resp_imei[] = {
1557 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1558 0x56
1559 };
1560
1561 /* DTAP - Attach Complete */
1562 static const unsigned char attach_compl[] = {
1563 0x08, 0x03
1564 };
1565
1566 /* DTAP - Routing Area Update Request */
1567 static const unsigned char ra_upd_req[] = {
1568 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1569 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1570 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1571 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1572 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1573 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1574 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1575 };
1576
1577 /* DTAP - Routing Area Update Complete */
1578 static const unsigned char ra_upd_complete[] = {
1579 0x08, 0x0a
1580 };
1581
1582 /* DTAP - Detach Request (MO) */
1583 /* normal detach, power_off = 1 */
1584 static const unsigned char detach_req[] = {
1585 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1586 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1587 };
1588
1589 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1590
1591 printf("Testing P-TMSI allocation\n");
1592
1593 printf(" - sgsn_alloc_ptmsi\n");
1594
1595 /* reset the PRNG used by sgsn_alloc_ptmsi */
1596 srand(1);
1597
1598 ptmsi1 = sgsn_alloc_ptmsi();
1599 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1600
1601 ptmsi2 = sgsn_alloc_ptmsi();
1602 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1603
1604 OSMO_ASSERT(ptmsi1 != ptmsi2);
1605
1606 printf(" - Repeated Attach Request\n");
1607
1608 /* reset the PRNG, so that the same P-TMSI will be generated
1609 * again */
1610 srand(1);
1611
1612 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1613
1614 /* Create a LLE/LLME */
1615 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1616 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1617 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1618
1619 /* inject the attach request */
1620 send_0408_message(lle->llme, foreign_tlli,
1621 attach_req, ARRAY_SIZE(attach_req));
1622
1623 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1624 OSMO_ASSERT(ctx != NULL);
1625 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1626 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1627
1628 old_ptmsi = ctx->p_tmsi_old;
1629
1630 /* we expect an identity request (IMEI) */
1631 OSMO_ASSERT(sgsn_tx_counter == 1);
1632
1633 /* inject the identity response (IMEI) */
1634 send_0408_message(ctx->llme, foreign_tlli,
1635 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1636
1637 /* check that the MM context has not been removed due to a failed
1638 * authorization */
1639 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1640
1641 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1642 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1643
1644 /* we expect an attach accept */
1645 OSMO_ASSERT(sgsn_tx_counter == 1);
1646
1647 /* we ignore this and send the attach again */
1648 send_0408_message(lle->llme, foreign_tlli,
1649 attach_req, ARRAY_SIZE(attach_req));
1650
1651 /* the allocated P-TMSI should be the same */
1652 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1653 OSMO_ASSERT(ctx != NULL);
1654 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1655 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1656 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1657
1658 /* inject the attach complete */
1659 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1660 send_0408_message(ctx->llme, local_tlli,
1661 attach_compl, ARRAY_SIZE(attach_compl));
1662
1663 /* we don't expect a response */
1664 OSMO_ASSERT(sgsn_tx_counter == 0);
1665
1666 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1667 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1668 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1669
1670 printf(" - Repeated RA Update Request\n");
1671
1672 /* inject the RA update request */
1673 send_0408_message(ctx->llme, local_tlli,
1674 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1675
1676 /* we expect an RA update accept */
1677 OSMO_ASSERT(sgsn_tx_counter == 1);
1678
1679 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1680 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1681 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1682
1683 /* repeat the RA update request */
1684 send_0408_message(ctx->llme, local_tlli,
1685 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1686
1687 /* we expect an RA update accept */
1688 OSMO_ASSERT(sgsn_tx_counter == 1);
1689
1690 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1691 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1692 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1693
1694 /* inject the RA update complete */
1695 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1696 send_0408_message(ctx->llme, local_tlli,
1697 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1698
1699 /* we don't expect a response */
1700 OSMO_ASSERT(sgsn_tx_counter == 0);
1701
1702 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1703 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1704 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1705
1706 /* inject the detach */
1707 send_0408_message(ctx->llme, local_tlli,
1708 detach_req, ARRAY_SIZE(detach_req));
1709
1710 /* verify that things are gone */
1711 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1712 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1713 OSMO_ASSERT(!ictx);
1714
1715 sgsn->cfg.auth_policy = saved_auth_policy;
1716}
1717
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01001718static void test_apn_matching(void)
1719{
1720 struct apn_ctx *actx, *actxs[9];
1721
1722 printf("Testing APN matching\n");
1723
1724 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1725 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1726 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1727 actxs[3] = NULL;
1728
1729 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1730 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1731 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1732 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1733
1734 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1735
1736 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1737 OSMO_ASSERT(actx == actxs[2]);
1738 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1739 OSMO_ASSERT(actx == actxs[2]);
1740 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1741 OSMO_ASSERT(actx == actxs[1]);
1742 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1743 OSMO_ASSERT(actx == actxs[1]);
1744 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1745 OSMO_ASSERT(actx == actxs[0]);
1746 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1747 OSMO_ASSERT(actx == NULL);
1748
1749 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1750 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1751 OSMO_ASSERT(actx == actxs[3]);
1752
1753 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1754 OSMO_ASSERT(actx == actxs[4]);
1755
1756 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1757 OSMO_ASSERT(actx == actxs[6]);
1758
1759 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1760 OSMO_ASSERT(actx == actxs[5]);
1761
1762 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1763 OSMO_ASSERT(actx == actxs[7]);
1764
1765 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1766 OSMO_ASSERT(actx == actxs[8]);
1767
1768 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1769 OSMO_ASSERT(actx == actxs[7]);
1770
1771 /* Free APN contexts and check how the matching changes */
1772
1773 sgsn_apn_ctx_free(actxs[7]);
1774 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1775 OSMO_ASSERT(actx == actxs[8]);
1776
1777 sgsn_apn_ctx_free(actxs[8]);
1778 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1779 OSMO_ASSERT(actx == actxs[6]);
1780
1781 sgsn_apn_ctx_free(actxs[6]);
1782 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1783 OSMO_ASSERT(actx == actxs[1]);
1784
1785 sgsn_apn_ctx_free(actxs[5]);
1786 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1787 OSMO_ASSERT(actx == actxs[4]);
1788
1789 sgsn_apn_ctx_free(actxs[4]);
1790 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1791 OSMO_ASSERT(actx == actxs[2]);
1792
1793 sgsn_apn_ctx_free(actxs[2]);
1794 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1795 OSMO_ASSERT(actx == actxs[1]);
1796
1797 sgsn_apn_ctx_free(actxs[1]);
1798 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1799 OSMO_ASSERT(actx == actxs[0]);
1800
1801 sgsn_apn_ctx_free(actxs[0]);
1802 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1803 OSMO_ASSERT(actx == actxs[3]);
1804
1805 sgsn_apn_ctx_free(actxs[3]);
1806 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1807 OSMO_ASSERT(actx == NULL);
1808}
1809
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001810struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1811 struct sgsn_subscriber_data *sdata);
1812
1813static void test_ggsn_selection(void)
1814{
1815 struct apn_ctx *actxs[4];
1816 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1817 struct gsm_subscriber *s1;
1818 const char *imsi1 = "1234567890";
1819 struct sgsn_mm_ctx *ctx;
1820 struct gprs_ra_id raid = { 0, };
1821 uint32_t local_tlli = 0xffeeddcc;
1822 enum gsm48_gsm_cause gsm_cause;
1823 struct tlv_parsed tp;
1824 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1825 struct sgsn_subscriber_pdp_data *pdp_data;
1826
1827 printf("Testing GGSN selection\n");
1828
1829 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1830
1831 /* Check for emptiness */
1832 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1833
1834 /* Create a context */
1835 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1836 ctx = alloc_mm_ctx(local_tlli, &raid);
1837 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1838
1839 /* Allocate and attach a subscriber */
1840 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1841 assert_subscr(s1, imsi1);
1842
1843 tp.lv[GSM48_IE_GSM_APN].len = 0;
1844 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1845
1846 /* TODO: Add PDP info entries to s1 */
1847
1848 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1849 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1850 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1851
1852 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1853 actxs[0]->ggsn = ggcs[0];
1854 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1855 actxs[1]->ggsn = ggcs[1];
1856 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1857 actxs[2]->ggsn = ggcs[2];
1858
1859 /* Resolve GGSNs */
1860
1861 tp.lv[GSM48_IE_GSM_APN].len =
1862 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1863
1864 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1865 OSMO_ASSERT(ggc != NULL);
1866 OSMO_ASSERT(ggc->id == 0);
1867
1868 tp.lv[GSM48_IE_GSM_APN].len =
1869 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1870
1871 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1872 OSMO_ASSERT(ggc != NULL);
1873 OSMO_ASSERT(ggc->id == 1);
1874
1875 tp.lv[GSM48_IE_GSM_APN].len = 0;
1876 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1877
1878 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1879 OSMO_ASSERT(ggc != NULL);
1880 OSMO_ASSERT(ggc->id == 0);
1881
1882 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1883 actxs[3]->ggsn = ggcs[2];
1884 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1885 OSMO_ASSERT(ggc != NULL);
1886 OSMO_ASSERT(ggc->id == 2);
1887
1888 sgsn_apn_ctx_free(actxs[3]);
1889 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1890
1891 tp.lv[GSM48_IE_GSM_APN].len =
1892 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1893
1894 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1895 OSMO_ASSERT(ggc == NULL);
1896 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
1897
1898 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
1899 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1900 OSMO_ASSERT(ggc == NULL);
1901 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
1902
1903 /* Add PDP data entry to subscriber */
1904
1905 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1906 pdp_data->context_id = 1;
1907
1908 pdp_data->pdp_type = 0x0121;
1909 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
1910
1911 tp.lv[GSM48_IE_GSM_APN].len =
1912 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1913
1914 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1915 OSMO_ASSERT(ggc != NULL);
1916 OSMO_ASSERT(ggc->id == 0);
1917
1918 tp.lv[GSM48_IE_GSM_APN].len =
1919 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1920
1921 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1922 OSMO_ASSERT(ggc == NULL);
1923 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
1924
1925 /* Cleanup */
1926
1927 subscr_put(s1);
1928 sgsn_mm_ctx_cleanup_free(ctx);
1929
1930 assert_no_subscrs();
1931
1932 sgsn_apn_ctx_free(actxs[0]);
1933 sgsn_apn_ctx_free(actxs[1]);
1934 sgsn_apn_ctx_free(actxs[2]);
1935
1936 sgsn_ggsn_ctx_free(ggcs[0]);
1937 sgsn_ggsn_ctx_free(ggcs[1]);
1938 sgsn_ggsn_ctx_free(ggcs[2]);
1939
1940 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1941}
1942
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001943static struct log_info_cat gprs_categories[] = {
1944 [DMM] = {
1945 .name = "DMM",
1946 .description = "Layer3 Mobility Management (MM)",
1947 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001948 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001949 },
1950 [DPAG] = {
1951 .name = "DPAG",
1952 .description = "Paging Subsystem",
1953 .color = "\033[1;38m",
1954 .enabled = 1, .loglevel = LOGL_NOTICE,
1955 },
1956 [DMEAS] = {
1957 .name = "DMEAS",
1958 .description = "Radio Measurement Processing",
1959 .enabled = 0, .loglevel = LOGL_NOTICE,
1960 },
1961 [DREF] = {
1962 .name = "DREF",
1963 .description = "Reference Counting",
1964 .enabled = 0, .loglevel = LOGL_NOTICE,
1965 },
1966 [DGPRS] = {
1967 .name = "DGPRS",
1968 .description = "GPRS Packet Service",
1969 .enabled = 1, .loglevel = LOGL_DEBUG,
1970 },
1971 [DNS] = {
1972 .name = "DNS",
1973 .description = "GPRS Network Service (NS)",
1974 .enabled = 1, .loglevel = LOGL_INFO,
1975 },
1976 [DBSSGP] = {
1977 .name = "DBSSGP",
1978 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1979 .enabled = 1, .loglevel = LOGL_DEBUG,
1980 },
1981 [DLLC] = {
1982 .name = "DLLC",
1983 .description = "GPRS Logical Link Control Protocol (LLC)",
1984 .enabled = 1, .loglevel = LOGL_DEBUG,
1985 },
1986 [DSNDCP] = {
1987 .name = "DSNDCP",
1988 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1989 .enabled = 1, .loglevel = LOGL_DEBUG,
1990 },
1991};
1992
1993static struct log_info info = {
1994 .cat = gprs_categories,
1995 .num_cat = ARRAY_SIZE(gprs_categories),
1996};
1997
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001998int main(int argc, char **argv)
1999{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002000 void *osmo_sgsn_ctx;
2001
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002002 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002003 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2004 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2005 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002006
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002007 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002008 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002009
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002010 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002011 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002012 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002013 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002014 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002015 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002016 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002017 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002018 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002019 test_gmm_attach_acl();
2020 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002021 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002022 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002023 test_gmm_attach_subscr_gsup_auth(0);
2024 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002025 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002026 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002027 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002028 test_gmm_ptmsi_allocation();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002029 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002030 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002031 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002032
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002033 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002034 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002035 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002036 return 0;
2037}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002038
2039
2040/* stubs */
2041struct osmo_prim_hdr;
2042int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2043{
2044 abort();
2045}