blob: 764027940bc84e19723c5b62cd3bc293d4a5f3c4 [file] [log] [blame]
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001/* test routines for gbproxy
2 * send NS messages to the gbproxy and dumps what happens
3 * (C) 2013 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 */
6
7#undef _GNU_SOURCE
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <getopt.h>
15#include <dlfcn.h>
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020017#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <osmocom/core/msgb.h>
21#include <osmocom/core/application.h>
22#include <osmocom/core/utils.h>
23#include <osmocom/core/logging.h>
24#include <osmocom/core/talloc.h>
25#include <osmocom/core/signal.h>
26#include <osmocom/core/rate_ctr.h>
Jacob Erlbeckb1381062014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck59748e62014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020029#include <osmocom/gprs/gprs_msgb.h>
30#include <osmocom/gprs/gprs_ns.h>
31#include <osmocom/gprs/gprs_bssgp.h>
32
33#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +020035#include <openbsc/gprs_llc.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020036#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020037
38#define REMOTE_BSS_ADDR 0x01020304
39#define REMOTE_SGSN_ADDR 0x05060708
40
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020041#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020042
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020043#define REMOTE_SGSN2_ADDR 0x15161718
44#define SGSN2_NSEI 0x0102
45
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020046struct gbproxy_config gbcfg = {0};
47
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020048static int dump_global(FILE *stream, int indent)
49{
50 unsigned int i;
51 const struct rate_ctr_group_desc *desc;
52 int rc;
53
54 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
55 if (rc < 0)
56 return rc;
57
58 desc = gbcfg.ctrg->desc;
59
60 for (i = 0; i < desc->num_ctr; i++) {
61 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
62 if (ctr->current) {
63 rc = fprintf(stream, "%*s %s: %llu\n",
64 indent, "",
65 desc->ctr_desc[i].description,
66 (long long)ctr->current);
67
68 if (rc < 0)
69 return rc;
70 }
71 }
72
73 return 0;
74}
75
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020076static int dump_peers(FILE *stream, int indent, time_t now,
77 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020078{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020079 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020080 struct gprs_ra_id raid;
81 unsigned int i;
82 const struct rate_ctr_group_desc *desc;
83 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084
85 rc = fprintf(stream, "%*sPeers:\n", indent, "");
86 if (rc < 0)
87 return rc;
88
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020089 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020090 struct gbproxy_tlli_info *tlli_info;
91 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020092 gsm48_parse_ra(&raid, peer->ra);
93
94 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
95 "RAI %u-%u-%u-%u\n",
96 indent, "",
97 peer->nsei, peer->bvci,
98 peer->blocked ? "" : "not ",
99 raid.mcc, raid.mnc, raid.lac, raid.rac);
100
101 if (rc < 0)
102 return rc;
103
104 desc = peer->ctrg->desc;
105
106 for (i = 0; i < desc->num_ctr; i++) {
107 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
108 if (ctr->current) {
109 rc = fprintf(stream, "%*s %s: %llu\n",
110 indent, "",
111 desc->ctr_desc[i].description,
112 (long long)ctr->current);
113
114 if (rc < 0)
115 return rc;
116 }
117 }
118
119 fprintf(stream, "%*s TLLI-Cache: %d\n",
120 indent, "", state->enabled_tllis_count);
121 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
122 char mi_buf[200];
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200123 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200124 int stored_msgs = 0;
125 struct llist_head *iter;
126 llist_for_each(iter, &tlli_info->stored_msgs)
127 stored_msgs++;
128
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +0200129 if (tlli_info->imsi_len > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200130 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
131 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +0200132 tlli_info->imsi,
133 tlli_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200134 } else {
135 snprintf(mi_buf, sizeof(mi_buf), "(none)");
136 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200137 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200138 indent, "", tlli_info->tlli.current);
139 if (tlli_info->tlli.assigned)
140 fprintf(stream, "/%08x", tlli_info->tlli.assigned);
141 if (tlli_info->sgsn_tlli.current) {
142 fprintf(stream, " -> %08x",
143 tlli_info->sgsn_tlli.current);
144 if (tlli_info->sgsn_tlli.assigned)
145 fprintf(stream, "/%08x",
146 tlli_info->sgsn_tlli.assigned);
147 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200148 fprintf(stream, ", IMSI %s, AGE %d",
149 mi_buf, (int)age);
150
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200151 if (stored_msgs)
152 fprintf(stream, ", STORED %d", stored_msgs);
153
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200154 if (cfg->check_imsi && tlli_info->enable_patching)
155 fprintf(stream, ", IMSI matches");
156
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200157 if (tlli_info->imsi_acq_pending)
158 fprintf(stream, ", IMSI acquisition in progress");
159
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200160 if (cfg->route_to_sgsn2)
161 fprintf(stream, ", SGSN NSEI %d",
162 tlli_info->sgsn_nsei);
163
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200164 if (tlli_info->is_deregistered)
165 fprintf(stream, ", DE-REGISTERED");
166
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200167 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200168 if (rc < 0)
169 return rc;
170 }
171 }
172
173 return 0;
174}
175
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200176const uint8_t *convert_ra(struct gprs_ra_id *raid)
177{
178 static uint8_t buf[6];
179 gsm48_construct_ra(buf, raid);
180 return buf;
181}
182
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200183/* DTAP - Attach Request */
184static const unsigned char dtap_attach_req[] = {
185 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
186 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
187 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
188 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
189 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
190 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200191};
192
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200193/* DTAP - Attach Request (invalid RAI) */
194static const unsigned char dtap_attach_req2[] = {
195 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
196 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
197 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
198 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
199 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
200 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
201};
202
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200203/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
204static const unsigned char dtap_attach_req3[] = {
205 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
206 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
207 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
208 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
209 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
210 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
211};
212
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200213/* DTAP - Identity Request */
214static const unsigned char dtap_identity_req[] = {
215 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200216};
217
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200218/* DTAP - Identity Response */
219static const unsigned char dtap_identity_resp[] = {
220 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
221 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200222};
223
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200224/* DTAP - Identity Response, IMSI 2 */
225static const unsigned char dtap_identity2_resp[] = {
226 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
227 0x16, 0x17, 0x18
228};
229
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200230/* DTAP - Identity Response, IMSI 3 */
231static const unsigned char dtap_identity3_resp[] = {
232 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
233 0x26, 0x27, 0x28
234};
235
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200236/* DTAP - Attach Accept */
237static const unsigned char dtap_attach_acc[] = {
238 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
239 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
240 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200241};
242
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200243/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200244static const unsigned char dtap_attach_acc2[] = {
245 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
246 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
247 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
248};
249
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200250/* DTAP - Attach Complete */
251static const unsigned char dtap_attach_complete[] = {
252 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200253};
254
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200255/* DTAP - GMM Information */
256static const unsigned char dtap_gmm_information[] = {
257 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200258};
259
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200260/* DTAP - Routing Area Update Request */
261static const unsigned char dtap_ra_upd_req[] = {
262 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
263 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
264 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
265 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
266 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
267 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
268 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200269};
270
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200271/* DTAP - Routing Area Update Accept */
272static const unsigned char dtap_ra_upd_acc[] = {
273 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
274 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
275 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200276};
277
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200278/* DTAP - Routing Area Update Accept, P-TMSI 2 */
279static const unsigned char dtap_ra_upd_acc2[] = {
280 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
281 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
282 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
283};
284
285/* DTAP - Routing Area Update Accept, P-TMSI 3 */
286static const unsigned char dtap_ra_upd_acc3[] = {
287 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
288 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
289 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
290};
291
292/* DTAP - Routing Area Update Complete */
293static const unsigned char dtap_ra_upd_complete[] = {
294 0x08, 0x0a
295};
296
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200297/* DTAP - Routing Area Update Reject */
298/* cause = 10 ("Implicitly detached"), force_standby = 0 */
299static const unsigned char dtap_ra_upd_rej[] = {
300 0x08, 0x0b, 0x0a, 0x00,
301};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200302
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200303/* DTAP - Activate PDP Context Request */
304static const unsigned char dtap_act_pdp_ctx_req[] = {
305 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200306 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
308 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
309 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
310 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200311 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200312};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200313
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200314/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200315/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200316static const unsigned char dtap_detach_po_req[] = {
317 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
318 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200319};
320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200321/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200322/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200323static const unsigned char dtap_detach_req[] = {
324 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
325 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200326};
327
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200328/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200329static const unsigned char dtap_detach_acc[] = {
330 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200331};
332
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200333/* DTAP - Detach Request (MT) */
334/* normal detach, reattach required, implicitly detached */
335static const unsigned char dtap_mt_detach_rea_req[] = {
336 0x08, 0x05, 0x01, 0x25, 0x0a
337};
338
339/* DTAP - Detach Request (MT) */
340/* normal detach, reattach not required, implicitly detached */
341static const unsigned char dtap_mt_detach_req[] = {
342 0x08, 0x05, 0x02, 0x25, 0x0a
343};
344
345/* DTAP - Detach Accept (MT) */
346static const unsigned char dtap_mt_detach_acc[] = {
347 0x08, 0x06
348};
349
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200350/* GPRS-LLC - SAPI: LLGMM, U, XID */
351static const unsigned char llc_u_xid_ul[] = {
352 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
353 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
354};
355
356/* GPRS-LLC - SAPI: LLGMM, U, XID */
357static const unsigned char llc_u_xid_dl[] = {
358 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
359 0xe4, 0xa9, 0x1a, 0x9e
360};
361
362/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
363static const unsigned char llc_ui_ll11_dns_query_ul[] = {
364 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
365 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
366 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
367 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
368 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
369 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
370 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
371 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
372 0x8f, 0x07
373};
374
375/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
376static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
377 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
378 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
379 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
380 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
381 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
382 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
383 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
384 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
385 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
386 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
387 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
388 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
389 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
390 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
391 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
392 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
393 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
394 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
395 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
396 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
397 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
398 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
399 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
400 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
401 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
402 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
403};
404
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200405static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
406 struct sockaddr_in *peer, const unsigned char* data,
407 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200408
409static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
410 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
411{
412 /* GPRS Network Service, PDU type: NS_RESET,
413 */
414 unsigned char msg[12] = {
415 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
416 0x04, 0x82, 0x11, 0x22
417 };
418
419 msg[3] = cause;
420 msg[6] = nsvci / 256;
421 msg[7] = nsvci % 256;
422 msg[10] = nsei / 256;
423 msg[11] = nsei % 256;
424
425 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
426}
427
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200428static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
429 uint16_t nsvci, uint16_t nsei)
430{
431 /* GPRS Network Service, PDU type: NS_RESET_ACK,
432 */
433 unsigned char msg[9] = {
434 0x03, 0x01, 0x82, 0x11, 0x22,
435 0x04, 0x82, 0x11, 0x22
436 };
437
438 msg[3] = nsvci / 256;
439 msg[4] = nsvci % 256;
440 msg[7] = nsei / 256;
441 msg[8] = nsei % 256;
442
443 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
444}
445
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200446static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
447{
448 /* GPRS Network Service, PDU type: NS_ALIVE */
449 unsigned char msg[1] = {
450 0x0a
451 };
452
453 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
454}
455
456static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
457{
458 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
459 unsigned char msg[1] = {
460 0x0b
461 };
462
463 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
464}
465
466static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
467{
468 /* GPRS Network Service, PDU type: NS_UNBLOCK */
469 unsigned char msg[1] = {
470 0x06
471 };
472
473 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
474}
475
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200476static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
477{
478 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
479 unsigned char msg[1] = {
480 0x07
481 };
482
483 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
484}
485
486static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
487 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200488 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
489{
490 /* GPRS Network Service, PDU type: NS_UNITDATA */
491 unsigned char msg[4096] = {
492 0x00, 0x00, 0x00, 0x00
493 };
494
495 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
496
497 msg[2] = nsbvci / 256;
498 msg[3] = nsbvci % 256;
499 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
500
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200501 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200502}
503
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200504static void send_bssgp_ul_unitdata(
505 struct gprs_ns_inst *nsi, const char *text,
506 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
507 struct gprs_ra_id *raid, uint16_t cell_id,
508 const uint8_t *llc_msg, size_t llc_msg_size)
509{
510 /* GPRS Network Service, PDU type: NS_UNITDATA */
511 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
512 unsigned char msg[4096] = {
513 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
514 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
515 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
516 };
517
518 size_t bssgp_msg_size = 23 + llc_msg_size;
519
520 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
521
522 gsm48_construct_ra(msg + 10, raid);
523 msg[1] = (uint8_t)(tlli >> 24);
524 msg[2] = (uint8_t)(tlli >> 16);
525 msg[3] = (uint8_t)(tlli >> 8);
526 msg[4] = (uint8_t)(tlli >> 0);
527 msg[16] = cell_id / 256;
528 msg[17] = cell_id % 256;
529 msg[21] = llc_msg_size / 256;
530 msg[22] = llc_msg_size % 256;
531 memcpy(msg + 23, llc_msg, llc_msg_size);
532
533 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
534 src_addr, nsbvci, msg, bssgp_msg_size);
535}
536
537static void send_bssgp_dl_unitdata(
538 struct gprs_ns_inst *nsi, const char *text,
539 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
540 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
541 const uint8_t *llc_msg, size_t llc_msg_size)
542{
543 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
544 unsigned char msg[4096] = {
545 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
546 0x16, 0x82, 0x02, 0x58,
547 };
548 unsigned char racap_drx[] = {
549 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
550 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
551 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
552 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
553 };
554
555 size_t bssgp_msg_size = 0;
556
557 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
558
559 msg[1] = (uint8_t)(tlli >> 24);
560 msg[2] = (uint8_t)(tlli >> 16);
561 msg[3] = (uint8_t)(tlli >> 8);
562 msg[4] = (uint8_t)(tlli >> 0);
563
564 bssgp_msg_size = 12;
565
566 if (with_racap_drx) {
567 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
568 bssgp_msg_size += sizeof(racap_drx);
569 }
570
571 if (imsi) {
572 OSMO_ASSERT(imsi_size <= 127);
573 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
574 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
575 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
576 bssgp_msg_size += 2 + imsi_size;
577 }
578
579 if ((bssgp_msg_size % 4) != 0) {
580 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
581 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
582 msg[bssgp_msg_size + 1] = 0x80 | abytes;
583 memset(msg + bssgp_msg_size + 2, 0, abytes);
584 bssgp_msg_size += 2 + abytes;
585 }
586
587 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
588 if (llc_msg_size < 128) {
589 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
590 bssgp_msg_size += 2;
591 } else {
592 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
593 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
594 bssgp_msg_size += 3;
595 }
596 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
597 bssgp_msg_size += llc_msg_size;
598
599
600 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
601 src_addr, nsbvci, msg, bssgp_msg_size);
602}
603
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200604static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
605 uint16_t bvci)
606{
607 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
608 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200609 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200610 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200611 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
612 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200613 };
614
615 msg[3] = bvci / 256;
616 msg[4] = bvci % 256;
617
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200618 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
619}
620
621static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
622 struct sockaddr_in *src_addr, uint16_t bvci)
623{
624 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
625 * BSSGP RESET_ACK */
626 static unsigned char msg[5] = {
627 0x23, 0x04, 0x82, 0x00,
628 0x00
629 };
630
631 msg[3] = bvci / 256;
632 msg[4] = bvci % 256;
633
634 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200635}
636
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200637static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
638 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200639 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200640 struct gprs_ra_id *raid)
641{
642 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
643 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200644 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
645 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200646 };
647
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200648 msg[3] = (uint8_t)(tlli >> 24);
649 msg[4] = (uint8_t)(tlli >> 16);
650 msg[5] = (uint8_t)(tlli >> 8);
651 msg[6] = (uint8_t)(tlli >> 0);
652
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200653 gsm48_construct_ra(msg + 9, raid);
654
655 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
656}
657
658static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
659 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200660 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200661 struct gprs_ra_id *raid)
662{
663 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
664 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200665 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
666 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200667 0x81, 0x01
668 };
669
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200670 msg[3] = (uint8_t)(tlli >> 24);
671 msg[4] = (uint8_t)(tlli >> 16);
672 msg[5] = (uint8_t)(tlli >> 8);
673 msg[6] = (uint8_t)(tlli >> 0);
674
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200675 gsm48_construct_ra(msg + 9, raid);
676
677 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
678}
679
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200680static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
681 struct sockaddr_in *src_addr,
682 uint16_t bvci, uint32_t tlli,
683 unsigned n_frames, unsigned n_octets)
684{
685 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
686 unsigned char msg[] = {
687 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
688 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
689 /* n octets */ 0xff, 0xff, 0xff
690 };
691
692 msg[3] = (uint8_t)(tlli >> 24);
693 msg[4] = (uint8_t)(tlli >> 16);
694 msg[5] = (uint8_t)(tlli >> 8);
695 msg[6] = (uint8_t)(tlli >> 0);
696 msg[9] = (uint8_t)(n_frames);
697 msg[12] = (uint8_t)(bvci >> 8);
698 msg[13] = (uint8_t)(bvci >> 0);
699 msg[16] = (uint8_t)(n_octets >> 16);
700 msg[17] = (uint8_t)(n_octets >> 8);
701 msg[18] = (uint8_t)(n_octets >> 0);
702
703 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
704}
705
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200706static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
707 struct sockaddr_in *src_addr,
708 uint16_t bvci, uint8_t tag)
709{
710 /* GPRS Network Service, PDU type: NS_UNITDATA,
711 * BSSGP FLOW_CONTROL_BVC */
712 unsigned char msg[] = {
713 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
714 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
715 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
716 };
717
718 msg[3] = tag;
719
720 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
721 msg, sizeof(msg));
722}
723
724static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
725 struct sockaddr_in *src_addr,
726 uint16_t bvci, uint8_t tag)
727{
728 /* GPRS Network Service, PDU type: NS_UNITDATA,
729 * BSSGP FLOW_CONTROL_BVC_ACK */
730 unsigned char msg[] = {
731 0x27, 0x1e, 0x81, /* Tag */ 0xce
732 };
733
734 msg[3] = tag;
735
736 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
737 msg, sizeof(msg));
738}
739
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200740static void send_llc_ul_ui(
741 struct gprs_ns_inst *nsi, const char *text,
742 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
743 struct gprs_ra_id *raid, uint16_t cell_id,
744 unsigned sapi, unsigned nu,
745 const uint8_t *msg, size_t msg_size)
746{
747 unsigned char llc_msg[4096] = {
748 0x00, 0xc0, 0x01
749 };
750
751 size_t llc_msg_size = 3 + msg_size + 3;
752 uint8_t e_bit = 0;
753 uint8_t pm_bit = 1;
754 unsigned fcs;
755
756 nu &= 0x01ff;
757
758 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
759
760 llc_msg[0] = (sapi & 0x0f);
761 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
762 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
763
764 memcpy(llc_msg + 3, msg, msg_size);
765
766 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
767 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
768 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
769 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
770
771 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
772 src_addr, nsbvci, tlli, raid, cell_id,
773 llc_msg, llc_msg_size);
774}
775
776static void send_llc_dl_ui(
777 struct gprs_ns_inst *nsi, const char *text,
778 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
779 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
780 unsigned sapi, unsigned nu,
781 const uint8_t *msg, size_t msg_size)
782{
783 /* GPRS Network Service, PDU type: NS_UNITDATA */
784 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
785 unsigned char llc_msg[4096] = {
786 0x00, 0x00, 0x01
787 };
788
789 size_t llc_msg_size = 3 + msg_size + 3;
790 uint8_t e_bit = 0;
791 uint8_t pm_bit = 1;
792 unsigned fcs;
793
794 nu &= 0x01ff;
795
796 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
797
798 llc_msg[0] = 0x40 | (sapi & 0x0f);
799 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
800 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
801
802 memcpy(llc_msg + 3, msg, msg_size);
803
804 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
805 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
806 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
807 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
808
809 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
810 src_addr, nsbvci, tlli,
811 with_racap_drx, imsi, imsi_size,
812 llc_msg, llc_msg_size);
813}
814
815
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200816static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
817 uint16_t nsvci, uint16_t nsei)
818{
819 printf("Setup NS-VC: remote 0x%08x:%d, "
820 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
821 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
822 nsvci, nsvci, nsei, nsei);
823
824 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
825 send_ns_alive(nsi, src_addr);
826 send_ns_unblock(nsi, src_addr);
827 send_ns_alive_ack(nsi, src_addr);
828}
829
830static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
831 uint16_t bvci)
832{
833 printf("Setup BSSGP: remote 0x%08x:%d, "
834 "BVCI 0x%04x(%d)\n\n",
835 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
836 bvci, bvci);
837
838 send_bssgp_reset(nsi, src_addr, bvci);
839}
840
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200841static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
842 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200843{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200844 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
845 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200846 send_ns_alive_ack(nsi, sgsn_peer);
847 send_ns_unblock_ack(nsi, sgsn_peer);
848 send_ns_alive(nsi, sgsn_peer);
849}
850
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200851static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
852{
853 sgsn_peer->sin_family = AF_INET;
854 sgsn_peer->sin_port = htons(32000);
855 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
856}
857
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200858static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
859{
860 sgsn_peer->sin_family = AF_INET;
861 sgsn_peer->sin_port = htons(32001);
862 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
863}
864
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200865static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
866{
867 size_t i;
868
869 for (i = 0; i < size; ++i) {
870 bss_peers[i].sin_family = AF_INET;
871 bss_peers[i].sin_port = htons((i + 1) * 1111);
872 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
873 }
874}
875
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200876int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
877 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
878
879/* override */
880int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
881 struct msgb *msg, uint16_t bvci)
882{
883 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
884 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200885 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200886
887 switch (event) {
888 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +0200889 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200890 default:
891 break;
892 }
893 return 0;
894}
895
896/* override */
897ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
898 const struct sockaddr *dest_addr, socklen_t addrlen)
899{
900 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
901 const struct sockaddr *, socklen_t);
902 static sendto_t real_sendto = NULL;
903 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200904 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200905
906 if (!real_sendto)
907 real_sendto = dlsym(RTLD_NEXT, "sendto");
908
909 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200910 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
911 dest_host, dest_port,
912 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200913 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200914 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
915 dest_host, dest_port,
916 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200917 else if (dest_host == REMOTE_SGSN2_ADDR)
918 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
919 dest_host, dest_port,
920 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200921 else
922 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
923
924 return len;
925}
926
927/* override */
928int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
929{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200930 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
931 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200932 uint16_t bvci = msgb_bvci(msg);
933 uint16_t nsei = msgb_nsei(msg);
934
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200935 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200936
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200937 if (!real_gprs_ns_sendmsg)
938 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
939
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200940 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200941 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
942 "msg length %d (%s)\n",
943 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200944 else if (nsei == SGSN2_NSEI)
945 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
946 "msg length %d (%s)\n",
947 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200948 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200949 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
950 "msg length %d (%s)\n",
951 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200952
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200953 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200954}
955
956static void dump_rate_ctr_group(FILE *stream, const char *prefix,
957 struct rate_ctr_group *ctrg)
958{
959 unsigned int i;
960
961 for (i = 0; i < ctrg->desc->num_ctr; i++) {
962 struct rate_ctr *ctr = &ctrg->ctr[i];
963 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
964 fprintf(stream, " %s%s: %llu%s",
965 prefix, ctrg->desc->ctr_desc[i].description,
966 (long long)ctr->current,
967 "\n");
968 };
969}
970
971/* Signal handler for signals from NS layer */
972static int test_signal(unsigned int subsys, unsigned int signal,
973 void *handler_data, void *signal_data)
974{
975 struct ns_signal_data *nssd = signal_data;
976 int rc;
977
978 if (subsys != SS_L_NS)
979 return 0;
980
981 switch (signal) {
982 case S_NS_RESET:
983 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
984 nssd->nsvc->nsvci,
985 gprs_ns_ll_str(nssd->nsvc));
986 break;
987
988 case S_NS_ALIVE_EXP:
989 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
990 nssd->nsvc->nsvci,
991 gprs_ns_ll_str(nssd->nsvc));
992 break;
993
994 case S_NS_BLOCK:
995 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
996 nssd->nsvc->nsvci,
997 gprs_ns_ll_str(nssd->nsvc));
998 break;
999
1000 case S_NS_UNBLOCK:
1001 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1002 nssd->nsvc->nsvci,
1003 gprs_ns_ll_str(nssd->nsvc));
1004 break;
1005
1006 case S_NS_REPLACED:
1007 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1008 nssd->nsvc->nsvci,
1009 gprs_ns_ll_str(nssd->nsvc));
1010 printf(" -> 0x%04x/%s\n",
1011 nssd->old_nsvc->nsvci,
1012 gprs_ns_ll_str(nssd->old_nsvc));
1013 break;
1014
1015 default:
1016 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1017 nssd->nsvc->nsvci,
1018 gprs_ns_ll_str(nssd->nsvc));
1019 break;
1020 }
1021 printf("\n");
1022 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1023 return rc;
1024}
1025
1026static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1027{
1028 struct msgb *msg;
1029 int ret;
1030 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1031 fprintf(stderr, "message too long: %d\n", data_len);
1032 return -1;
1033 }
1034
1035 msg = gprs_ns_msgb_alloc();
1036 memmove(msg->data, data, data_len);
1037 msg->l2h = msg->data;
1038 msgb_put(msg, data_len);
1039
1040 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1041 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1042 osmo_hexdump(data, data_len));
1043
1044 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1045
1046 printf("result (%s) = %d\n\n", text, ret);
1047
1048 msgb_free(msg);
1049
1050 return ret;
1051}
1052
1053static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1054{
1055 struct gprs_nsvc *nsvc;
1056
1057 printf("Current NS-VCIs:\n");
1058 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1059 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001060 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001061 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001062 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1063 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1064 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001065 );
1066 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1067 }
1068 printf("\n");
1069}
1070
1071static void test_gbproxy()
1072{
1073 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1074 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001075 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001076
1077 bssgp_nsi = nsi;
1078 gbcfg.nsi = bssgp_nsi;
1079 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1080
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001081 configure_sgsn_peer(&sgsn_peer);
1082 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001083
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001084 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001085 printf("--- Initialise SGSN ---\n\n");
1086
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001087 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001088 gprs_dump_nsi(nsi);
1089
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001090 printf("--- Initialise BSS 1 ---\n\n");
1091
1092 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1093 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1094 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001095 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001096
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001097 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1098
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001099 printf("--- Initialise BSS 2 ---\n\n");
1100
1101 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1102 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1103 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001104 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001105
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001106 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1107
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001108 printf("--- Move BSS 1 to new port ---\n\n");
1109
1110 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1111 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001112 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001113
1114 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1115
1116 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1117 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001118 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001119
1120 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1121
1122 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1123 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001124 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001125
1126 printf("--- Move BSS 2 to new port ---\n\n");
1127
1128 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1129 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001130 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001131
1132 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1133
1134 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1135 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001136 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001137
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001138 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1139
1140 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1141 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001142 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001143
1144 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1145
1146 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1147 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001148 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001149
1150 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1151
1152 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1153
1154 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1155 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001156 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001157
1158 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1159
1160 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1161
1162 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1163 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001164 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001165
1166 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1167
1168 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1169
1170 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1171
1172 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1173
1174 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1175
1176 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1177
1178 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1179
1180 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1181
1182 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1183
1184 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1185
1186 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1187
1188 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1189
1190 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1191
1192 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1193
1194 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1195 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001196 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001197
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001198 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001199
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001200 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1201
1202 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1203
1204 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1205
1206 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1207
1208 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1209
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001210 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1211
1212 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1213
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001214 /* Find peer */
1215 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1216 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1217 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1218 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1219 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1220 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1221
1222
1223 /* Cleanup */
1224 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1225 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1226 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1227 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1228 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1229
1230 dump_peers(stdout, 0, 0, &gbcfg);
1231
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001232 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001233
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001234 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001235 gprs_ns_destroy(nsi);
1236 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001237}
1238
1239static void test_gbproxy_ident_changes()
1240{
1241 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1242 struct sockaddr_in bss_peer[1] = {{0},};
1243 struct sockaddr_in sgsn_peer= {0};
1244 uint16_t nsei[2] = {0x1000, 0x2000};
1245 uint16_t nsvci[2] = {0x1001, 0x2001};
1246 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1247
1248 bssgp_nsi = nsi;
1249 gbcfg.nsi = bssgp_nsi;
1250 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1251
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001252 configure_sgsn_peer(&sgsn_peer);
1253 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001254
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001255 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001256 printf("--- Initialise SGSN ---\n\n");
1257
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001258 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001259 gprs_dump_nsi(nsi);
1260
1261 printf("--- Initialise BSS 1 ---\n\n");
1262
1263 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1264 gprs_dump_nsi(nsi);
1265
1266 printf("--- Setup BVCI 1 ---\n\n");
1267
1268 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1269 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001270 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001271
1272 printf("--- Setup BVCI 2 ---\n\n");
1273
1274 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1275 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001276 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001277
1278 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1279
1280 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1281 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1282
1283 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1284
1285 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1286 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1287
1288 printf("--- Change NSEI ---\n\n");
1289
1290 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1291 gprs_dump_nsi(nsi);
1292
1293 printf("--- Setup BVCI 1 ---\n\n");
1294
1295 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1296 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001297 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001298
1299 printf("--- Setup BVCI 3 ---\n\n");
1300
1301 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1302 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001304
1305 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1306
1307 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1308 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1309
1310 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1311 " (should fail) ---\n\n");
1312
1313 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001314 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001315 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001316 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001317
1318 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1319
1320 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1321 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1322
1323 printf("--- Change NSVCI ---\n\n");
1324
1325 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1326 gprs_dump_nsi(nsi);
1327
1328 printf("--- Setup BVCI 1 ---\n\n");
1329
1330 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1331 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001332 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001333
1334 printf("--- Setup BVCI 4 ---\n\n");
1335
1336 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1337 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001338 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001339
1340 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1341
1342 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1343 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1344
1345 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1346 " (should fail) ---\n\n");
1347
1348 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001349 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001350 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001351 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001352
1353 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1354
1355 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1356 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1357
1358 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1359
1360 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1361 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1362
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001363 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001364 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001365
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001366 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001367 gprs_ns_destroy(nsi);
1368 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001369}
1370
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001371static void test_gbproxy_ra_patching()
1372{
1373 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1374 struct sockaddr_in bss_peer[1] = {{0},};
1375 struct sockaddr_in sgsn_peer= {0};
1376 struct gprs_ra_id rai_bss =
1377 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1378 struct gprs_ra_id rai_sgsn =
1379 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1380 struct gprs_ra_id rai_unknown =
1381 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001382 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001383 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001384 const uint32_t ptmsi = 0xefe2b700;
1385 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001386 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001387 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001388 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001389 struct gbproxy_tlli_info *tlli_info;
1390 struct gbproxy_peer *peer;
1391
1392 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001393
1394 bssgp_nsi = nsi;
1395 gbcfg.nsi = bssgp_nsi;
1396 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001397 gbcfg.core_mcc = 123;
1398 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001399 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001400 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001401 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001402
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001403 configure_sgsn_peer(&sgsn_peer);
1404 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001405
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001406 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001407 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001408 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1409 gbcfg.match_re, err_msg);
1410 exit(1);
1411 }
1412
1413
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001414 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001415 printf("--- Initialise SGSN ---\n\n");
1416
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001417 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001418 gprs_dump_nsi(nsi);
1419
1420 printf("--- Initialise BSS 1 ---\n\n");
1421
1422 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1423 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1424 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001425 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001426
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001427 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001428 OSMO_ASSERT(peer != NULL);
1429
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001430 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1431
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001432 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1433 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001434
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001435 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001436 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001437
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001438 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1439 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1440
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001441 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1442
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001443 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1444 foreign_tlli, &rai_bss, cell_id,
1445 GPRS_SAPI_GMM, 0,
1446 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001447
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001448 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1449
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001450 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1451 foreign_tlli, 0, NULL, 0,
1452 GPRS_SAPI_GMM, 0,
1453 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001454
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001455 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1456 foreign_tlli, &rai_bss, cell_id,
1457 GPRS_SAPI_GMM, 3,
1458 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001459
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001460 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1461 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1462
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001463 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1464 foreign_tlli, 1, imsi, sizeof(imsi),
1465 GPRS_SAPI_GMM, 1,
1466 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001467
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001468 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1469
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001470 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1471 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1472 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1473
1474 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1475 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1476 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1477
1478 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1479 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1480 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1481
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001482 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001483 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001484 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1485 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1486 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1487 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1488 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1489 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1490 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1491 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001492
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001493 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1494 local_tlli, &rai_bss, cell_id,
1495 GPRS_SAPI_GMM, 4,
1496 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001497
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001498 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1499
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001500 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001501 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001502 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1503 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1504 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1505 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1506 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1507 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1508 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1509 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001510
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001511 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001512 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1513 local_tlli, &rai_bss, cell_id,
1514 GPRS_SAPI_GMM, 3,
1515 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001516
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001517 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1518
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001519 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001520 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001521 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1522 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1523 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1524 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1525 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1526 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1527 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1528 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001529
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001530 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1531 local_tlli, 1, imsi, sizeof(imsi),
1532 GPRS_SAPI_GMM, 2,
1533 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001534
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001535 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1536
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001537 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001538 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001539 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1540 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1541 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1542 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001543
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001544 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001545 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1546 local_tlli, &rai_bss, cell_id,
1547 GPRS_SAPI_GMM, 3,
1548 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001549
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001550 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1551
Jacob Erlbeck73685282014-05-23 20:48:07 +02001552 gbcfg.core_apn[0] = 0;
1553 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001554
1555 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001556 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1557 local_tlli, &rai_bss, cell_id,
1558 GPRS_SAPI_GMM, 3,
1559 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001560
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001561 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1562
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001563 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001564
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001565 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001566 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1567 local_tlli, &rai_bss, cell_id,
1568 GPRS_SAPI_GMM, 6,
1569 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001570
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001571 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1572 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1573
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001574 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1575 local_tlli, 1, imsi, sizeof(imsi),
1576 GPRS_SAPI_GMM, 5,
1577 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001578
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001579 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001580
1581 printf("--- RA update ---\n\n");
1582
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001583 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1584 foreign_tlli, &rai_bss, 0x7080,
1585 GPRS_SAPI_GMM, 5,
1586 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001587
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001588 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1589
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001590 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1591 foreign_tlli, 1, imsi, sizeof(imsi),
1592 GPRS_SAPI_GMM, 6,
1593 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001594
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001595 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1596
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001597 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001598 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1599 local_tlli, &rai_bss, cell_id,
1600 GPRS_SAPI_GMM, 3,
1601 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001602
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001603 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1604
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001605 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001606
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001607 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001608 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1609 local_tlli, &rai_bss, cell_id,
1610 GPRS_SAPI_GMM, 6,
1611 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001612
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001613 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1614
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001615 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001616 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001617
1618 printf("--- Bad cases ---\n\n");
1619
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001620 /* The RAI in the Attach Request message differs from the RAI in the
1621 * BSSGP message, only patch the latter */
1622
1623 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1624 foreign_tlli2, &rai_bss, cell_id,
1625 GPRS_SAPI_GMM, 0,
1626 dtap_attach_req2, sizeof(dtap_attach_req2));
1627
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001628 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1629
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001630 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001631 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1632 local_tlli, &rai_bss, cell_id,
1633 GPRS_SAPI_GMM, 3,
1634 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001635
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001636 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001637 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001638
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001639 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001640 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001641
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001642 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001643 gprs_ns_destroy(nsi);
1644 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001645}
1646
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001647static void test_gbproxy_ptmsi_assignment()
1648{
1649 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1650 struct sockaddr_in bss_peer[1] = {{0},};
1651 struct sockaddr_in sgsn_peer= {0};
1652 struct gprs_ra_id rai_bss =
1653 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1654 struct gprs_ra_id rai_unknown =
1655 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1656 uint16_t cell_id = 0x1234;
1657
1658 const uint32_t ptmsi = 0xefe2b700;
1659 const uint32_t local_tlli = 0xefe2b700;
1660
1661 const uint32_t foreign_tlli1 = 0x8000dead;
1662 const uint32_t foreign_tlli2 = 0x8000beef;
1663
1664 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1665 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1666
1667 struct gbproxy_tlli_info *tlli_info, *tlli_info2;
1668 struct gbproxy_peer *peer;
1669 unsigned bss_nu = 0;
1670 unsigned sgsn_nu = 0;
1671
1672 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1673
1674 bssgp_nsi = nsi;
1675 gbcfg.nsi = bssgp_nsi;
1676 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1677 gbcfg.core_mcc = 0;
1678 gbcfg.core_mnc = 0;
1679 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1680 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1681 gbcfg.patch_ptmsi = 0;
1682 gbcfg.bss_ptmsi_state = 0;
1683 gbcfg.sgsn_tlli_state = 1;
1684
1685 configure_sgsn_peer(&sgsn_peer);
1686 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1687
1688 printf("=== %s ===\n", __func__);
1689 printf("--- Initialise SGSN ---\n\n");
1690
1691 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1692
1693 printf("--- Initialise BSS 1 ---\n\n");
1694
1695 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1696 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1697
1698 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1699 OSMO_ASSERT(peer != NULL);
1700
1701 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1702
1703 gprs_dump_nsi(nsi);
1704 dump_global(stdout, 0);
1705 dump_peers(stdout, 0, 0, &gbcfg);
1706
1707 printf("--- Establish first LLC connection ---\n\n");
1708
1709 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1710 foreign_tlli1, &rai_unknown, cell_id,
1711 GPRS_SAPI_GMM, bss_nu++,
1712 dtap_attach_req, sizeof(dtap_attach_req));
1713
1714 dump_peers(stdout, 0, 0, &gbcfg);
1715
1716 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1717 foreign_tlli1, 0, NULL, 0,
1718 GPRS_SAPI_GMM, sgsn_nu++,
1719 dtap_identity_req, sizeof(dtap_identity_req));
1720
1721 dump_peers(stdout, 0, 0, &gbcfg);
1722
1723 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1724 foreign_tlli1, &rai_bss, cell_id,
1725 GPRS_SAPI_GMM, bss_nu++,
1726 dtap_identity_resp, sizeof(dtap_identity_resp));
1727
1728 dump_peers(stdout, 0, 0, &gbcfg);
1729
1730 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1731 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1732 GPRS_SAPI_GMM, sgsn_nu++,
1733 dtap_attach_acc, sizeof(dtap_attach_acc));
1734
1735 dump_peers(stdout, 0, 0, &gbcfg);
1736
1737 tlli_info = gbproxy_find_tlli(peer, foreign_tlli1);
1738 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1739 OSMO_ASSERT(tlli_info);
1740 OSMO_ASSERT(tlli_info == tlli_info2);
1741 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1742 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli1);
1743 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1744 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1745 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1746
1747 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1748 local_tlli, &rai_bss, cell_id,
1749 GPRS_SAPI_GMM, bss_nu++,
1750 dtap_attach_complete, sizeof(dtap_attach_complete));
1751
1752 dump_peers(stdout, 0, 0, &gbcfg);
1753
1754 tlli_info = gbproxy_find_tlli(peer, local_tlli);
1755 OSMO_ASSERT(tlli_info);
1756 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1757 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli1);
1758 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1759 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1760 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1761
1762
1763 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1764 local_tlli, 1, imsi1, sizeof(imsi1),
1765 GPRS_SAPI_GMM, sgsn_nu++,
1766 dtap_gmm_information, sizeof(dtap_gmm_information));
1767
1768 dump_peers(stdout, 0, 0, &gbcfg);
1769
1770 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1771 OSMO_ASSERT(tlli_info);
1772 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1773 OSMO_ASSERT(!gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
1774
1775 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1776 OSMO_ASSERT(tlli_info == tlli_info2);
1777 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1778 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1779 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1780
1781 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
1782
1783 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1784 foreign_tlli2, &rai_unknown, cell_id,
1785 GPRS_SAPI_GMM, bss_nu++,
1786 dtap_attach_req, sizeof(dtap_attach_req));
1787
1788 dump_peers(stdout, 0, 0, &gbcfg);
1789
1790 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1791 foreign_tlli2, 0, NULL, 0,
1792 GPRS_SAPI_GMM, sgsn_nu++,
1793 dtap_identity_req, sizeof(dtap_identity_req));
1794
1795 dump_peers(stdout, 0, 0, &gbcfg);
1796
1797 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1798 foreign_tlli2, &rai_bss, cell_id,
1799 GPRS_SAPI_GMM, bss_nu++,
1800 dtap_identity2_resp, sizeof(dtap_identity2_resp));
1801
1802 dump_peers(stdout, 0, 0, &gbcfg);
1803
1804 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1805 foreign_tlli2, 1, imsi2, sizeof(imsi2),
1806 GPRS_SAPI_GMM, sgsn_nu++,
1807 dtap_attach_acc, sizeof(dtap_attach_acc));
1808
1809 dump_peers(stdout, 0, 0, &gbcfg);
1810
1811 tlli_info = gbproxy_find_tlli(peer, foreign_tlli2);
1812 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1813 OSMO_ASSERT(tlli_info);
1814 OSMO_ASSERT(tlli_info == tlli_info2);
1815 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1816 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli2);
1817 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1818 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1819 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1820
1821 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1822 local_tlli, &rai_bss, cell_id,
1823 GPRS_SAPI_GMM, bss_nu++,
1824 dtap_attach_complete, sizeof(dtap_attach_complete));
1825
1826 dump_peers(stdout, 0, 0, &gbcfg);
1827
1828 tlli_info = gbproxy_find_tlli(peer, local_tlli);
1829 OSMO_ASSERT(tlli_info);
1830 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1831 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli2);
1832 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1833 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1834 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1835
1836 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1837 local_tlli, 1, imsi2, sizeof(imsi2),
1838 GPRS_SAPI_GMM, sgsn_nu++,
1839 dtap_gmm_information, sizeof(dtap_gmm_information));
1840
1841 dump_peers(stdout, 0, 0, &gbcfg);
1842
1843 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
1844 OSMO_ASSERT(tlli_info);
1845 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck1a024422014-09-16 14:10:27 +02001846 OSMO_ASSERT(!gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001847
1848 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
Jacob Erlbeck1a024422014-09-16 14:10:27 +02001849 OSMO_ASSERT(tlli_info == tlli_info2);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001850 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1851 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1852 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1853
1854 dump_global(stdout, 0);
1855
1856 gbprox_reset(&gbcfg);
1857 gprs_ns_destroy(nsi);
1858 nsi = NULL;
1859}
1860
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001861static void test_gbproxy_ptmsi_patching()
1862{
1863 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1864 struct sockaddr_in bss_peer[1] = {{0},};
1865 struct sockaddr_in sgsn_peer= {0};
1866 struct gprs_ra_id rai_bss =
1867 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1868 struct gprs_ra_id rai_sgsn =
1869 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001870 struct gprs_ra_id rai_wrong_mcc_sgsn =
1871 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001872 struct gprs_ra_id rai_unknown =
1873 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1874 uint16_t cell_id = 0x1234;
1875
1876 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001877 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1878 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001879 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001880 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1881 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001882 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001883 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001884
1885 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001886 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1887 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001888 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001889 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1890 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001891 const uint32_t foreign_bss_tlli = 0x8000dead;
1892
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001893
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001894 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1895 struct gbproxy_tlli_info *tlli_info;
1896 struct gbproxy_peer *peer;
1897 unsigned bss_nu = 0;
1898 unsigned sgsn_nu = 0;
1899
1900 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001901 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1902 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1903 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1904 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1905 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001906
1907 bssgp_nsi = nsi;
1908 gbcfg.nsi = bssgp_nsi;
1909 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1910 gbcfg.core_mcc = 123;
1911 gbcfg.core_mnc = 456;
1912 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1913 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1914 gbcfg.patch_ptmsi = 1;
1915 gbcfg.bss_ptmsi_state = 0;
1916 gbcfg.sgsn_tlli_state = 1;
1917
1918 configure_sgsn_peer(&sgsn_peer);
1919 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1920
1921 printf("=== %s ===\n", __func__);
1922 printf("--- Initialise SGSN ---\n\n");
1923
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001924 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001925
1926 printf("--- Initialise BSS 1 ---\n\n");
1927
1928 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1929 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1930
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001931 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001932 OSMO_ASSERT(peer != NULL);
1933
1934 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1935
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001936 gprs_dump_nsi(nsi);
1937 dump_global(stdout, 0);
1938 dump_peers(stdout, 0, 0, &gbcfg);
1939
1940 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1941
1942 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1943 foreign_bss_tlli, &rai_unknown, cell_id,
1944 GPRS_SAPI_GMM, bss_nu++,
1945 dtap_attach_req, sizeof(dtap_attach_req));
1946
1947 dump_peers(stdout, 0, 0, &gbcfg);
1948
1949 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1950 random_sgsn_tlli, 0, NULL, 0,
1951 GPRS_SAPI_GMM, sgsn_nu++,
1952 dtap_identity_req, sizeof(dtap_identity_req));
1953
1954 dump_peers(stdout, 0, 0, &gbcfg);
1955
1956 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1957 foreign_bss_tlli, &rai_bss, cell_id,
1958 GPRS_SAPI_GMM, bss_nu++,
1959 dtap_identity_resp, sizeof(dtap_identity_resp));
1960
1961 dump_peers(stdout, 0, 0, &gbcfg);
1962
1963 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1964 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1965 GPRS_SAPI_GMM, sgsn_nu++,
1966 dtap_attach_acc, sizeof(dtap_attach_acc));
1967
1968 dump_peers(stdout, 0, 0, &gbcfg);
1969
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001970 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001971 OSMO_ASSERT(tlli_info);
1972 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1973 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1974 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1975 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1976 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1977 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1978 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1979 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1980 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1981 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1982
1983 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1984 local_bss_tlli, &rai_bss, cell_id,
1985 GPRS_SAPI_GMM, bss_nu++,
1986 dtap_attach_complete, sizeof(dtap_attach_complete));
1987
1988 dump_peers(stdout, 0, 0, &gbcfg);
1989
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02001990 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001991 OSMO_ASSERT(tlli_info);
1992 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1993 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1994 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1995 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1996 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1997 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1998 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1999 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2000
2001 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2002 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2003 GPRS_SAPI_GMM, sgsn_nu++,
2004 dtap_gmm_information, sizeof(dtap_gmm_information));
2005
2006 dump_peers(stdout, 0, 0, &gbcfg);
2007
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002008 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002009 OSMO_ASSERT(tlli_info);
2010 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2011 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2012 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2013 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2014
Jacob Erlbeck82add782014-09-05 18:08:12 +02002015 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2016 local_bss_tlli, &rai_bss, cell_id,
2017 GPRS_SAPI_GMM, bss_nu++,
2018 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2019
2020 dump_peers(stdout, 0, 0, &gbcfg);
2021
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002022 /* Non-DTAP */
2023 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2024 local_bss_tlli, &rai_bss, cell_id,
2025 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2026
2027 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2028 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2029 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2030
2031 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2032 local_bss_tlli, &rai_bss, cell_id,
2033 llc_ui_ll11_dns_query_ul,
2034 sizeof(llc_ui_ll11_dns_query_ul));
2035
2036 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2037 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2038 llc_ui_ll11_dns_resp_dl,
2039 sizeof(llc_ui_ll11_dns_resp_dl));
2040
2041 dump_peers(stdout, 0, 0, &gbcfg);
2042
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002043 /* Repeated RA Update Requests */
2044 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2045 local_bss_tlli, &rai_bss, 0x7080,
2046 GPRS_SAPI_GMM, bss_nu++,
2047 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2048
2049 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2050 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2051 GPRS_SAPI_GMM, sgsn_nu++,
2052 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2053
2054 dump_peers(stdout, 0, 0, &gbcfg);
2055
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002056 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2057 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002058 OSMO_ASSERT(tlli_info);
2059 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2060 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2061 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2062 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2063 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2064 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2065 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2066 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2067 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2068 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2069
2070 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2071 local_bss_tlli2, &rai_bss, 0x7080,
2072 GPRS_SAPI_GMM, bss_nu++,
2073 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2074
2075 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2076 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2077 GPRS_SAPI_GMM, sgsn_nu++,
2078 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2079
2080 dump_peers(stdout, 0, 0, &gbcfg);
2081
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002082 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2083 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2084 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002085 OSMO_ASSERT(tlli_info);
2086 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
2087 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2088 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2089 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2090 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
2091 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2092 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2093 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2094 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2095 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
2096
2097 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2098 local_bss_tlli3, &rai_bss, 0x7080,
2099 GPRS_SAPI_GMM, bss_nu++,
2100 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2101
2102 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
2103
2104 OSMO_ASSERT(tlli_info);
2105 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2106 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2107 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2108 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2109
2110 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2111 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2112 GPRS_SAPI_GMM, sgsn_nu++,
2113 dtap_gmm_information, sizeof(dtap_gmm_information));
2114
2115 dump_peers(stdout, 0, 0, &gbcfg);
2116
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002117 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002118 OSMO_ASSERT(tlli_info);
2119 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
2120 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2121 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
2122 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2123
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002124 /* Other messages */
2125 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002126 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002130 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002131
2132 dump_peers(stdout, 0, 0, &gbcfg);
2133
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002134 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002135
2136 dump_peers(stdout, 0, 0, &gbcfg);
2137
2138 /* Bad case: Invalid BVCI */
2139 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002140 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002141 dump_global(stdout, 0);
2142
2143 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002144 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002145
2146 dump_global(stdout, 0);
2147
2148 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002149 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002150 &rai_wrong_mcc_sgsn);
2151
2152 dump_global(stdout, 0);
2153
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002154 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2155 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2156 unknown_sgsn_tlli, 1, NULL, 0,
2157 GPRS_SAPI_GMM, 2,
2158 dtap_gmm_information, sizeof(dtap_gmm_information));
2159
2160 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2161 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2162 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2163 GPRS_SAPI_GMM, 3,
2164 dtap_gmm_information, sizeof(dtap_gmm_information));
2165
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002166 /* Detach */
2167 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002168 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002169 GPRS_SAPI_GMM, bss_nu++,
2170 dtap_detach_req, sizeof(dtap_detach_req));
2171
2172 dump_peers(stdout, 0, 0, &gbcfg);
2173
2174 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002175 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002176 GPRS_SAPI_GMM, sgsn_nu++,
2177 dtap_detach_acc, sizeof(dtap_detach_acc));
2178
2179 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002180
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002181 dump_global(stdout, 0);
2182
2183 gbprox_reset(&gbcfg);
2184 gprs_ns_destroy(nsi);
2185 nsi = NULL;
2186}
2187
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002188static void test_gbproxy_imsi_acquisition()
2189{
2190 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2191 struct sockaddr_in bss_peer[1] = {{0},};
2192 struct sockaddr_in sgsn_peer= {0};
2193 struct gprs_ra_id rai_bss =
2194 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2195 struct gprs_ra_id rai_sgsn =
2196 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2197 struct gprs_ra_id rai_wrong_mcc_sgsn =
2198 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2199 struct gprs_ra_id rai_unknown =
2200 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2201 uint16_t cell_id = 0x1234;
2202
2203 const uint32_t sgsn_ptmsi = 0xefe2b700;
2204 const uint32_t local_sgsn_tlli = 0xefe2b700;
2205 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2206
2207 const uint32_t bss_ptmsi = 0xc00f7304;
2208 const uint32_t local_bss_tlli = 0xc00f7304;
2209 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002210 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002211
2212 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2213 struct gbproxy_tlli_info *tlli_info;
2214 struct gbproxy_peer *peer;
2215 unsigned bss_nu = 0;
2216 unsigned sgsn_nu = 0;
2217
2218 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2219
2220 bssgp_nsi = nsi;
2221 gbcfg.nsi = bssgp_nsi;
2222 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2223 gbcfg.core_mcc = 123;
2224 gbcfg.core_mnc = 456;
2225 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2226 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2227 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002228 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002229 gbcfg.bss_ptmsi_state = 0;
2230 gbcfg.sgsn_tlli_state = 1;
2231
2232 configure_sgsn_peer(&sgsn_peer);
2233 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2234
2235 printf("=== %s ===\n", __func__);
2236 printf("--- Initialise SGSN ---\n\n");
2237
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002238 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002239
2240 printf("--- Initialise BSS 1 ---\n\n");
2241
2242 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2243 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2244
2245 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2246 OSMO_ASSERT(peer != NULL);
2247
2248 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2249
2250 gprs_dump_nsi(nsi);
2251 dump_global(stdout, 0);
2252 dump_peers(stdout, 0, 0, &gbcfg);
2253
2254 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2255
2256 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002257 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002258 GPRS_SAPI_GMM, bss_nu++,
2259 dtap_attach_req, sizeof(dtap_attach_req));
2260
2261 dump_peers(stdout, 0, 0, &gbcfg);
2262
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002263 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2264 foreign_bss_tlli, &rai_bss, cell_id,
2265 GPRS_SAPI_GMM, bss_nu++,
2266 dtap_identity_resp, sizeof(dtap_identity_resp));
2267
2268 dump_peers(stdout, 0, 0, &gbcfg);
2269
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002270 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2271 random_sgsn_tlli, 0, NULL, 0,
2272 GPRS_SAPI_GMM, sgsn_nu++,
2273 dtap_identity_req, sizeof(dtap_identity_req));
2274
2275 dump_peers(stdout, 0, 0, &gbcfg);
2276
2277 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2278 foreign_bss_tlli, &rai_bss, cell_id,
2279 GPRS_SAPI_GMM, bss_nu++,
2280 dtap_identity_resp, sizeof(dtap_identity_resp));
2281
2282 dump_peers(stdout, 0, 0, &gbcfg);
2283
2284 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2285 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2286 GPRS_SAPI_GMM, sgsn_nu++,
2287 dtap_attach_acc, sizeof(dtap_attach_acc));
2288
2289 dump_peers(stdout, 0, 0, &gbcfg);
2290
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002291 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002292 OSMO_ASSERT(tlli_info);
2293 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2294 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2295 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2296 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2297 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2298 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2299 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2300 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2301 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2302 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2303
2304 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2305 local_bss_tlli, &rai_bss, cell_id,
2306 GPRS_SAPI_GMM, bss_nu++,
2307 dtap_attach_complete, sizeof(dtap_attach_complete));
2308
2309 dump_peers(stdout, 0, 0, &gbcfg);
2310
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002311 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002312 OSMO_ASSERT(tlli_info);
2313 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2314 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2315 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2316 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2317 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2318 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2319 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2320 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2321
2322 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2323 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2324 GPRS_SAPI_GMM, sgsn_nu++,
2325 dtap_gmm_information, sizeof(dtap_gmm_information));
2326
2327 dump_peers(stdout, 0, 0, &gbcfg);
2328
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002329 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002330 OSMO_ASSERT(tlli_info);
2331 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2332 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2333 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2334 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2335
2336 /* Non-DTAP */
2337 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2338 local_bss_tlli, &rai_bss, cell_id,
2339 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2340
2341 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2342 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2343 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2344
2345 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2346 local_bss_tlli, &rai_bss, cell_id,
2347 llc_ui_ll11_dns_query_ul,
2348 sizeof(llc_ui_ll11_dns_query_ul));
2349
2350 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2351 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2352 llc_ui_ll11_dns_resp_dl,
2353 sizeof(llc_ui_ll11_dns_resp_dl));
2354
2355 dump_peers(stdout, 0, 0, &gbcfg);
2356
2357 /* Other messages */
2358 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2359 local_bss_tlli, 1, 12);
2360
2361 dump_peers(stdout, 0, 0, &gbcfg);
2362
2363 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2364 local_sgsn_tlli, 1, 12);
2365
2366 dump_peers(stdout, 0, 0, &gbcfg);
2367
2368 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2369
2370 dump_peers(stdout, 0, 0, &gbcfg);
2371
2372 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2373
2374 dump_peers(stdout, 0, 0, &gbcfg);
2375
2376 /* Bad case: Invalid BVCI */
2377 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2378 local_bss_tlli, 1, 12);
2379 dump_global(stdout, 0);
2380
2381 /* Bad case: Invalid RAI */
2382 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2383
2384 dump_global(stdout, 0);
2385
2386 /* Bad case: Invalid MCC (LAC ok) */
2387 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2388 &rai_wrong_mcc_sgsn);
2389
2390 dump_global(stdout, 0);
2391
2392 /* Detach */
2393 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2394 local_bss_tlli, &rai_bss, cell_id,
2395 GPRS_SAPI_GMM, bss_nu++,
2396 dtap_detach_req, sizeof(dtap_detach_req));
2397
2398 dump_peers(stdout, 0, 0, &gbcfg);
2399
2400 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2401 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2402 GPRS_SAPI_GMM, sgsn_nu++,
2403 dtap_detach_acc, sizeof(dtap_detach_acc));
2404
2405 dump_peers(stdout, 0, 0, &gbcfg);
2406
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002407 /* Special case: Repeated Attach Requests */
2408
2409 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2410 foreign_bss_tlli, &rai_unknown, cell_id,
2411 GPRS_SAPI_GMM, bss_nu++,
2412 dtap_attach_req, sizeof(dtap_attach_req));
2413
2414 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2415 foreign_bss_tlli, &rai_unknown, cell_id,
2416 GPRS_SAPI_GMM, bss_nu++,
2417 dtap_attach_req, sizeof(dtap_attach_req));
2418
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002419 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2420 foreign_bss_tlli, &rai_bss, cell_id,
2421 GPRS_SAPI_GMM, bss_nu++,
2422 dtap_detach_req, sizeof(dtap_detach_req));
2423
2424 dump_peers(stdout, 0, 0, &gbcfg);
2425
2426 /* Special case: Detach from an unknown TLLI */
2427
2428 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2429 other_bss_tlli, &rai_bss, cell_id,
2430 GPRS_SAPI_GMM, bss_nu++,
2431 dtap_detach_req, sizeof(dtap_detach_req));
2432
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002433 dump_peers(stdout, 0, 0, &gbcfg);
2434
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002435 dump_global(stdout, 0);
2436
2437 gbprox_reset(&gbcfg);
2438 gprs_ns_destroy(nsi);
2439 nsi = NULL;
2440}
2441
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002442static void test_gbproxy_secondary_sgsn()
2443{
2444 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2445 struct sockaddr_in bss_peer[1] = {{0},};
2446 struct sockaddr_in sgsn_peer[2]= {{0},};
2447 struct gprs_ra_id rai_bss =
2448 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2449 struct gprs_ra_id rai_sgsn =
2450 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2451 struct gprs_ra_id rai_unknown =
2452 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2453 uint16_t cell_id = 0x1234;
2454
2455 const uint32_t sgsn_ptmsi = 0xefe2b700;
2456 const uint32_t local_sgsn_tlli = 0xefe2b700;
2457 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2458
2459 const uint32_t bss_ptmsi = 0xc00f7304;
2460 const uint32_t local_bss_tlli = 0xc00f7304;
2461 const uint32_t foreign_bss_tlli = 0x8000dead;
2462
2463 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2464 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2465 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2466 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2467 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2468 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2469
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002470 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002471 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002472 const uint32_t local_bss_tlli3 = 0xead4775a;
2473 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2474
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002475 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2476 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002477 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002478 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002479 struct gbproxy_tlli_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002480 struct gbproxy_peer *peer;
2481 unsigned bss_nu = 0;
2482 unsigned sgsn_nu = 0;
2483
2484 const char *err_msg = NULL;
2485 const char *filter_re = "999999";
2486
2487 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2488 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2489
2490 bssgp_nsi = nsi;
2491 gbcfg.nsi = bssgp_nsi;
2492 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2493 gbcfg.core_mcc = 123;
2494 gbcfg.core_mnc = 456;
2495 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2496 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2497 gbcfg.patch_ptmsi = 1;
2498 gbcfg.acquire_imsi = 1;
2499 gbcfg.bss_ptmsi_state = 0;
2500 gbcfg.sgsn_tlli_state = 1;
2501 gbcfg.route_to_sgsn2 = 1;
2502 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2503
2504 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2505 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2506 err_msg);
2507 OSMO_ASSERT(err_msg == NULL);
2508 }
2509
2510 configure_sgsn_peer(&sgsn_peer[0]);
2511 configure_sgsn2_peer(&sgsn_peer[1]);
2512 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2513
2514 printf("=== %s ===\n", __func__);
2515 printf("--- Initialise SGSN 1 ---\n\n");
2516
2517 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2518
2519 printf("--- Initialise SGSN 2 ---\n\n");
2520
2521 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2522
2523 printf("--- Initialise BSS 1 ---\n\n");
2524
2525 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2526 setup_bssgp(nsi, &bss_peer[0], 0x0);
2527 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2528 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2529 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2530 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2531
2532 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2533 OSMO_ASSERT(peer != NULL);
2534
2535 gprs_dump_nsi(nsi);
2536 dump_global(stdout, 0);
2537 dump_peers(stdout, 0, 0, &gbcfg);
2538
2539 printf("--- Flow control ---\n\n");
2540
2541 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2542 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2543 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2544
2545 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2546
2547 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2548 foreign_bss_tlli, &rai_unknown, cell_id,
2549 GPRS_SAPI_GMM, bss_nu++,
2550 dtap_attach_req, sizeof(dtap_attach_req));
2551
2552 dump_peers(stdout, 0, 0, &gbcfg);
2553
2554 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2555 foreign_bss_tlli, &rai_bss, cell_id,
2556 GPRS_SAPI_GMM, bss_nu++,
2557 dtap_identity_resp, sizeof(dtap_identity_resp));
2558
2559 dump_peers(stdout, 0, 0, &gbcfg);
2560
2561 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2562 random_sgsn_tlli, 0, NULL, 0,
2563 GPRS_SAPI_GMM, sgsn_nu++,
2564 dtap_identity_req, sizeof(dtap_identity_req));
2565
2566 dump_peers(stdout, 0, 0, &gbcfg);
2567
2568 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2569 foreign_bss_tlli, &rai_bss, cell_id,
2570 GPRS_SAPI_GMM, bss_nu++,
2571 dtap_identity_resp, sizeof(dtap_identity_resp));
2572
2573 dump_peers(stdout, 0, 0, &gbcfg);
2574
2575 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2576 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2577 GPRS_SAPI_GMM, sgsn_nu++,
2578 dtap_attach_acc, sizeof(dtap_attach_acc));
2579
2580 dump_peers(stdout, 0, 0, &gbcfg);
2581
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002582 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2583 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002584 OSMO_ASSERT(tlli_info);
2585 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2586 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2587 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2588 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2589 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2590 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2591 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2592 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2593 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2594 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2595
2596 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2597 local_bss_tlli, &rai_bss, cell_id,
2598 GPRS_SAPI_GMM, bss_nu++,
2599 dtap_attach_complete, sizeof(dtap_attach_complete));
2600
2601 dump_peers(stdout, 0, 0, &gbcfg);
2602
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002603 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2604 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002605 OSMO_ASSERT(tlli_info);
2606 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2607 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2608 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2609 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2610 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2611 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2612 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2613 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2614
2615 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2616 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2617 GPRS_SAPI_GMM, sgsn_nu++,
2618 dtap_gmm_information, sizeof(dtap_gmm_information));
2619
2620 dump_peers(stdout, 0, 0, &gbcfg);
2621
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002622 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2623 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002624 OSMO_ASSERT(tlli_info);
2625 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2626 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2627 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2628 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2629
2630 /* Non-DTAP */
2631 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2632 local_bss_tlli, &rai_bss, cell_id,
2633 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2634
2635 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2636 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2637 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2638
2639 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2640 local_bss_tlli, &rai_bss, cell_id,
2641 llc_ui_ll11_dns_query_ul,
2642 sizeof(llc_ui_ll11_dns_query_ul));
2643
2644 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2645 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2646 llc_ui_ll11_dns_resp_dl,
2647 sizeof(llc_ui_ll11_dns_resp_dl));
2648
2649 dump_peers(stdout, 0, 0, &gbcfg);
2650
2651 /* Other messages */
2652 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2653 local_bss_tlli, 1, 12);
2654
2655 dump_peers(stdout, 0, 0, &gbcfg);
2656
2657 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2658 local_sgsn_tlli, 1, 12);
2659
2660 dump_peers(stdout, 0, 0, &gbcfg);
2661
2662 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2663
2664 dump_peers(stdout, 0, 0, &gbcfg);
2665
2666 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2667
2668 dump_peers(stdout, 0, 0, &gbcfg);
2669
2670 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2671
2672 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2673 foreign_bss_tlli2, &rai_unknown, cell_id,
2674 GPRS_SAPI_GMM, bss_nu++,
2675 dtap_attach_req, sizeof(dtap_attach_req));
2676
2677 dump_peers(stdout, 0, 0, &gbcfg);
2678
2679 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2680 foreign_bss_tlli2, &rai_bss, cell_id,
2681 GPRS_SAPI_GMM, bss_nu++,
2682 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2683
2684 dump_peers(stdout, 0, 0, &gbcfg);
2685
2686 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2687 random_sgsn_tlli2, 0, NULL, 0,
2688 GPRS_SAPI_GMM, sgsn_nu++,
2689 dtap_identity_req, sizeof(dtap_identity_req));
2690
2691 dump_peers(stdout, 0, 0, &gbcfg);
2692
2693 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2694 foreign_bss_tlli2, &rai_bss, cell_id,
2695 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002696 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002697
2698 dump_peers(stdout, 0, 0, &gbcfg);
2699
2700 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2701 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2702 GPRS_SAPI_GMM, sgsn_nu++,
2703 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2704
2705 dump_peers(stdout, 0, 0, &gbcfg);
2706
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002707 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2708 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002709 OSMO_ASSERT(tlli_info);
2710 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2711 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2712 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2713 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2714 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2715 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2716 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2717 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2718 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2719 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2720
2721 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2722 local_bss_tlli2, &rai_bss, cell_id,
2723 GPRS_SAPI_GMM, bss_nu++,
2724 dtap_attach_complete, sizeof(dtap_attach_complete));
2725
2726 dump_peers(stdout, 0, 0, &gbcfg);
2727
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002728 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2729 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002730 OSMO_ASSERT(tlli_info);
2731 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2732 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2733 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2734 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2735 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2736 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2737 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2738 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2739
2740 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2741 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2742 GPRS_SAPI_GMM, sgsn_nu++,
2743 dtap_gmm_information, sizeof(dtap_gmm_information));
2744
2745 dump_peers(stdout, 0, 0, &gbcfg);
2746
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002747 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2748 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002749 OSMO_ASSERT(tlli_info);
2750 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2751 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2752 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2753 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2754
2755 /* Non-DTAP */
2756 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2757 local_bss_tlli2, &rai_bss, cell_id,
2758 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2759
2760 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2761 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2762 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2763
2764 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2765 local_bss_tlli2, &rai_bss, cell_id,
2766 llc_ui_ll11_dns_query_ul,
2767 sizeof(llc_ui_ll11_dns_query_ul));
2768
2769 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2770 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2771 llc_ui_ll11_dns_resp_dl,
2772 sizeof(llc_ui_ll11_dns_resp_dl));
2773
2774 dump_peers(stdout, 0, 0, &gbcfg);
2775
2776 /* Other messages */
2777 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2778 local_bss_tlli2, 1, 12);
2779
2780 dump_peers(stdout, 0, 0, &gbcfg);
2781
2782 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2783 local_sgsn_tlli2, 1, 12);
2784
2785 dump_peers(stdout, 0, 0, &gbcfg);
2786
2787 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2788
2789 dump_peers(stdout, 0, 0, &gbcfg);
2790
2791 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2792
2793 dump_peers(stdout, 0, 0, &gbcfg);
2794
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002795 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
2796
2797 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2798 foreign_bss_tlli3, &rai_unknown, cell_id,
2799 GPRS_SAPI_GMM, bss_nu++,
2800 dtap_attach_req, sizeof(dtap_attach_req));
2801
2802 dump_peers(stdout, 0, 0, &gbcfg);
2803
2804 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2805 foreign_bss_tlli3, &rai_bss, cell_id,
2806 GPRS_SAPI_GMM, bss_nu++,
2807 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2808
2809 dump_peers(stdout, 0, 0, &gbcfg);
2810
2811 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2812 random_sgsn_tlli3, 0, NULL, 0,
2813 GPRS_SAPI_GMM, sgsn_nu++,
2814 dtap_identity_req, sizeof(dtap_identity_req));
2815
2816 dump_peers(stdout, 0, 0, &gbcfg);
2817
2818 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2819 foreign_bss_tlli3, &rai_bss, cell_id,
2820 GPRS_SAPI_GMM, bss_nu++,
2821 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2822
2823 dump_peers(stdout, 0, 0, &gbcfg);
2824
2825 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
2826 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
2827 GPRS_SAPI_GMM, sgsn_nu++,
2828 dtap_attach_acc, sizeof(dtap_attach_acc));
2829
2830 dump_peers(stdout, 0, 0, &gbcfg);
2831
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002832 OSMO_ASSERT(!gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
2833 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
2834 OSMO_ASSERT(tlli_info);
2835 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
2836 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli3);
2837 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2838 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2839 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
2840 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2841 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli3);
2842 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2843 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2844 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2845
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002846 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2847 local_bss_tlli3, &rai_bss, cell_id,
2848 GPRS_SAPI_GMM, bss_nu++,
2849 dtap_attach_complete, sizeof(dtap_attach_complete));
2850
2851 dump_peers(stdout, 0, 0, &gbcfg);
2852
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002853 other_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2854 OSMO_ASSERT(other_info);
2855 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
2856 OSMO_ASSERT(tlli_info);
2857 OSMO_ASSERT(tlli_info != other_info);
2858 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
2859 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli3);
2860 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2861 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2862 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2863 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli3);
2864 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2865 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2866
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002867 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2868 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2869 GPRS_SAPI_GMM, sgsn_nu++,
2870 dtap_gmm_information, sizeof(dtap_gmm_information));
2871
2872 dump_peers(stdout, 0, 0, &gbcfg);
2873
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002874 other_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2875 OSMO_ASSERT(other_info);
2876 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
2877 OSMO_ASSERT(tlli_info);
2878 OSMO_ASSERT(tlli_info != other_info);
2879 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
2880 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2881 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2882 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2883
2884
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002885 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2886
2887 /* Detach */
2888 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2889 local_bss_tlli, &rai_bss, cell_id,
2890 GPRS_SAPI_GMM, bss_nu++,
2891 dtap_detach_req, sizeof(dtap_detach_req));
2892
2893 dump_peers(stdout, 0, 0, &gbcfg);
2894
2895 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2896 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2897 GPRS_SAPI_GMM, sgsn_nu++,
2898 dtap_detach_acc, sizeof(dtap_detach_acc));
2899
2900 dump_peers(stdout, 0, 0, &gbcfg);
2901
2902 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2903
2904 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2905 local_bss_tlli2, &rai_bss, cell_id,
2906 GPRS_SAPI_GMM, bss_nu++,
2907 dtap_detach_req, sizeof(dtap_detach_req));
2908
2909 dump_peers(stdout, 0, 0, &gbcfg);
2910
2911 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2912 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2913 GPRS_SAPI_GMM, sgsn_nu++,
2914 dtap_detach_acc, sizeof(dtap_detach_acc));
2915
2916 dump_peers(stdout, 0, 0, &gbcfg);
2917
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002918 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
2919
2920 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2921 local_bss_tlli3, &rai_bss, cell_id,
2922 GPRS_SAPI_GMM, bss_nu++,
2923 dtap_detach_req, sizeof(dtap_detach_req));
2924
2925 dump_peers(stdout, 0, 0, &gbcfg);
2926
2927 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2928 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2929 GPRS_SAPI_GMM, sgsn_nu++,
2930 dtap_detach_acc, sizeof(dtap_detach_acc));
2931
2932 dump_peers(stdout, 0, 0, &gbcfg);
2933
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002934 dump_global(stdout, 0);
2935
2936 gbprox_reset(&gbcfg);
2937 gprs_ns_destroy(nsi);
2938 nsi = NULL;
2939}
2940
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002941static void test_gbproxy_keep_info()
2942{
2943 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2944 struct sockaddr_in bss_peer[1] = {{0},};
2945 struct sockaddr_in sgsn_peer= {0};
2946 struct gprs_ra_id rai_bss =
2947 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2948 uint16_t cell_id = 0x1234;
2949
2950 const uint32_t ptmsi = 0xefe2b700;
2951 const uint32_t local_tlli = 0xefe2b700;
2952 const uint32_t foreign_tlli = 0xafe2b700;
2953
2954 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002955 struct gbproxy_tlli_info *tlli_info, *tlli_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002956 struct gbproxy_peer *peer;
2957 unsigned bss_nu = 0;
2958 unsigned sgsn_nu = 0;
2959
2960 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
2961
2962 bssgp_nsi = nsi;
2963 gbcfg.nsi = bssgp_nsi;
2964 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2965 gbcfg.patch_ptmsi = 0;
2966 gbcfg.acquire_imsi = 1;
2967 gbcfg.bss_ptmsi_state = 0;
2968 gbcfg.sgsn_tlli_state = 1;
2969 gbcfg.core_mcc = 0;
2970 gbcfg.core_mnc = 0;
2971 gbcfg.core_apn = NULL;
2972 gbcfg.core_apn_size = 0;
2973 gbcfg.route_to_sgsn2 = 0;
2974 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002975 gbcfg.keep_tlli_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002976
2977 configure_sgsn_peer(&sgsn_peer);
2978 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2979
2980 printf("=== %s ===\n", __func__);
2981 printf("--- Initialise SGSN ---\n\n");
2982
2983 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2984
2985 printf("--- Initialise BSS 1 ---\n\n");
2986
2987 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2988 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2989
2990 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2991 OSMO_ASSERT(peer != NULL);
2992
2993 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2994
2995 gprs_dump_nsi(nsi);
2996 dump_global(stdout, 0);
2997 dump_peers(stdout, 0, 0, &gbcfg);
2998
2999 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3000
3001 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3002 foreign_tlli, &rai_bss, cell_id,
3003 GPRS_SAPI_GMM, bss_nu++,
3004 dtap_attach_req, sizeof(dtap_attach_req));
3005
3006 dump_peers(stdout, 0, 0, &gbcfg);
3007
3008 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3009 OSMO_ASSERT(tlli_info);
3010 OSMO_ASSERT(tlli_info->imsi_len == 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003011 OSMO_ASSERT(!tlli_info->is_deregistered);
3012 OSMO_ASSERT(tlli_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003013
3014 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3015 foreign_tlli, &rai_bss, cell_id,
3016 GPRS_SAPI_GMM, bss_nu++,
3017 dtap_identity_resp, sizeof(dtap_identity_resp));
3018
3019 dump_peers(stdout, 0, 0, &gbcfg);
3020
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003021 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3022 OSMO_ASSERT(tlli_info);
3023 OSMO_ASSERT(tlli_info->imsi_len > 0);
3024 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3025
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003026 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3027 foreign_tlli, 0, NULL, 0,
3028 GPRS_SAPI_GMM, sgsn_nu++,
3029 dtap_identity_req, sizeof(dtap_identity_req));
3030
3031 dump_peers(stdout, 0, 0, &gbcfg);
3032
3033 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3034 foreign_tlli, &rai_bss, cell_id,
3035 GPRS_SAPI_GMM, bss_nu++,
3036 dtap_identity_resp, sizeof(dtap_identity_resp));
3037
3038 dump_peers(stdout, 0, 0, &gbcfg);
3039
3040 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3041 OSMO_ASSERT(tlli_info);
3042 OSMO_ASSERT(tlli_info->imsi_len > 0);
3043 OSMO_ASSERT(gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi)));
3044
3045 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3046 foreign_tlli, 1, imsi, sizeof(imsi),
3047 GPRS_SAPI_GMM, sgsn_nu++,
3048 dtap_attach_acc, sizeof(dtap_attach_acc));
3049
3050 dump_peers(stdout, 0, 0, &gbcfg);
3051
3052 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3053 local_tlli, &rai_bss, cell_id,
3054 GPRS_SAPI_GMM, bss_nu++,
3055 dtap_attach_complete, sizeof(dtap_attach_complete));
3056
3057 dump_peers(stdout, 0, 0, &gbcfg);
3058
3059 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3060 local_tlli, 1, imsi, sizeof(imsi),
3061 GPRS_SAPI_GMM, sgsn_nu++,
3062 dtap_gmm_information, sizeof(dtap_gmm_information));
3063
3064 dump_peers(stdout, 0, 0, &gbcfg);
3065
3066 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3067 OSMO_ASSERT(tlli_info);
3068
3069 /* Detach (MO) */
3070 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3071 local_tlli, &rai_bss, cell_id,
3072 GPRS_SAPI_GMM, bss_nu++,
3073 dtap_detach_req, sizeof(dtap_detach_req));
3074
3075 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3076 OSMO_ASSERT(tlli_info);
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
3080 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3081 local_tlli, 1, imsi, sizeof(imsi),
3082 GPRS_SAPI_GMM, sgsn_nu++,
3083 dtap_detach_acc, sizeof(dtap_detach_acc));
3084
3085 dump_peers(stdout, 0, 0, &gbcfg);
3086
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003087 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3088 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3089 OSMO_ASSERT(tlli_info);
3090 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003091
3092 /* Re-Attach */
3093 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3094 foreign_tlli, &rai_bss, cell_id,
3095 GPRS_SAPI_GMM, bss_nu++,
3096 dtap_attach_req3, sizeof(dtap_attach_req3));
3097
3098 dump_peers(stdout, 0, 0, &gbcfg);
3099
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003100 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3101 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3102 OSMO_ASSERT(tlli_info);
3103 OSMO_ASSERT(tlli_info == tlli_info2);
3104 OSMO_ASSERT(tlli_info->imsi_len != 0);
3105 OSMO_ASSERT(!tlli_info->is_deregistered);
3106 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3107
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003108 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3109 foreign_tlli, 1, imsi, sizeof(imsi),
3110 GPRS_SAPI_GMM, sgsn_nu++,
3111 dtap_attach_acc, sizeof(dtap_attach_acc));
3112
3113 dump_peers(stdout, 0, 0, &gbcfg);
3114
3115 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3116 local_tlli, &rai_bss, cell_id,
3117 GPRS_SAPI_GMM, bss_nu++,
3118 dtap_attach_complete, sizeof(dtap_attach_complete));
3119
3120 dump_peers(stdout, 0, 0, &gbcfg);
3121
3122 /* Detach (MT) */
3123 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3124 local_tlli, 1, imsi, sizeof(imsi),
3125 GPRS_SAPI_GMM, sgsn_nu++,
3126 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3127
3128 dump_peers(stdout, 0, 0, &gbcfg);
3129
3130 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3131 OSMO_ASSERT(tlli_info);
3132
3133 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3134 local_tlli, &rai_bss, cell_id,
3135 GPRS_SAPI_GMM, bss_nu++,
3136 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3137
3138 dump_peers(stdout, 0, 0, &gbcfg);
3139
3140 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003141 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3142 OSMO_ASSERT(tlli_info);
3143 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003144
3145 /* Re-Attach */
3146 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3147 foreign_tlli, &rai_bss, cell_id,
3148 GPRS_SAPI_GMM, bss_nu++,
3149 dtap_attach_req3, sizeof(dtap_attach_req3));
3150
3151 dump_peers(stdout, 0, 0, &gbcfg);
3152
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003153 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3154 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3155 OSMO_ASSERT(tlli_info);
3156 OSMO_ASSERT(tlli_info == tlli_info2);
3157 OSMO_ASSERT(tlli_info->imsi_len != 0);
3158 OSMO_ASSERT(!tlli_info->is_deregistered);
3159 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3160
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003161 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3162 foreign_tlli, 1, imsi, sizeof(imsi),
3163 GPRS_SAPI_GMM, sgsn_nu++,
3164 dtap_attach_acc, sizeof(dtap_attach_acc));
3165
3166 dump_peers(stdout, 0, 0, &gbcfg);
3167
3168 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3169 local_tlli, &rai_bss, cell_id,
3170 GPRS_SAPI_GMM, bss_nu++,
3171 dtap_attach_complete, sizeof(dtap_attach_complete));
3172
3173 dump_peers(stdout, 0, 0, &gbcfg);
3174
3175 /* Detach (MT) */
3176 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3177 local_tlli, 1, imsi, sizeof(imsi),
3178 GPRS_SAPI_GMM, sgsn_nu++,
3179 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3180
3181 dump_peers(stdout, 0, 0, &gbcfg);
3182
3183 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3184 OSMO_ASSERT(tlli_info);
3185
3186 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3187 local_tlli, &rai_bss, cell_id,
3188 GPRS_SAPI_GMM, bss_nu++,
3189 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3190
3191 dump_peers(stdout, 0, 0, &gbcfg);
3192
3193 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003194 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3195 OSMO_ASSERT(tlli_info);
3196 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003197
3198 /* Re-Attach */
3199 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3200 foreign_tlli, &rai_bss, cell_id,
3201 GPRS_SAPI_GMM, bss_nu++,
3202 dtap_attach_req3, sizeof(dtap_attach_req3));
3203
3204 dump_peers(stdout, 0, 0, &gbcfg);
3205
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003206 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3207 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3208 OSMO_ASSERT(tlli_info);
3209 OSMO_ASSERT(tlli_info == tlli_info2);
3210 OSMO_ASSERT(tlli_info->imsi_len != 0);
3211 OSMO_ASSERT(!tlli_info->is_deregistered);
3212 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3213
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003214 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3215 foreign_tlli, 1, imsi, sizeof(imsi),
3216 GPRS_SAPI_GMM, sgsn_nu++,
3217 dtap_attach_acc, sizeof(dtap_attach_acc));
3218
3219 dump_peers(stdout, 0, 0, &gbcfg);
3220
3221 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3222 local_tlli, &rai_bss, cell_id,
3223 GPRS_SAPI_GMM, bss_nu++,
3224 dtap_attach_complete, sizeof(dtap_attach_complete));
3225
3226 dump_peers(stdout, 0, 0, &gbcfg);
3227
3228 /* RA update procedure (reject -> Detach) */
3229 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3230 local_tlli, &rai_bss, 0x7080,
3231 GPRS_SAPI_GMM, bss_nu++,
3232 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3233
3234 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3235 local_tlli, 1, imsi, sizeof(imsi),
3236 GPRS_SAPI_GMM, sgsn_nu++,
3237 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3238
3239 dump_peers(stdout, 0, 0, &gbcfg);
3240
Jacob Erlbeck85e5c8f2014-09-16 12:16:58 +02003241 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3242 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3243 OSMO_ASSERT(tlli_info);
3244 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003245
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003246 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3247 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3248 foreign_tlli, &rai_bss, cell_id,
3249 GPRS_SAPI_GMM, bss_nu++,
3250 dtap_attach_req, sizeof(dtap_attach_req));
3251
3252 dump_peers(stdout, 0, 0, &gbcfg);
3253
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003254 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3255 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3256 OSMO_ASSERT(tlli_info);
3257 OSMO_ASSERT(tlli_info != tlli_info2);
3258 OSMO_ASSERT(tlli_info->imsi_len == 0);
3259 OSMO_ASSERT(!tlli_info->is_deregistered);
3260 OSMO_ASSERT(tlli_info->imsi_acq_pending);
3261
3262 /* This wouldn't happen in reality, since the Attach Request hadn't
3263 * been forwarded to the SGSN.
3264 * TODO: Add the missing messages.
3265 */
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003266 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3267 foreign_tlli, 1, imsi, sizeof(imsi),
3268 GPRS_SAPI_GMM, sgsn_nu++,
3269 dtap_attach_acc, sizeof(dtap_attach_acc));
3270
3271 dump_peers(stdout, 0, 0, &gbcfg);
3272
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003273 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3274 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3275 OSMO_ASSERT(tlli_info);
3276 OSMO_ASSERT(tlli_info == tlli_info2);
3277 OSMO_ASSERT(tlli_info->imsi_len >= 0);
3278 OSMO_ASSERT(!tlli_info->is_deregistered);
3279 OSMO_ASSERT(tlli_info->imsi_acq_pending);
3280
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003281 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3282 local_tlli, &rai_bss, cell_id,
3283 GPRS_SAPI_GMM, bss_nu++,
3284 dtap_attach_complete, sizeof(dtap_attach_complete));
3285
3286 dump_peers(stdout, 0, 0, &gbcfg);
3287
3288 /* Detach (MT) */
3289 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3290 local_tlli, 1, imsi, sizeof(imsi),
3291 GPRS_SAPI_GMM, sgsn_nu++,
3292 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3293
3294 dump_peers(stdout, 0, 0, &gbcfg);
3295
3296 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3297 OSMO_ASSERT(tlli_info);
3298
3299 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3300 local_tlli, &rai_bss, cell_id,
3301 GPRS_SAPI_GMM, bss_nu++,
3302 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3303
3304 dump_peers(stdout, 0, 0, &gbcfg);
3305
Jacob Erlbeck16a3cd32014-09-15 11:46:42 +02003306 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3307 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3308 OSMO_ASSERT(tlli_info);
3309 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003310
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003311 dump_global(stdout, 0);
3312
3313 gbprox_reset(&gbcfg);
3314 gprs_ns_destroy(nsi);
3315 nsi = NULL;
3316}
3317
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003318/* TODO: Move tlv testing to libosmocore */
3319int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3320int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3321 uint8_t **value);
3322int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3323 size_t *value_len);
3324int lv_shift(uint8_t **data, size_t *data_len,
3325 uint8_t **value, size_t *value_len);
3326
3327static void check_tlv_match(uint8_t **data, size_t *data_len,
3328 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3329{
3330 uint8_t *value;
3331 size_t value_len;
3332 int rc;
3333
3334 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3335 OSMO_ASSERT(rc == 0);
3336
3337 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003338 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003339 OSMO_ASSERT(value_len == exp_len);
3340 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3341}
3342
3343static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3344 uint8_t tag, size_t len, const uint8_t *exp_val)
3345{
3346 uint8_t *value;
3347 int rc;
3348
3349 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3350 OSMO_ASSERT(rc == 0);
3351
3352 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003353 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003354 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3355}
3356
3357static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3358 size_t len, const uint8_t *exp_val)
3359{
3360 uint8_t *value;
3361 int rc;
3362
3363 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003364 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003365 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3366}
3367
3368static void check_lv_shift(uint8_t **data, size_t *data_len,
3369 size_t exp_len, const uint8_t *exp_val)
3370{
3371 uint8_t *value;
3372 size_t value_len;
3373 int rc;
3374
3375 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003376 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003377 OSMO_ASSERT(value_len == exp_len);
3378 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3379}
3380
3381static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3382 const uint8_t *test_data)
3383{
3384 uint8_t buf[300] = {0};
3385
3386 uint8_t *unchanged_ptr = buf - 1;
3387 size_t unchanged_len = 0xdead;
3388 size_t tmp_data_len = data_len;
3389 uint8_t *value = unchanged_ptr;
3390 size_t value_len = unchanged_len;
3391 uint8_t *data = buf;
3392
3393 OSMO_ASSERT(data_len <= sizeof(buf));
3394
3395 tlv_put(data, tag, len, test_data);
3396 if (data_len < len + 2) {
3397 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3398 tag, &value, &value_len));
3399 OSMO_ASSERT(tmp_data_len == 0);
3400 OSMO_ASSERT(data == buf + data_len);
3401 OSMO_ASSERT(value == unchanged_ptr);
3402 OSMO_ASSERT(value_len == unchanged_len);
3403 } else {
3404 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3405 tag, &value, &value_len));
3406 OSMO_ASSERT(value != unchanged_ptr);
3407 OSMO_ASSERT(value_len != unchanged_len);
3408 }
3409}
3410
3411static void check_tv_fixed_match_data_len(size_t data_len,
3412 uint8_t tag, size_t len,
3413 const uint8_t *test_data)
3414{
3415 uint8_t buf[300] = {0};
3416
3417 uint8_t *unchanged_ptr = buf - 1;
3418 size_t tmp_data_len = data_len;
3419 uint8_t *value = unchanged_ptr;
3420 uint8_t *data = buf;
3421
3422 OSMO_ASSERT(data_len <= sizeof(buf));
3423
3424 tv_fixed_put(data, tag, len, test_data);
3425
3426 if (data_len < len + 1) {
3427 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3428 tag, len, &value));
3429 OSMO_ASSERT(tmp_data_len == 0);
3430 OSMO_ASSERT(data == buf + data_len);
3431 OSMO_ASSERT(value == unchanged_ptr);
3432 } else {
3433 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3434 tag, len, &value));
3435 OSMO_ASSERT(value != unchanged_ptr);
3436 }
3437}
3438
3439static void check_v_fixed_shift_data_len(size_t data_len,
3440 size_t len, const uint8_t *test_data)
3441{
3442 uint8_t buf[300] = {0};
3443
3444 uint8_t *unchanged_ptr = buf - 1;
3445 size_t tmp_data_len = data_len;
3446 uint8_t *value = unchanged_ptr;
3447 uint8_t *data = buf;
3448
3449 OSMO_ASSERT(data_len <= sizeof(buf));
3450
3451 memcpy(data, test_data, len);
3452
3453 if (data_len < len) {
3454 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3455 len, &value));
3456 OSMO_ASSERT(tmp_data_len == 0);
3457 OSMO_ASSERT(data == buf + data_len);
3458 OSMO_ASSERT(value == unchanged_ptr);
3459 } else {
3460 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3461 len, &value));
3462 OSMO_ASSERT(value != unchanged_ptr);
3463 }
3464}
3465
3466static void check_lv_shift_data_len(size_t data_len,
3467 size_t len, const uint8_t *test_data)
3468{
3469 uint8_t buf[300] = {0};
3470
3471 uint8_t *unchanged_ptr = buf - 1;
3472 size_t unchanged_len = 0xdead;
3473 size_t tmp_data_len = data_len;
3474 uint8_t *value = unchanged_ptr;
3475 size_t value_len = unchanged_len;
3476 uint8_t *data = buf;
3477
3478 lv_put(data, len, test_data);
3479 if (data_len < len + 1) {
3480 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3481 &value, &value_len));
3482 OSMO_ASSERT(tmp_data_len == 0);
3483 OSMO_ASSERT(data == buf + data_len);
3484 OSMO_ASSERT(value == unchanged_ptr);
3485 OSMO_ASSERT(value_len == unchanged_len);
3486 } else {
3487 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3488 &value, &value_len));
3489 OSMO_ASSERT(value != unchanged_ptr);
3490 OSMO_ASSERT(value_len != unchanged_len);
3491 }
3492}
3493
3494static void test_tlv_shift_functions()
3495{
3496 uint8_t test_data[1024];
3497 uint8_t buf[1024];
3498 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003499 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003500 uint8_t *data;
3501 size_t data_len;
3502 const uint8_t tag = 0x1a;
3503
3504 printf("Test shift functions\n");
3505
3506 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3507 test_data[i] = (uint8_t)i;
3508
3509 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003510 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003511
3512 memset(buf, 0xee, sizeof(buf));
3513 data_end = data = buf;
3514
3515 for (i = 0; i < iterations; i++) {
3516 data_end = tlv_put(data_end, tag, len, test_data);
3517 data_end = tv_fixed_put(data_end, tag, len, test_data);
3518 /* v_fixed_put */
3519 memcpy(data_end, test_data, len);
3520 data_end += len;
3521 data_end = lv_put(data_end, len, test_data);
3522 }
3523
3524 data_len = data_end - data;
3525 OSMO_ASSERT(data_len <= sizeof(buf));
3526
3527 for (i = 0; i < iterations; i++) {
3528 check_tlv_match(&data, &data_len, tag, len, test_data);
3529 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3530 check_v_fixed_shift(&data, &data_len, len, test_data);
3531 check_lv_shift(&data, &data_len, len, test_data);
3532 }
3533
3534 OSMO_ASSERT(data == data_end);
3535
3536 /* Test at end of data */
3537
3538 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3539 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3540 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3541 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3542
3543 /* Test invalid data_len */
3544 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3545 check_tlv_match_data_len(data_len, tag, len, test_data);
3546 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3547 check_v_fixed_shift_data_len(data_len, len, test_data);
3548 check_lv_shift_data_len(data_len, len, test_data);
3549 }
3550 }
3551}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003552
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003553struct gbproxy_tlli_info *register_tlli(
3554 struct gbproxy_peer *peer, uint32_t tlli,
3555 const uint8_t *imsi, size_t imsi_len, time_t now)
3556{
3557 struct gbproxy_tlli_info *tlli_info;
3558 int enable_patching = -1;
3559 int tlli_already_known = 0;
3560
3561 /* Check, whether the IMSI matches */
3562 if (gprs_is_mi_imsi(imsi, imsi_len)) {
3563 enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
3564 if (enable_patching < 0)
3565 return NULL;
3566 }
3567
3568 tlli_info = gbproxy_find_tlli(peer, tlli);
3569
3570 if (!tlli_info) {
3571 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, imsi_len);
3572
3573 if (tlli_info) {
3574 /* TLLI has changed somehow, adjust it */
3575 LOGP(DGPRS, LOGL_INFO,
3576 "The TLLI has changed from %08x to %08x\n",
3577 tlli_info->tlli.current, tlli);
3578 tlli_info->tlli.current = tlli;
3579 }
3580 }
3581
3582 if (!tlli_info) {
3583 tlli_info = gbproxy_tlli_info_alloc(peer);
3584 tlli_info->tlli.current = tlli;
3585 } else {
3586 gbproxy_detach_tlli_info(peer, tlli_info);
3587 tlli_already_known = 1;
3588 }
3589
3590 OSMO_ASSERT(tlli_info != NULL);
3591
3592 if (!tlli_already_known)
3593 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3594
3595 gbproxy_attach_tlli_info(peer, now, tlli_info);
3596 gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
3597
3598 if (enable_patching >= 0)
3599 tlli_info->enable_patching = enable_patching;
3600
3601 return tlli_info;
3602}
3603
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003604static void test_gbproxy_tlli_expire(void)
3605{
3606 struct gbproxy_config cfg = {0};
3607 struct gbproxy_peer *peer;
3608 const char *err_msg = NULL;
3609 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3610 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003611 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003612 const uint32_t tlli1 = 1234 | 0xc0000000;
3613 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003614 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003615 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003616 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003617
3618 printf("Test TLLI info expiry\n\n");
3619
3620 gbproxy_init_config(&cfg);
3621
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003622 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003623 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3624 err_msg);
3625 OSMO_ASSERT(err_msg == NULL);
3626 }
3627
3628 {
3629 struct gbproxy_tlli_info *tlli_info;
3630
3631 printf("Test TLLI replacement:\n");
3632
3633 cfg.tlli_max_len = 0;
3634 cfg.tlli_max_age = 0;
3635 peer = gbproxy_peer_alloc(&cfg, 20);
3636 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3637
3638 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003639 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003640 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003641 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003642 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003643 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3644
3645 /* replace the old entry */
3646 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003647 tlli_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003648 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003649 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003650 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003651 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3652
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003653 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003654
3655 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003656 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003657 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003658 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003659 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003660 OSMO_ASSERT(!tlli_info);
3661
3662 printf("\n");
3663
3664 gbproxy_peer_free(peer);
3665 }
3666
3667 {
3668 struct gbproxy_tlli_info *tlli_info;
3669
3670 printf("Test IMSI replacement:\n");
3671
3672 cfg.tlli_max_len = 0;
3673 cfg.tlli_max_age = 0;
3674 peer = gbproxy_peer_alloc(&cfg, 20);
3675 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3676
3677 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003678 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003679 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003680 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003681 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003682 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3683
3684 /* try to replace the old entry */
3685 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003686 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003687 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003688 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003689 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003690 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3691
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003692 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003693
3694 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003695 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003696 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003697 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003698 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003699 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003700
3701 printf("\n");
3702
3703 gbproxy_peer_free(peer);
3704 }
3705
3706 {
3707 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003708 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003709
3710 printf("Test TLLI expiry, max_len == 1:\n");
3711
3712 cfg.tlli_max_len = 1;
3713 cfg.tlli_max_age = 0;
3714 peer = gbproxy_peer_alloc(&cfg, 20);
3715 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3716
3717 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003718 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003719 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3720
3721 /* replace the old entry */
3722 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003723 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003724 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3725
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003726 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003727 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003728 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3729
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003730 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003731
3732 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003733 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003734 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003735 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003736 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003737 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003738
3739 printf("\n");
3740
3741 gbproxy_peer_free(peer);
3742 }
3743
3744 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003745 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003746 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003747
3748 printf("Test TLLI expiry, max_age == 1:\n");
3749
3750 cfg.tlli_max_len = 0;
3751 cfg.tlli_max_age = 1;
3752 peer = gbproxy_peer_alloc(&cfg, 20);
3753 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3754
3755 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003756 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003757 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3758
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003759 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003760 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003761 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003762 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3763
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003764 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003765 OSMO_ASSERT(num_removed == 1);
3766 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3767
3768 dump_peers(stdout, 2, now + 2, &cfg);
3769
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003770 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003771 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003772 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003773 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003774 OSMO_ASSERT(tlli_info);
3775 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
3776
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003777 printf("\n");
3778
3779 gbproxy_peer_free(peer);
3780 }
3781
3782 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003783 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003784 int num_removed;
3785
3786 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
3787
3788 cfg.tlli_max_len = 0;
3789 cfg.tlli_max_age = 1;
3790 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003791 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3792
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003793 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003794 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003795 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3796
3797 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003798 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003799 now + 1);
3800 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3801
3802 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003803 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003804 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003805 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
3806
3807 dump_peers(stdout, 2, now + 2, &cfg);
3808
3809 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003810 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003811 OSMO_ASSERT(num_removed == 2);
3812 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3813
3814 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003815
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003816 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003817 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003818 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003819 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003820 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003821 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003822 OSMO_ASSERT(tlli_info);
3823 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
3824
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003825 printf("\n");
3826
3827 gbproxy_peer_free(peer);
3828 }
3829}
3830
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003831static void test_gbproxy_imsi_matching(void)
3832{
3833 struct gbproxy_config cfg = {0};
3834 struct gbproxy_peer *peer;
3835 const char *err_msg = NULL;
3836 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3837 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3838 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3839 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3840 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3841 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3842 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3843 const char *filter_re1 = ".*";
3844 const char *filter_re2 = "^1234";
3845 const char *filter_re3 = "^4321";
3846 const char *filter_re4_bad = "^12[";
3847
3848 printf("=== Test IMSI/TMSI matching ===\n\n");
3849
3850 gbproxy_init_config(&cfg);
3851 OSMO_ASSERT(cfg.check_imsi == 0);
3852
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003853 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003854 OSMO_ASSERT(cfg.check_imsi == 1);
3855
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003856 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003857 OSMO_ASSERT(cfg.check_imsi == 1);
3858
3859 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003860 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003861 OSMO_ASSERT(err_msg != NULL);
3862 OSMO_ASSERT(cfg.check_imsi == 0);
3863
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003864 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003865 OSMO_ASSERT(cfg.check_imsi == 1);
3866
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003867 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003868 OSMO_ASSERT(cfg.check_imsi == 0);
3869
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003870 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003871 OSMO_ASSERT(cfg.check_imsi == 1);
3872
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003873 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003874 OSMO_ASSERT(cfg.check_imsi == 0);
3875
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003876 peer = gbproxy_peer_alloc(&cfg, 20);
3877
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003878 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003879 OSMO_ASSERT(cfg.check_imsi == 1);
3880
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003881 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3882 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003883 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003884 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003885 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003886 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3887 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3888 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3889 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3890 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003891
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003892 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003893 OSMO_ASSERT(cfg.check_imsi == 1);
3894
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003895 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3896 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3897 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3898 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3899 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3900 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3901 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003902
3903 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3904
3905 gbproxy_peer_free(peer);
3906}
3907
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003908static struct log_info_cat gprs_categories[] = {
3909 [DGPRS] = {
3910 .name = "DGPRS",
3911 .description = "GPRS Packet Service",
3912 .enabled = 1, .loglevel = LOGL_DEBUG,
3913 },
3914 [DNS] = {
3915 .name = "DNS",
3916 .description = "GPRS Network Service (NS)",
3917 .enabled = 1, .loglevel = LOGL_INFO,
3918 },
3919 [DBSSGP] = {
3920 .name = "DBSSGP",
3921 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3922 .enabled = 1, .loglevel = LOGL_DEBUG,
3923 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003924};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003925
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003926static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003927 .cat = gprs_categories,
3928 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003929};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003930
3931int main(int argc, char **argv)
3932{
3933 osmo_init_logging(&info);
3934 log_set_use_color(osmo_stderr_target, 0);
3935 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02003936 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003937
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003938 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003939 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3940 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003941
3942 rate_ctr_init(NULL);
3943
3944 setlinebuf(stdout);
3945
3946 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003947 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003948 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003949 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003950 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003951 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02003952 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003953 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003954 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003955 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003956 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003957 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003958 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003959 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003960
3961 exit(EXIT_SUCCESS);
3962}