blob: b35519f99966c58798963c49d9545ac8f907b8b7 [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 Erlbeck7430da62014-09-12 15:09:56 +0200160 if (tlli_info->is_deregistered)
161 fprintf(stream, ", DE-REGISTERED");
162
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200163 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200164 if (rc < 0)
165 return rc;
166 }
167 }
168
169 return 0;
170}
171
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200172const uint8_t *convert_ra(struct gprs_ra_id *raid)
173{
174 static uint8_t buf[6];
175 gsm48_construct_ra(buf, raid);
176 return buf;
177}
178
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200179/* DTAP - Attach Request */
180static const unsigned char dtap_attach_req[] = {
181 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
182 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
183 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
184 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
185 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
186 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200187};
188
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200189/* DTAP - Attach Request (invalid RAI) */
190static const unsigned char dtap_attach_req2[] = {
191 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
192 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
193 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
194 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
195 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
196 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
197};
198
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200199/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
200static const unsigned char dtap_attach_req3[] = {
201 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
202 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
203 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
204 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
205 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
206 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
207};
208
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200209/* DTAP - Identity Request */
210static const unsigned char dtap_identity_req[] = {
211 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200212};
213
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200214/* DTAP - Identity Response */
215static const unsigned char dtap_identity_resp[] = {
216 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
217 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200218};
219
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200220/* DTAP - Identity Response, IMSI 2 */
221static const unsigned char dtap_identity2_resp[] = {
222 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
223 0x16, 0x17, 0x18
224};
225
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200226/* DTAP - Identity Response, IMSI 3 */
227static const unsigned char dtap_identity3_resp[] = {
228 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
229 0x26, 0x27, 0x28
230};
231
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200232/* DTAP - Attach Accept */
233static const unsigned char dtap_attach_acc[] = {
234 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
235 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
236 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200237};
238
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200239/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200240static const unsigned char dtap_attach_acc2[] = {
241 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
242 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
243 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
244};
245
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200246/* DTAP - Attach Complete */
247static const unsigned char dtap_attach_complete[] = {
248 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200249};
250
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200251/* DTAP - GMM Information */
252static const unsigned char dtap_gmm_information[] = {
253 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200254};
255
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200256/* DTAP - Routing Area Update Request */
257static const unsigned char dtap_ra_upd_req[] = {
258 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
259 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
260 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
261 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
262 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
263 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
264 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200265};
266
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200267/* DTAP - Routing Area Update Accept */
268static const unsigned char dtap_ra_upd_acc[] = {
269 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
270 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
271 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200272};
273
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200274/* DTAP - Routing Area Update Accept, P-TMSI 2 */
275static const unsigned char dtap_ra_upd_acc2[] = {
276 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
277 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
278 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
279};
280
281/* DTAP - Routing Area Update Accept, P-TMSI 3 */
282static const unsigned char dtap_ra_upd_acc3[] = {
283 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
284 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
285 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
286};
287
288/* DTAP - Routing Area Update Complete */
289static const unsigned char dtap_ra_upd_complete[] = {
290 0x08, 0x0a
291};
292
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200293/* DTAP - Routing Area Update Reject */
294/* cause = 10 ("Implicitly detached"), force_standby = 0 */
295static const unsigned char dtap_ra_upd_rej[] = {
296 0x08, 0x0b, 0x0a, 0x00,
297};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200298
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200299/* DTAP - Activate PDP Context Request */
300static const unsigned char dtap_act_pdp_ctx_req[] = {
301 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200302 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
304 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
305 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
306 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200307 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200308};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200309
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200310/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200311/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200312static const unsigned char dtap_detach_po_req[] = {
313 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
314 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200315};
316
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200317/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200318/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200319static const unsigned char dtap_detach_req[] = {
320 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
321 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200322};
323
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200324/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200325static const unsigned char dtap_detach_acc[] = {
326 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200327};
328
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200329/* DTAP - Detach Request (MT) */
330/* normal detach, reattach required, implicitly detached */
331static const unsigned char dtap_mt_detach_rea_req[] = {
332 0x08, 0x05, 0x01, 0x25, 0x0a
333};
334
335/* DTAP - Detach Request (MT) */
336/* normal detach, reattach not required, implicitly detached */
337static const unsigned char dtap_mt_detach_req[] = {
338 0x08, 0x05, 0x02, 0x25, 0x0a
339};
340
341/* DTAP - Detach Accept (MT) */
342static const unsigned char dtap_mt_detach_acc[] = {
343 0x08, 0x06
344};
345
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200346/* GPRS-LLC - SAPI: LLGMM, U, XID */
347static const unsigned char llc_u_xid_ul[] = {
348 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
349 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
350};
351
352/* GPRS-LLC - SAPI: LLGMM, U, XID */
353static const unsigned char llc_u_xid_dl[] = {
354 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
355 0xe4, 0xa9, 0x1a, 0x9e
356};
357
358/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
359static const unsigned char llc_ui_ll11_dns_query_ul[] = {
360 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
361 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
362 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
363 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
364 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
365 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
366 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
367 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
368 0x8f, 0x07
369};
370
371/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
372static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
373 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
374 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
375 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
376 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
377 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
378 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
379 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
380 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
381 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
382 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
383 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
384 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
385 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
386 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
387 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
388 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
389 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
390 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
391 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
392 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
393 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
394 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
395 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
396 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
397 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
398 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
399};
400
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200401static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
402 struct sockaddr_in *peer, const unsigned char* data,
403 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200404
405static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
406 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
407{
408 /* GPRS Network Service, PDU type: NS_RESET,
409 */
410 unsigned char msg[12] = {
411 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
412 0x04, 0x82, 0x11, 0x22
413 };
414
415 msg[3] = cause;
416 msg[6] = nsvci / 256;
417 msg[7] = nsvci % 256;
418 msg[10] = nsei / 256;
419 msg[11] = nsei % 256;
420
421 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
422}
423
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200424static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
425 uint16_t nsvci, uint16_t nsei)
426{
427 /* GPRS Network Service, PDU type: NS_RESET_ACK,
428 */
429 unsigned char msg[9] = {
430 0x03, 0x01, 0x82, 0x11, 0x22,
431 0x04, 0x82, 0x11, 0x22
432 };
433
434 msg[3] = nsvci / 256;
435 msg[4] = nsvci % 256;
436 msg[7] = nsei / 256;
437 msg[8] = nsei % 256;
438
439 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
440}
441
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200442static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
443{
444 /* GPRS Network Service, PDU type: NS_ALIVE */
445 unsigned char msg[1] = {
446 0x0a
447 };
448
449 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
450}
451
452static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
453{
454 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
455 unsigned char msg[1] = {
456 0x0b
457 };
458
459 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
460}
461
462static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
463{
464 /* GPRS Network Service, PDU type: NS_UNBLOCK */
465 unsigned char msg[1] = {
466 0x06
467 };
468
469 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
470}
471
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200472static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
473{
474 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
475 unsigned char msg[1] = {
476 0x07
477 };
478
479 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
480}
481
482static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
483 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200484 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
485{
486 /* GPRS Network Service, PDU type: NS_UNITDATA */
487 unsigned char msg[4096] = {
488 0x00, 0x00, 0x00, 0x00
489 };
490
491 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
492
493 msg[2] = nsbvci / 256;
494 msg[3] = nsbvci % 256;
495 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
496
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200497 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200498}
499
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200500static void send_bssgp_ul_unitdata(
501 struct gprs_ns_inst *nsi, const char *text,
502 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
503 struct gprs_ra_id *raid, uint16_t cell_id,
504 const uint8_t *llc_msg, size_t llc_msg_size)
505{
506 /* GPRS Network Service, PDU type: NS_UNITDATA */
507 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
508 unsigned char msg[4096] = {
509 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
510 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
511 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
512 };
513
514 size_t bssgp_msg_size = 23 + llc_msg_size;
515
516 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
517
518 gsm48_construct_ra(msg + 10, raid);
519 msg[1] = (uint8_t)(tlli >> 24);
520 msg[2] = (uint8_t)(tlli >> 16);
521 msg[3] = (uint8_t)(tlli >> 8);
522 msg[4] = (uint8_t)(tlli >> 0);
523 msg[16] = cell_id / 256;
524 msg[17] = cell_id % 256;
525 msg[21] = llc_msg_size / 256;
526 msg[22] = llc_msg_size % 256;
527 memcpy(msg + 23, llc_msg, llc_msg_size);
528
529 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
530 src_addr, nsbvci, msg, bssgp_msg_size);
531}
532
533static void send_bssgp_dl_unitdata(
534 struct gprs_ns_inst *nsi, const char *text,
535 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
536 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
537 const uint8_t *llc_msg, size_t llc_msg_size)
538{
539 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
540 unsigned char msg[4096] = {
541 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
542 0x16, 0x82, 0x02, 0x58,
543 };
544 unsigned char racap_drx[] = {
545 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
546 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
547 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
548 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
549 };
550
551 size_t bssgp_msg_size = 0;
552
553 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
554
555 msg[1] = (uint8_t)(tlli >> 24);
556 msg[2] = (uint8_t)(tlli >> 16);
557 msg[3] = (uint8_t)(tlli >> 8);
558 msg[4] = (uint8_t)(tlli >> 0);
559
560 bssgp_msg_size = 12;
561
562 if (with_racap_drx) {
563 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
564 bssgp_msg_size += sizeof(racap_drx);
565 }
566
567 if (imsi) {
568 OSMO_ASSERT(imsi_size <= 127);
569 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
570 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
571 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
572 bssgp_msg_size += 2 + imsi_size;
573 }
574
575 if ((bssgp_msg_size % 4) != 0) {
576 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
577 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
578 msg[bssgp_msg_size + 1] = 0x80 | abytes;
579 memset(msg + bssgp_msg_size + 2, 0, abytes);
580 bssgp_msg_size += 2 + abytes;
581 }
582
583 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
584 if (llc_msg_size < 128) {
585 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
586 bssgp_msg_size += 2;
587 } else {
588 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
589 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
590 bssgp_msg_size += 3;
591 }
592 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
593 bssgp_msg_size += llc_msg_size;
594
595
596 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
597 src_addr, nsbvci, msg, bssgp_msg_size);
598}
599
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200600static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
601 uint16_t bvci)
602{
603 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
604 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200605 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200606 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200607 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
608 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200609 };
610
611 msg[3] = bvci / 256;
612 msg[4] = bvci % 256;
613
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200614 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
615}
616
617static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
618 struct sockaddr_in *src_addr, uint16_t bvci)
619{
620 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
621 * BSSGP RESET_ACK */
622 static unsigned char msg[5] = {
623 0x23, 0x04, 0x82, 0x00,
624 0x00
625 };
626
627 msg[3] = bvci / 256;
628 msg[4] = bvci % 256;
629
630 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200631}
632
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200633static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
634 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200635 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200636 struct gprs_ra_id *raid)
637{
638 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
639 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200640 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
641 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200642 };
643
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200644 msg[3] = (uint8_t)(tlli >> 24);
645 msg[4] = (uint8_t)(tlli >> 16);
646 msg[5] = (uint8_t)(tlli >> 8);
647 msg[6] = (uint8_t)(tlli >> 0);
648
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200649 gsm48_construct_ra(msg + 9, raid);
650
651 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
652}
653
654static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
655 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200656 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200657 struct gprs_ra_id *raid)
658{
659 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
660 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200661 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
662 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200663 0x81, 0x01
664 };
665
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200666 msg[3] = (uint8_t)(tlli >> 24);
667 msg[4] = (uint8_t)(tlli >> 16);
668 msg[5] = (uint8_t)(tlli >> 8);
669 msg[6] = (uint8_t)(tlli >> 0);
670
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200671 gsm48_construct_ra(msg + 9, raid);
672
673 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
674}
675
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200676static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
677 struct sockaddr_in *src_addr,
678 uint16_t bvci, uint32_t tlli,
679 unsigned n_frames, unsigned n_octets)
680{
681 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
682 unsigned char msg[] = {
683 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
684 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
685 /* n octets */ 0xff, 0xff, 0xff
686 };
687
688 msg[3] = (uint8_t)(tlli >> 24);
689 msg[4] = (uint8_t)(tlli >> 16);
690 msg[5] = (uint8_t)(tlli >> 8);
691 msg[6] = (uint8_t)(tlli >> 0);
692 msg[9] = (uint8_t)(n_frames);
693 msg[12] = (uint8_t)(bvci >> 8);
694 msg[13] = (uint8_t)(bvci >> 0);
695 msg[16] = (uint8_t)(n_octets >> 16);
696 msg[17] = (uint8_t)(n_octets >> 8);
697 msg[18] = (uint8_t)(n_octets >> 0);
698
699 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
700}
701
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200702static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
703 struct sockaddr_in *src_addr,
704 uint16_t bvci, uint8_t tag)
705{
706 /* GPRS Network Service, PDU type: NS_UNITDATA,
707 * BSSGP FLOW_CONTROL_BVC */
708 unsigned char msg[] = {
709 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
710 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
711 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
712 };
713
714 msg[3] = tag;
715
716 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
717 msg, sizeof(msg));
718}
719
720static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
721 struct sockaddr_in *src_addr,
722 uint16_t bvci, uint8_t tag)
723{
724 /* GPRS Network Service, PDU type: NS_UNITDATA,
725 * BSSGP FLOW_CONTROL_BVC_ACK */
726 unsigned char msg[] = {
727 0x27, 0x1e, 0x81, /* Tag */ 0xce
728 };
729
730 msg[3] = tag;
731
732 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
733 msg, sizeof(msg));
734}
735
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200736static void send_llc_ul_ui(
737 struct gprs_ns_inst *nsi, const char *text,
738 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
739 struct gprs_ra_id *raid, uint16_t cell_id,
740 unsigned sapi, unsigned nu,
741 const uint8_t *msg, size_t msg_size)
742{
743 unsigned char llc_msg[4096] = {
744 0x00, 0xc0, 0x01
745 };
746
747 size_t llc_msg_size = 3 + msg_size + 3;
748 uint8_t e_bit = 0;
749 uint8_t pm_bit = 1;
750 unsigned fcs;
751
752 nu &= 0x01ff;
753
754 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
755
756 llc_msg[0] = (sapi & 0x0f);
757 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
758 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
759
760 memcpy(llc_msg + 3, msg, msg_size);
761
762 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
763 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
764 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
765 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
766
767 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
768 src_addr, nsbvci, tlli, raid, cell_id,
769 llc_msg, llc_msg_size);
770}
771
772static void send_llc_dl_ui(
773 struct gprs_ns_inst *nsi, const char *text,
774 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
775 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
776 unsigned sapi, unsigned nu,
777 const uint8_t *msg, size_t msg_size)
778{
779 /* GPRS Network Service, PDU type: NS_UNITDATA */
780 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
781 unsigned char llc_msg[4096] = {
782 0x00, 0x00, 0x01
783 };
784
785 size_t llc_msg_size = 3 + msg_size + 3;
786 uint8_t e_bit = 0;
787 uint8_t pm_bit = 1;
788 unsigned fcs;
789
790 nu &= 0x01ff;
791
792 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
793
794 llc_msg[0] = 0x40 | (sapi & 0x0f);
795 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
796 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
797
798 memcpy(llc_msg + 3, msg, msg_size);
799
800 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
801 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
802 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
803 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
804
805 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
806 src_addr, nsbvci, tlli,
807 with_racap_drx, imsi, imsi_size,
808 llc_msg, llc_msg_size);
809}
810
811
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200812static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
813 uint16_t nsvci, uint16_t nsei)
814{
815 printf("Setup NS-VC: remote 0x%08x:%d, "
816 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
817 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
818 nsvci, nsvci, nsei, nsei);
819
820 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
821 send_ns_alive(nsi, src_addr);
822 send_ns_unblock(nsi, src_addr);
823 send_ns_alive_ack(nsi, src_addr);
824}
825
826static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
827 uint16_t bvci)
828{
829 printf("Setup BSSGP: remote 0x%08x:%d, "
830 "BVCI 0x%04x(%d)\n\n",
831 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
832 bvci, bvci);
833
834 send_bssgp_reset(nsi, src_addr, bvci);
835}
836
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200837static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
838 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200839{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200840 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
841 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200842 send_ns_alive_ack(nsi, sgsn_peer);
843 send_ns_unblock_ack(nsi, sgsn_peer);
844 send_ns_alive(nsi, sgsn_peer);
845}
846
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200847static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
848{
849 sgsn_peer->sin_family = AF_INET;
850 sgsn_peer->sin_port = htons(32000);
851 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
852}
853
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200854static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
855{
856 sgsn_peer->sin_family = AF_INET;
857 sgsn_peer->sin_port = htons(32001);
858 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
859}
860
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200861static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
862{
863 size_t i;
864
865 for (i = 0; i < size; ++i) {
866 bss_peers[i].sin_family = AF_INET;
867 bss_peers[i].sin_port = htons((i + 1) * 1111);
868 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
869 }
870}
871
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200872int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
873 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
874
875/* override */
876int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
877 struct msgb *msg, uint16_t bvci)
878{
879 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
880 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200881 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200882
883 switch (event) {
884 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200885 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200886 default:
887 break;
888 }
889 return 0;
890}
891
892/* override */
893ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
894 const struct sockaddr *dest_addr, socklen_t addrlen)
895{
896 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
897 const struct sockaddr *, socklen_t);
898 static sendto_t real_sendto = NULL;
899 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200900 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200901
902 if (!real_sendto)
903 real_sendto = dlsym(RTLD_NEXT, "sendto");
904
905 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200906 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
907 dest_host, dest_port,
908 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200909 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200910 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
911 dest_host, dest_port,
912 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200913 else if (dest_host == REMOTE_SGSN2_ADDR)
914 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
915 dest_host, dest_port,
916 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200917 else
918 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
919
920 return len;
921}
922
923/* override */
924int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
925{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200926 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
927 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200928 uint16_t bvci = msgb_bvci(msg);
929 uint16_t nsei = msgb_nsei(msg);
930
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200931 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200932
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200933 if (!real_gprs_ns_sendmsg)
934 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
935
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200936 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200937 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
938 "msg length %d (%s)\n",
939 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200940 else if (nsei == SGSN2_NSEI)
941 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
942 "msg length %d (%s)\n",
943 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200944 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200945 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
946 "msg length %d (%s)\n",
947 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200948
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200949 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200950}
951
952static void dump_rate_ctr_group(FILE *stream, const char *prefix,
953 struct rate_ctr_group *ctrg)
954{
955 unsigned int i;
956
957 for (i = 0; i < ctrg->desc->num_ctr; i++) {
958 struct rate_ctr *ctr = &ctrg->ctr[i];
959 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
960 fprintf(stream, " %s%s: %llu%s",
961 prefix, ctrg->desc->ctr_desc[i].description,
962 (long long)ctr->current,
963 "\n");
964 };
965}
966
967/* Signal handler for signals from NS layer */
968static int test_signal(unsigned int subsys, unsigned int signal,
969 void *handler_data, void *signal_data)
970{
971 struct ns_signal_data *nssd = signal_data;
972 int rc;
973
974 if (subsys != SS_L_NS)
975 return 0;
976
977 switch (signal) {
978 case S_NS_RESET:
979 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
980 nssd->nsvc->nsvci,
981 gprs_ns_ll_str(nssd->nsvc));
982 break;
983
984 case S_NS_ALIVE_EXP:
985 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
986 nssd->nsvc->nsvci,
987 gprs_ns_ll_str(nssd->nsvc));
988 break;
989
990 case S_NS_BLOCK:
991 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
992 nssd->nsvc->nsvci,
993 gprs_ns_ll_str(nssd->nsvc));
994 break;
995
996 case S_NS_UNBLOCK:
997 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
998 nssd->nsvc->nsvci,
999 gprs_ns_ll_str(nssd->nsvc));
1000 break;
1001
1002 case S_NS_REPLACED:
1003 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1004 nssd->nsvc->nsvci,
1005 gprs_ns_ll_str(nssd->nsvc));
1006 printf(" -> 0x%04x/%s\n",
1007 nssd->old_nsvc->nsvci,
1008 gprs_ns_ll_str(nssd->old_nsvc));
1009 break;
1010
1011 default:
1012 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1013 nssd->nsvc->nsvci,
1014 gprs_ns_ll_str(nssd->nsvc));
1015 break;
1016 }
1017 printf("\n");
1018 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1019 return rc;
1020}
1021
1022static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1023{
1024 struct msgb *msg;
1025 int ret;
1026 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1027 fprintf(stderr, "message too long: %d\n", data_len);
1028 return -1;
1029 }
1030
1031 msg = gprs_ns_msgb_alloc();
1032 memmove(msg->data, data, data_len);
1033 msg->l2h = msg->data;
1034 msgb_put(msg, data_len);
1035
1036 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1037 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1038 osmo_hexdump(data, data_len));
1039
1040 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1041
1042 printf("result (%s) = %d\n\n", text, ret);
1043
1044 msgb_free(msg);
1045
1046 return ret;
1047}
1048
1049static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1050{
1051 struct gprs_nsvc *nsvc;
1052
1053 printf("Current NS-VCIs:\n");
1054 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1055 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001056 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001057 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001058 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1059 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1060 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001061 );
1062 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1063 }
1064 printf("\n");
1065}
1066
1067static void test_gbproxy()
1068{
1069 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1070 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001071 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001072
1073 bssgp_nsi = nsi;
1074 gbcfg.nsi = bssgp_nsi;
1075 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1076
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001077 configure_sgsn_peer(&sgsn_peer);
1078 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001079
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001080 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001081 printf("--- Initialise SGSN ---\n\n");
1082
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001083 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001084 gprs_dump_nsi(nsi);
1085
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001086 printf("--- Initialise BSS 1 ---\n\n");
1087
1088 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1089 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1090 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001091 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001092
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001093 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1094
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001095 printf("--- Initialise BSS 2 ---\n\n");
1096
1097 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1098 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1099 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001100 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001101
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001102 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1103
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001104 printf("--- Move BSS 1 to new port ---\n\n");
1105
1106 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1107 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001108 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001109
1110 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1111
1112 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1113 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001114 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001115
1116 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1117
1118 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1119 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001120 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001121
1122 printf("--- Move BSS 2 to new port ---\n\n");
1123
1124 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1125 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001126 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001127
1128 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1129
1130 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1131 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001132 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001133
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001134 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1135
1136 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1137 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001138 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001139
1140 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1141
1142 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1143 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001144 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001145
1146 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1147
1148 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1149
1150 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1151 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001152 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001153
1154 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1155
1156 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1157
1158 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1159 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001160 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001161
1162 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1163
1164 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1165
1166 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1167
1168 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1169
1170 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1171
1172 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1173
1174 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1175
1176 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1177
1178 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1179
1180 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1181
1182 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1183
1184 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1185
1186 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1187
1188 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1189
1190 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1191 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001192 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001193
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001194 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001195
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001196 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1197
1198 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1199
1200 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1201
1202 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1203
1204 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1205
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001206 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1207
1208 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1209
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001210 /* Find peer */
1211 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1212 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1213 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1214 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1215 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1216 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1217
1218
1219 /* Cleanup */
1220 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1221 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1222 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1223 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1224 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1225
1226 dump_peers(stdout, 0, 0, &gbcfg);
1227
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001228 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001229
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001230 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001231 gprs_ns_destroy(nsi);
1232 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001233}
1234
1235static void test_gbproxy_ident_changes()
1236{
1237 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1238 struct sockaddr_in bss_peer[1] = {{0},};
1239 struct sockaddr_in sgsn_peer= {0};
1240 uint16_t nsei[2] = {0x1000, 0x2000};
1241 uint16_t nsvci[2] = {0x1001, 0x2001};
1242 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1243
1244 bssgp_nsi = nsi;
1245 gbcfg.nsi = bssgp_nsi;
1246 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1247
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001248 configure_sgsn_peer(&sgsn_peer);
1249 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001250
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001251 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001252 printf("--- Initialise SGSN ---\n\n");
1253
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001254 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001255 gprs_dump_nsi(nsi);
1256
1257 printf("--- Initialise BSS 1 ---\n\n");
1258
1259 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1260 gprs_dump_nsi(nsi);
1261
1262 printf("--- Setup BVCI 1 ---\n\n");
1263
1264 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1265 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001266 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001267
1268 printf("--- Setup BVCI 2 ---\n\n");
1269
1270 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1271 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001272 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001273
1274 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1275
1276 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1277 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1278
1279 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1280
1281 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1282 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1283
1284 printf("--- Change NSEI ---\n\n");
1285
1286 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1287 gprs_dump_nsi(nsi);
1288
1289 printf("--- Setup BVCI 1 ---\n\n");
1290
1291 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1292 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001293 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001294
1295 printf("--- Setup BVCI 3 ---\n\n");
1296
1297 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1298 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001299 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001300
1301 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1302
1303 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1304 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1305
1306 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1307 " (should fail) ---\n\n");
1308
1309 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001310 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001311 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001312 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001313
1314 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1315
1316 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1317 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1318
1319 printf("--- Change NSVCI ---\n\n");
1320
1321 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1322 gprs_dump_nsi(nsi);
1323
1324 printf("--- Setup BVCI 1 ---\n\n");
1325
1326 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1327 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001328 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001329
1330 printf("--- Setup BVCI 4 ---\n\n");
1331
1332 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1333 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001334 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001335
1336 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1337
1338 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1339 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1340
1341 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1342 " (should fail) ---\n\n");
1343
1344 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001345 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001346 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001347 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001348
1349 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1350
1351 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1352 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1353
1354 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1355
1356 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1357 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1358
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001359 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001360 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001361
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001362 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001363 gprs_ns_destroy(nsi);
1364 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001365}
1366
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001367static void test_gbproxy_ra_patching()
1368{
1369 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1370 struct sockaddr_in bss_peer[1] = {{0},};
1371 struct sockaddr_in sgsn_peer= {0};
1372 struct gprs_ra_id rai_bss =
1373 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1374 struct gprs_ra_id rai_sgsn =
1375 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1376 struct gprs_ra_id rai_unknown =
1377 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001378 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001379 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001380 const uint32_t ptmsi = 0xefe2b700;
1381 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001382 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001383 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001384 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001385 struct gbproxy_tlli_info *tlli_info;
1386 struct gbproxy_peer *peer;
1387
1388 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001389
1390 bssgp_nsi = nsi;
1391 gbcfg.nsi = bssgp_nsi;
1392 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001393 gbcfg.core_mcc = 123;
1394 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001395 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001396 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001397 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001398
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001399 configure_sgsn_peer(&sgsn_peer);
1400 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001401
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001402 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001403 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001404 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1405 gbcfg.match_re, err_msg);
1406 exit(1);
1407 }
1408
1409
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001410 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001411 printf("--- Initialise SGSN ---\n\n");
1412
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001413 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001414 gprs_dump_nsi(nsi);
1415
1416 printf("--- Initialise BSS 1 ---\n\n");
1417
1418 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1419 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1420 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001421 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001422
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001423 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001424 OSMO_ASSERT(peer != NULL);
1425
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001426 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1427
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001428 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1429 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001430
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001431 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001432 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001433
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001434 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1435 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1436
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001437 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1438
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001439 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1440 foreign_tlli, &rai_bss, cell_id,
1441 GPRS_SAPI_GMM, 0,
1442 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001443
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001444 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1445
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001446 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1447 foreign_tlli, 0, NULL, 0,
1448 GPRS_SAPI_GMM, 0,
1449 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001450
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001451 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1452 foreign_tlli, &rai_bss, cell_id,
1453 GPRS_SAPI_GMM, 3,
1454 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001455
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001456 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1457 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1458
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001459 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1460 foreign_tlli, 1, imsi, sizeof(imsi),
1461 GPRS_SAPI_GMM, 1,
1462 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001463
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001464 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1465
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001466 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1467 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1468 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1469
1470 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1471 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1472 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1473
1474 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1475 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1476 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1477
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001478 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001479 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001480 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1481 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1482 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1483 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1484 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1485 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1486 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1487 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001488
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001489 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1490 local_tlli, &rai_bss, cell_id,
1491 GPRS_SAPI_GMM, 4,
1492 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001493
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001494 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1495
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001496 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001497 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001498 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1499 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1500 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1501 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1502 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1503 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1504 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1505 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001506
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001507 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001508 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1509 local_tlli, &rai_bss, cell_id,
1510 GPRS_SAPI_GMM, 3,
1511 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001512
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001513 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1514
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001515 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001516 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001517 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1518 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1519 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1520 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1521 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1522 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1523 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1524 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001525
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001526 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1527 local_tlli, 1, imsi, sizeof(imsi),
1528 GPRS_SAPI_GMM, 2,
1529 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001530
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001531 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1532
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001533 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001534 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001535 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1536 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1537 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1538 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001539
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001540 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001541 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1542 local_tlli, &rai_bss, cell_id,
1543 GPRS_SAPI_GMM, 3,
1544 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001545
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001546 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1547
Jacob Erlbeck73685282014-05-23 20:48:07 +02001548 gbcfg.core_apn[0] = 0;
1549 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001550
1551 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001552 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1553 local_tlli, &rai_bss, cell_id,
1554 GPRS_SAPI_GMM, 3,
1555 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001556
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001557 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1558
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001559 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001560
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001561 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001562 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1563 local_tlli, &rai_bss, cell_id,
1564 GPRS_SAPI_GMM, 6,
1565 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001566
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001567 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1568 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1569
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001570 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1571 local_tlli, 1, imsi, sizeof(imsi),
1572 GPRS_SAPI_GMM, 5,
1573 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001574
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001575 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001576
1577 printf("--- RA update ---\n\n");
1578
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001579 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1580 foreign_tlli, &rai_bss, 0x7080,
1581 GPRS_SAPI_GMM, 5,
1582 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001583
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001584 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1585
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001586 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1587 foreign_tlli, 1, imsi, sizeof(imsi),
1588 GPRS_SAPI_GMM, 6,
1589 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001590
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001591 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1592
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001593 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001594 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1595 local_tlli, &rai_bss, cell_id,
1596 GPRS_SAPI_GMM, 3,
1597 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001598
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001599 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1600
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001601 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001602
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001603 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001604 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1605 local_tlli, &rai_bss, cell_id,
1606 GPRS_SAPI_GMM, 6,
1607 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001608
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001609 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1610
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001611 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001612 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001613
1614 printf("--- Bad cases ---\n\n");
1615
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001616 /* The RAI in the Attach Request message differs from the RAI in the
1617 * BSSGP message, only patch the latter */
1618
1619 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1620 foreign_tlli2, &rai_bss, cell_id,
1621 GPRS_SAPI_GMM, 0,
1622 dtap_attach_req2, sizeof(dtap_attach_req2));
1623
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001624 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1625
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001626 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001627 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1628 local_tlli, &rai_bss, cell_id,
1629 GPRS_SAPI_GMM, 3,
1630 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001631
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001632 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001633 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001634
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001635 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001636 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001637
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001638 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001639 gprs_ns_destroy(nsi);
1640 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001641}
1642
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001643static void test_gbproxy_ptmsi_assignment()
1644{
1645 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1646 struct sockaddr_in bss_peer[1] = {{0},};
1647 struct sockaddr_in sgsn_peer= {0};
1648 struct gprs_ra_id rai_bss =
1649 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1650 struct gprs_ra_id rai_unknown =
1651 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1652 uint16_t cell_id = 0x1234;
1653
1654 const uint32_t ptmsi = 0xefe2b700;
1655 const uint32_t local_tlli = 0xefe2b700;
1656
1657 const uint32_t foreign_tlli1 = 0x8000dead;
1658 const uint32_t foreign_tlli2 = 0x8000beef;
1659
1660 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1661 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1662
1663 struct gbproxy_tlli_info *tlli_info, *tlli_info2;
1664 struct gbproxy_peer *peer;
1665 unsigned bss_nu = 0;
1666 unsigned sgsn_nu = 0;
1667
1668 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1669
1670 bssgp_nsi = nsi;
1671 gbcfg.nsi = bssgp_nsi;
1672 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1673 gbcfg.core_mcc = 0;
1674 gbcfg.core_mnc = 0;
1675 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1676 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1677 gbcfg.patch_ptmsi = 0;
1678 gbcfg.bss_ptmsi_state = 0;
1679 gbcfg.sgsn_tlli_state = 1;
1680
1681 configure_sgsn_peer(&sgsn_peer);
1682 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1683
1684 printf("=== %s ===\n", __func__);
1685 printf("--- Initialise SGSN ---\n\n");
1686
1687 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1688
1689 printf("--- Initialise BSS 1 ---\n\n");
1690
1691 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1692 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1693
1694 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1695 OSMO_ASSERT(peer != NULL);
1696
1697 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1698
1699 gprs_dump_nsi(nsi);
1700 dump_global(stdout, 0);
1701 dump_peers(stdout, 0, 0, &gbcfg);
1702
1703 printf("--- Establish first LLC connection ---\n\n");
1704
1705 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1706 foreign_tlli1, &rai_unknown, cell_id,
1707 GPRS_SAPI_GMM, bss_nu++,
1708 dtap_attach_req, sizeof(dtap_attach_req));
1709
1710 dump_peers(stdout, 0, 0, &gbcfg);
1711
1712 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1713 foreign_tlli1, 0, NULL, 0,
1714 GPRS_SAPI_GMM, sgsn_nu++,
1715 dtap_identity_req, sizeof(dtap_identity_req));
1716
1717 dump_peers(stdout, 0, 0, &gbcfg);
1718
1719 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1720 foreign_tlli1, &rai_bss, cell_id,
1721 GPRS_SAPI_GMM, bss_nu++,
1722 dtap_identity_resp, sizeof(dtap_identity_resp));
1723
1724 dump_peers(stdout, 0, 0, &gbcfg);
1725
1726 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1727 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1728 GPRS_SAPI_GMM, sgsn_nu++,
1729 dtap_attach_acc, sizeof(dtap_attach_acc));
1730
1731 dump_peers(stdout, 0, 0, &gbcfg);
1732
1733 tlli_info = gbproxy_find_tlli(peer, foreign_tlli1);
1734 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1735 OSMO_ASSERT(tlli_info);
1736 OSMO_ASSERT(tlli_info == tlli_info2);
1737 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1738 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli1);
1739 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1740 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1741 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1742
1743 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1744 local_tlli, &rai_bss, cell_id,
1745 GPRS_SAPI_GMM, bss_nu++,
1746 dtap_attach_complete, sizeof(dtap_attach_complete));
1747
1748 dump_peers(stdout, 0, 0, &gbcfg);
1749
1750 tlli_info = gbproxy_find_tlli(peer, local_tlli);
1751 OSMO_ASSERT(tlli_info);
1752 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1753 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli1);
1754 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1755 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1756 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1757
1758
1759 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1760 local_tlli, 1, imsi1, sizeof(imsi1),
1761 GPRS_SAPI_GMM, sgsn_nu++,
1762 dtap_gmm_information, sizeof(dtap_gmm_information));
1763
1764 dump_peers(stdout, 0, 0, &gbcfg);
1765
1766 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1767 OSMO_ASSERT(tlli_info);
1768 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1769 OSMO_ASSERT(!gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
1770
1771 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1772 OSMO_ASSERT(tlli_info == tlli_info2);
1773 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1774 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1775 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1776
1777 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
1778
1779 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1780 foreign_tlli2, &rai_unknown, cell_id,
1781 GPRS_SAPI_GMM, bss_nu++,
1782 dtap_attach_req, sizeof(dtap_attach_req));
1783
1784 dump_peers(stdout, 0, 0, &gbcfg);
1785
1786 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1787 foreign_tlli2, 0, NULL, 0,
1788 GPRS_SAPI_GMM, sgsn_nu++,
1789 dtap_identity_req, sizeof(dtap_identity_req));
1790
1791 dump_peers(stdout, 0, 0, &gbcfg);
1792
1793 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1794 foreign_tlli2, &rai_bss, cell_id,
1795 GPRS_SAPI_GMM, bss_nu++,
1796 dtap_identity2_resp, sizeof(dtap_identity2_resp));
1797
1798 dump_peers(stdout, 0, 0, &gbcfg);
1799
1800 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1801 foreign_tlli2, 1, imsi2, sizeof(imsi2),
1802 GPRS_SAPI_GMM, sgsn_nu++,
1803 dtap_attach_acc, sizeof(dtap_attach_acc));
1804
1805 dump_peers(stdout, 0, 0, &gbcfg);
1806
1807 tlli_info = gbproxy_find_tlli(peer, foreign_tlli2);
1808 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
1809 OSMO_ASSERT(tlli_info);
1810 OSMO_ASSERT(tlli_info == tlli_info2);
1811 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1812 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli2);
1813 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1814 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1815 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1816
1817 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1818 local_tlli, &rai_bss, cell_id,
1819 GPRS_SAPI_GMM, bss_nu++,
1820 dtap_attach_complete, sizeof(dtap_attach_complete));
1821
1822 dump_peers(stdout, 0, 0, &gbcfg);
1823
1824 tlli_info = gbproxy_find_tlli(peer, local_tlli);
1825 OSMO_ASSERT(tlli_info);
1826 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1827 OSMO_ASSERT(tlli_info->tlli.current == foreign_tlli2);
1828 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1829 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1830 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1831
1832 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1833 local_tlli, 1, imsi2, sizeof(imsi2),
1834 GPRS_SAPI_GMM, sgsn_nu++,
1835 dtap_gmm_information, sizeof(dtap_gmm_information));
1836
1837 dump_peers(stdout, 0, 0, &gbcfg);
1838
1839 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
1840 OSMO_ASSERT(tlli_info);
1841 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck1a024422014-09-16 14:10:27 +02001842 OSMO_ASSERT(!gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001843
1844 tlli_info2 = gbproxy_find_tlli(peer, local_tlli);
Jacob Erlbeck1a024422014-09-16 14:10:27 +02001845 OSMO_ASSERT(tlli_info == tlli_info2);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001846 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1847 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1848 OSMO_ASSERT(tlli_info->tlli.ptmsi == ptmsi);
1849
1850 dump_global(stdout, 0);
1851
1852 gbprox_reset(&gbcfg);
1853 gprs_ns_destroy(nsi);
1854 nsi = NULL;
1855}
1856
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001857static void test_gbproxy_ptmsi_patching()
1858{
1859 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1860 struct sockaddr_in bss_peer[1] = {{0},};
1861 struct sockaddr_in sgsn_peer= {0};
1862 struct gprs_ra_id rai_bss =
1863 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1864 struct gprs_ra_id rai_sgsn =
1865 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001866 struct gprs_ra_id rai_wrong_mcc_sgsn =
1867 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001868 struct gprs_ra_id rai_unknown =
1869 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1870 uint16_t cell_id = 0x1234;
1871
1872 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001873 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1874 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001875 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001876 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1877 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001878 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001879 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001880
1881 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001882 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1883 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001884 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001885 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1886 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001887 const uint32_t foreign_bss_tlli = 0x8000dead;
1888
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001889
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001890 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1891 struct gbproxy_tlli_info *tlli_info;
1892 struct gbproxy_peer *peer;
1893 unsigned bss_nu = 0;
1894 unsigned sgsn_nu = 0;
1895
1896 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001897 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1898 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1899 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1900 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1901 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001902
1903 bssgp_nsi = nsi;
1904 gbcfg.nsi = bssgp_nsi;
1905 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1906 gbcfg.core_mcc = 123;
1907 gbcfg.core_mnc = 456;
1908 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1909 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1910 gbcfg.patch_ptmsi = 1;
1911 gbcfg.bss_ptmsi_state = 0;
1912 gbcfg.sgsn_tlli_state = 1;
1913
1914 configure_sgsn_peer(&sgsn_peer);
1915 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1916
1917 printf("=== %s ===\n", __func__);
1918 printf("--- Initialise SGSN ---\n\n");
1919
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001920 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001921
1922 printf("--- Initialise BSS 1 ---\n\n");
1923
1924 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1925 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1926
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001927 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001928 OSMO_ASSERT(peer != NULL);
1929
1930 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1931
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001932 gprs_dump_nsi(nsi);
1933 dump_global(stdout, 0);
1934 dump_peers(stdout, 0, 0, &gbcfg);
1935
1936 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1937
1938 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1939 foreign_bss_tlli, &rai_unknown, cell_id,
1940 GPRS_SAPI_GMM, bss_nu++,
1941 dtap_attach_req, sizeof(dtap_attach_req));
1942
1943 dump_peers(stdout, 0, 0, &gbcfg);
1944
1945 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1946 random_sgsn_tlli, 0, NULL, 0,
1947 GPRS_SAPI_GMM, sgsn_nu++,
1948 dtap_identity_req, sizeof(dtap_identity_req));
1949
1950 dump_peers(stdout, 0, 0, &gbcfg);
1951
1952 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1953 foreign_bss_tlli, &rai_bss, cell_id,
1954 GPRS_SAPI_GMM, bss_nu++,
1955 dtap_identity_resp, sizeof(dtap_identity_resp));
1956
1957 dump_peers(stdout, 0, 0, &gbcfg);
1958
1959 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1960 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1961 GPRS_SAPI_GMM, sgsn_nu++,
1962 dtap_attach_acc, sizeof(dtap_attach_acc));
1963
1964 dump_peers(stdout, 0, 0, &gbcfg);
1965
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001966 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001967 OSMO_ASSERT(tlli_info);
1968 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1969 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1970 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1971 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1972 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1973 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1974 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1975 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1976 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1977 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1978
1979 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1980 local_bss_tlli, &rai_bss, cell_id,
1981 GPRS_SAPI_GMM, bss_nu++,
1982 dtap_attach_complete, sizeof(dtap_attach_complete));
1983
1984 dump_peers(stdout, 0, 0, &gbcfg);
1985
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001986 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001987 OSMO_ASSERT(tlli_info);
1988 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1989 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1990 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1991 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1992 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1993 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1994 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1995 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1996
1997 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1998 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1999 GPRS_SAPI_GMM, sgsn_nu++,
2000 dtap_gmm_information, sizeof(dtap_gmm_information));
2001
2002 dump_peers(stdout, 0, 0, &gbcfg);
2003
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002004 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002005 OSMO_ASSERT(tlli_info);
2006 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2007 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2008 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2009 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2010
Jacob Erlbeck82add782014-09-05 18:08:12 +02002011 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2012 local_bss_tlli, &rai_bss, cell_id,
2013 GPRS_SAPI_GMM, bss_nu++,
2014 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2015
2016 dump_peers(stdout, 0, 0, &gbcfg);
2017
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002018 /* Non-DTAP */
2019 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2020 local_bss_tlli, &rai_bss, cell_id,
2021 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2022
2023 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2024 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2025 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2026
2027 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2028 local_bss_tlli, &rai_bss, cell_id,
2029 llc_ui_ll11_dns_query_ul,
2030 sizeof(llc_ui_ll11_dns_query_ul));
2031
2032 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2033 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2034 llc_ui_ll11_dns_resp_dl,
2035 sizeof(llc_ui_ll11_dns_resp_dl));
2036
2037 dump_peers(stdout, 0, 0, &gbcfg);
2038
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002039 /* Repeated RA Update Requests */
2040 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2041 local_bss_tlli, &rai_bss, 0x7080,
2042 GPRS_SAPI_GMM, bss_nu++,
2043 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2044
2045 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2046 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2047 GPRS_SAPI_GMM, sgsn_nu++,
2048 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2049
2050 dump_peers(stdout, 0, 0, &gbcfg);
2051
2052 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
2053 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2054 OSMO_ASSERT(tlli_info);
2055 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2056 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2057 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2058 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2059 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2060 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2061 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2062 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2063 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2064 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2065
2066 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2067 local_bss_tlli2, &rai_bss, 0x7080,
2068 GPRS_SAPI_GMM, bss_nu++,
2069 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2070
2071 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2072 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2073 GPRS_SAPI_GMM, sgsn_nu++,
2074 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2075
2076 dump_peers(stdout, 0, 0, &gbcfg);
2077
2078 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
2079 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
2080 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2081 OSMO_ASSERT(tlli_info);
2082 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
2083 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2084 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2085 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2086 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
2087 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2088 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2089 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2090 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2091 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
2092
2093 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2094 local_bss_tlli3, &rai_bss, 0x7080,
2095 GPRS_SAPI_GMM, bss_nu++,
2096 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2097
2098 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
2099
2100 OSMO_ASSERT(tlli_info);
2101 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2102 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2103 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2104 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2105
2106 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2107 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2108 GPRS_SAPI_GMM, sgsn_nu++,
2109 dtap_gmm_information, sizeof(dtap_gmm_information));
2110
2111 dump_peers(stdout, 0, 0, &gbcfg);
2112
2113 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
2114 OSMO_ASSERT(tlli_info);
2115 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
2116 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2117 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
2118 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2119
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002120 /* Other messages */
2121 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002122 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002123
2124 dump_peers(stdout, 0, 0, &gbcfg);
2125
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002126 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
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_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002131
2132 dump_peers(stdout, 0, 0, &gbcfg);
2133
2134 /* Bad case: Invalid BVCI */
2135 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002136 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002137 dump_global(stdout, 0);
2138
2139 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002140 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002141
2142 dump_global(stdout, 0);
2143
2144 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002145 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002146 &rai_wrong_mcc_sgsn);
2147
2148 dump_global(stdout, 0);
2149
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002150 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2151 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2152 unknown_sgsn_tlli, 1, NULL, 0,
2153 GPRS_SAPI_GMM, 2,
2154 dtap_gmm_information, sizeof(dtap_gmm_information));
2155
2156 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2157 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2158 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2159 GPRS_SAPI_GMM, 3,
2160 dtap_gmm_information, sizeof(dtap_gmm_information));
2161
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002162 /* Detach */
2163 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002164 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002165 GPRS_SAPI_GMM, bss_nu++,
2166 dtap_detach_req, sizeof(dtap_detach_req));
2167
2168 dump_peers(stdout, 0, 0, &gbcfg);
2169
2170 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002171 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002172 GPRS_SAPI_GMM, sgsn_nu++,
2173 dtap_detach_acc, sizeof(dtap_detach_acc));
2174
2175 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002176
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002177 dump_global(stdout, 0);
2178
2179 gbprox_reset(&gbcfg);
2180 gprs_ns_destroy(nsi);
2181 nsi = NULL;
2182}
2183
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002184static void test_gbproxy_imsi_acquisition()
2185{
2186 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2187 struct sockaddr_in bss_peer[1] = {{0},};
2188 struct sockaddr_in sgsn_peer= {0};
2189 struct gprs_ra_id rai_bss =
2190 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2191 struct gprs_ra_id rai_sgsn =
2192 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2193 struct gprs_ra_id rai_wrong_mcc_sgsn =
2194 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2195 struct gprs_ra_id rai_unknown =
2196 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2197 uint16_t cell_id = 0x1234;
2198
2199 const uint32_t sgsn_ptmsi = 0xefe2b700;
2200 const uint32_t local_sgsn_tlli = 0xefe2b700;
2201 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2202
2203 const uint32_t bss_ptmsi = 0xc00f7304;
2204 const uint32_t local_bss_tlli = 0xc00f7304;
2205 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002206 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002207
2208 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2209 struct gbproxy_tlli_info *tlli_info;
2210 struct gbproxy_peer *peer;
2211 unsigned bss_nu = 0;
2212 unsigned sgsn_nu = 0;
2213
2214 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2215
2216 bssgp_nsi = nsi;
2217 gbcfg.nsi = bssgp_nsi;
2218 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2219 gbcfg.core_mcc = 123;
2220 gbcfg.core_mnc = 456;
2221 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2222 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2223 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002224 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002225 gbcfg.bss_ptmsi_state = 0;
2226 gbcfg.sgsn_tlli_state = 1;
2227
2228 configure_sgsn_peer(&sgsn_peer);
2229 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2230
2231 printf("=== %s ===\n", __func__);
2232 printf("--- Initialise SGSN ---\n\n");
2233
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002234 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002235
2236 printf("--- Initialise BSS 1 ---\n\n");
2237
2238 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2239 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2240
2241 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2242 OSMO_ASSERT(peer != NULL);
2243
2244 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2245
2246 gprs_dump_nsi(nsi);
2247 dump_global(stdout, 0);
2248 dump_peers(stdout, 0, 0, &gbcfg);
2249
2250 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2251
2252 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002253 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002254 GPRS_SAPI_GMM, bss_nu++,
2255 dtap_attach_req, sizeof(dtap_attach_req));
2256
2257 dump_peers(stdout, 0, 0, &gbcfg);
2258
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002259 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2260 foreign_bss_tlli, &rai_bss, cell_id,
2261 GPRS_SAPI_GMM, bss_nu++,
2262 dtap_identity_resp, sizeof(dtap_identity_resp));
2263
2264 dump_peers(stdout, 0, 0, &gbcfg);
2265
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002266 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2267 random_sgsn_tlli, 0, NULL, 0,
2268 GPRS_SAPI_GMM, sgsn_nu++,
2269 dtap_identity_req, sizeof(dtap_identity_req));
2270
2271 dump_peers(stdout, 0, 0, &gbcfg);
2272
2273 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2274 foreign_bss_tlli, &rai_bss, cell_id,
2275 GPRS_SAPI_GMM, bss_nu++,
2276 dtap_identity_resp, sizeof(dtap_identity_resp));
2277
2278 dump_peers(stdout, 0, 0, &gbcfg);
2279
2280 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2281 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_attach_acc, sizeof(dtap_attach_acc));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
2287 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2288 OSMO_ASSERT(tlli_info);
2289 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2290 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2291 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2292 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2293 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2294 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2295 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2296 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2297 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2298 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2299
2300 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2301 local_bss_tlli, &rai_bss, cell_id,
2302 GPRS_SAPI_GMM, bss_nu++,
2303 dtap_attach_complete, sizeof(dtap_attach_complete));
2304
2305 dump_peers(stdout, 0, 0, &gbcfg);
2306
2307 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2308 OSMO_ASSERT(tlli_info);
2309 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2310 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2311 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2312 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2313 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2314 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2315 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2316 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2317
2318 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2319 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2320 GPRS_SAPI_GMM, sgsn_nu++,
2321 dtap_gmm_information, sizeof(dtap_gmm_information));
2322
2323 dump_peers(stdout, 0, 0, &gbcfg);
2324
2325 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2326 OSMO_ASSERT(tlli_info);
2327 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2328 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2329 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2330 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2331
2332 /* Non-DTAP */
2333 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2334 local_bss_tlli, &rai_bss, cell_id,
2335 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2336
2337 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2338 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2339 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2340
2341 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2342 local_bss_tlli, &rai_bss, cell_id,
2343 llc_ui_ll11_dns_query_ul,
2344 sizeof(llc_ui_ll11_dns_query_ul));
2345
2346 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2347 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2348 llc_ui_ll11_dns_resp_dl,
2349 sizeof(llc_ui_ll11_dns_resp_dl));
2350
2351 dump_peers(stdout, 0, 0, &gbcfg);
2352
2353 /* Other messages */
2354 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2355 local_bss_tlli, 1, 12);
2356
2357 dump_peers(stdout, 0, 0, &gbcfg);
2358
2359 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2360 local_sgsn_tlli, 1, 12);
2361
2362 dump_peers(stdout, 0, 0, &gbcfg);
2363
2364 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2365
2366 dump_peers(stdout, 0, 0, &gbcfg);
2367
2368 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2369
2370 dump_peers(stdout, 0, 0, &gbcfg);
2371
2372 /* Bad case: Invalid BVCI */
2373 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2374 local_bss_tlli, 1, 12);
2375 dump_global(stdout, 0);
2376
2377 /* Bad case: Invalid RAI */
2378 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2379
2380 dump_global(stdout, 0);
2381
2382 /* Bad case: Invalid MCC (LAC ok) */
2383 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2384 &rai_wrong_mcc_sgsn);
2385
2386 dump_global(stdout, 0);
2387
2388 /* Detach */
2389 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2390 local_bss_tlli, &rai_bss, cell_id,
2391 GPRS_SAPI_GMM, bss_nu++,
2392 dtap_detach_req, sizeof(dtap_detach_req));
2393
2394 dump_peers(stdout, 0, 0, &gbcfg);
2395
2396 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2397 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2398 GPRS_SAPI_GMM, sgsn_nu++,
2399 dtap_detach_acc, sizeof(dtap_detach_acc));
2400
2401 dump_peers(stdout, 0, 0, &gbcfg);
2402
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002403 /* Special case: Repeated Attach Requests */
2404
2405 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2406 foreign_bss_tlli, &rai_unknown, cell_id,
2407 GPRS_SAPI_GMM, bss_nu++,
2408 dtap_attach_req, sizeof(dtap_attach_req));
2409
2410 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2411 foreign_bss_tlli, &rai_unknown, cell_id,
2412 GPRS_SAPI_GMM, bss_nu++,
2413 dtap_attach_req, sizeof(dtap_attach_req));
2414
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002415 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2416 foreign_bss_tlli, &rai_bss, cell_id,
2417 GPRS_SAPI_GMM, bss_nu++,
2418 dtap_detach_req, sizeof(dtap_detach_req));
2419
2420 dump_peers(stdout, 0, 0, &gbcfg);
2421
2422 /* Special case: Detach from an unknown TLLI */
2423
2424 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2425 other_bss_tlli, &rai_bss, cell_id,
2426 GPRS_SAPI_GMM, bss_nu++,
2427 dtap_detach_req, sizeof(dtap_detach_req));
2428
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002429 dump_peers(stdout, 0, 0, &gbcfg);
2430
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002431 dump_global(stdout, 0);
2432
2433 gbprox_reset(&gbcfg);
2434 gprs_ns_destroy(nsi);
2435 nsi = NULL;
2436}
2437
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002438static void test_gbproxy_secondary_sgsn()
2439{
2440 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2441 struct sockaddr_in bss_peer[1] = {{0},};
2442 struct sockaddr_in sgsn_peer[2]= {{0},};
2443 struct gprs_ra_id rai_bss =
2444 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2445 struct gprs_ra_id rai_sgsn =
2446 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2447 struct gprs_ra_id rai_unknown =
2448 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2449 uint16_t cell_id = 0x1234;
2450
2451 const uint32_t sgsn_ptmsi = 0xefe2b700;
2452 const uint32_t local_sgsn_tlli = 0xefe2b700;
2453 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2454
2455 const uint32_t bss_ptmsi = 0xc00f7304;
2456 const uint32_t local_bss_tlli = 0xc00f7304;
2457 const uint32_t foreign_bss_tlli = 0x8000dead;
2458
2459 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2460 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2461 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2462 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2463 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2464 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2465
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002466 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
2467 const uint32_t local_bss_tlli3 = 0xead4775a;
2468 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2469
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002470 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2471 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002472 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002473 struct gbproxy_tlli_info *tlli_info;
2474 struct gbproxy_peer *peer;
2475 unsigned bss_nu = 0;
2476 unsigned sgsn_nu = 0;
2477
2478 const char *err_msg = NULL;
2479 const char *filter_re = "999999";
2480
2481 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2482 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2483
2484 bssgp_nsi = nsi;
2485 gbcfg.nsi = bssgp_nsi;
2486 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2487 gbcfg.core_mcc = 123;
2488 gbcfg.core_mnc = 456;
2489 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2490 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2491 gbcfg.patch_ptmsi = 1;
2492 gbcfg.acquire_imsi = 1;
2493 gbcfg.bss_ptmsi_state = 0;
2494 gbcfg.sgsn_tlli_state = 1;
2495 gbcfg.route_to_sgsn2 = 1;
2496 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2497
2498 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2499 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2500 err_msg);
2501 OSMO_ASSERT(err_msg == NULL);
2502 }
2503
2504 configure_sgsn_peer(&sgsn_peer[0]);
2505 configure_sgsn2_peer(&sgsn_peer[1]);
2506 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2507
2508 printf("=== %s ===\n", __func__);
2509 printf("--- Initialise SGSN 1 ---\n\n");
2510
2511 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2512
2513 printf("--- Initialise SGSN 2 ---\n\n");
2514
2515 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2516
2517 printf("--- Initialise BSS 1 ---\n\n");
2518
2519 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2520 setup_bssgp(nsi, &bss_peer[0], 0x0);
2521 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2522 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2523 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2524 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2525
2526 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2527 OSMO_ASSERT(peer != NULL);
2528
2529 gprs_dump_nsi(nsi);
2530 dump_global(stdout, 0);
2531 dump_peers(stdout, 0, 0, &gbcfg);
2532
2533 printf("--- Flow control ---\n\n");
2534
2535 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2536 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2537 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2538
2539 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2540
2541 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2542 foreign_bss_tlli, &rai_unknown, cell_id,
2543 GPRS_SAPI_GMM, bss_nu++,
2544 dtap_attach_req, sizeof(dtap_attach_req));
2545
2546 dump_peers(stdout, 0, 0, &gbcfg);
2547
2548 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2549 foreign_bss_tlli, &rai_bss, cell_id,
2550 GPRS_SAPI_GMM, bss_nu++,
2551 dtap_identity_resp, sizeof(dtap_identity_resp));
2552
2553 dump_peers(stdout, 0, 0, &gbcfg);
2554
2555 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2556 random_sgsn_tlli, 0, NULL, 0,
2557 GPRS_SAPI_GMM, sgsn_nu++,
2558 dtap_identity_req, sizeof(dtap_identity_req));
2559
2560 dump_peers(stdout, 0, 0, &gbcfg);
2561
2562 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2563 foreign_bss_tlli, &rai_bss, cell_id,
2564 GPRS_SAPI_GMM, bss_nu++,
2565 dtap_identity_resp, sizeof(dtap_identity_resp));
2566
2567 dump_peers(stdout, 0, 0, &gbcfg);
2568
2569 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2570 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2571 GPRS_SAPI_GMM, sgsn_nu++,
2572 dtap_attach_acc, sizeof(dtap_attach_acc));
2573
2574 dump_peers(stdout, 0, 0, &gbcfg);
2575
2576 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2577 OSMO_ASSERT(tlli_info);
2578 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2579 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2580 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2581 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2582 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2583 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2584 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2585 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2586 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2587 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2588
2589 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2590 local_bss_tlli, &rai_bss, cell_id,
2591 GPRS_SAPI_GMM, bss_nu++,
2592 dtap_attach_complete, sizeof(dtap_attach_complete));
2593
2594 dump_peers(stdout, 0, 0, &gbcfg);
2595
2596 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2597 OSMO_ASSERT(tlli_info);
2598 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2599 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2600 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2601 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2602 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2603 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2604 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2605 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2606
2607 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2608 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2609 GPRS_SAPI_GMM, sgsn_nu++,
2610 dtap_gmm_information, sizeof(dtap_gmm_information));
2611
2612 dump_peers(stdout, 0, 0, &gbcfg);
2613
2614 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2615 OSMO_ASSERT(tlli_info);
2616 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2617 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2618 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2619 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2620
2621 /* Non-DTAP */
2622 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2623 local_bss_tlli, &rai_bss, cell_id,
2624 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2625
2626 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2627 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2628 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2629
2630 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2631 local_bss_tlli, &rai_bss, cell_id,
2632 llc_ui_ll11_dns_query_ul,
2633 sizeof(llc_ui_ll11_dns_query_ul));
2634
2635 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2636 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2637 llc_ui_ll11_dns_resp_dl,
2638 sizeof(llc_ui_ll11_dns_resp_dl));
2639
2640 dump_peers(stdout, 0, 0, &gbcfg);
2641
2642 /* Other messages */
2643 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2644 local_bss_tlli, 1, 12);
2645
2646 dump_peers(stdout, 0, 0, &gbcfg);
2647
2648 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2649 local_sgsn_tlli, 1, 12);
2650
2651 dump_peers(stdout, 0, 0, &gbcfg);
2652
2653 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2654
2655 dump_peers(stdout, 0, 0, &gbcfg);
2656
2657 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2658
2659 dump_peers(stdout, 0, 0, &gbcfg);
2660
2661 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2662
2663 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2664 foreign_bss_tlli2, &rai_unknown, cell_id,
2665 GPRS_SAPI_GMM, bss_nu++,
2666 dtap_attach_req, sizeof(dtap_attach_req));
2667
2668 dump_peers(stdout, 0, 0, &gbcfg);
2669
2670 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2671 foreign_bss_tlli2, &rai_bss, cell_id,
2672 GPRS_SAPI_GMM, bss_nu++,
2673 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2674
2675 dump_peers(stdout, 0, 0, &gbcfg);
2676
2677 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2678 random_sgsn_tlli2, 0, NULL, 0,
2679 GPRS_SAPI_GMM, sgsn_nu++,
2680 dtap_identity_req, sizeof(dtap_identity_req));
2681
2682 dump_peers(stdout, 0, 0, &gbcfg);
2683
2684 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2685 foreign_bss_tlli2, &rai_bss, cell_id,
2686 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002687 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002688
2689 dump_peers(stdout, 0, 0, &gbcfg);
2690
2691 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2692 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2693 GPRS_SAPI_GMM, sgsn_nu++,
2694 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2695
2696 dump_peers(stdout, 0, 0, &gbcfg);
2697
2698 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2699 OSMO_ASSERT(tlli_info);
2700 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2701 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2702 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2703 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2704 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2705 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2706 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2707 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2708 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2709 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2710
2711 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2712 local_bss_tlli2, &rai_bss, cell_id,
2713 GPRS_SAPI_GMM, bss_nu++,
2714 dtap_attach_complete, sizeof(dtap_attach_complete));
2715
2716 dump_peers(stdout, 0, 0, &gbcfg);
2717
2718 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2719 OSMO_ASSERT(tlli_info);
2720 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2721 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2722 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2723 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2724 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2725 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2726 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2727 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2728
2729 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2730 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2731 GPRS_SAPI_GMM, sgsn_nu++,
2732 dtap_gmm_information, sizeof(dtap_gmm_information));
2733
2734 dump_peers(stdout, 0, 0, &gbcfg);
2735
2736 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2737 OSMO_ASSERT(tlli_info);
2738 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2739 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2740 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2741 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2742
2743 /* Non-DTAP */
2744 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2745 local_bss_tlli2, &rai_bss, cell_id,
2746 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2747
2748 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2749 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2750 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2751
2752 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2753 local_bss_tlli2, &rai_bss, cell_id,
2754 llc_ui_ll11_dns_query_ul,
2755 sizeof(llc_ui_ll11_dns_query_ul));
2756
2757 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2758 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2759 llc_ui_ll11_dns_resp_dl,
2760 sizeof(llc_ui_ll11_dns_resp_dl));
2761
2762 dump_peers(stdout, 0, 0, &gbcfg);
2763
2764 /* Other messages */
2765 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2766 local_bss_tlli2, 1, 12);
2767
2768 dump_peers(stdout, 0, 0, &gbcfg);
2769
2770 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2771 local_sgsn_tlli2, 1, 12);
2772
2773 dump_peers(stdout, 0, 0, &gbcfg);
2774
2775 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2776
2777 dump_peers(stdout, 0, 0, &gbcfg);
2778
2779 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2780
2781 dump_peers(stdout, 0, 0, &gbcfg);
2782
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002783 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
2784
2785 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2786 foreign_bss_tlli3, &rai_unknown, cell_id,
2787 GPRS_SAPI_GMM, bss_nu++,
2788 dtap_attach_req, sizeof(dtap_attach_req));
2789
2790 dump_peers(stdout, 0, 0, &gbcfg);
2791
2792 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2793 foreign_bss_tlli3, &rai_bss, cell_id,
2794 GPRS_SAPI_GMM, bss_nu++,
2795 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2796
2797 dump_peers(stdout, 0, 0, &gbcfg);
2798
2799 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2800 random_sgsn_tlli3, 0, NULL, 0,
2801 GPRS_SAPI_GMM, sgsn_nu++,
2802 dtap_identity_req, sizeof(dtap_identity_req));
2803
2804 dump_peers(stdout, 0, 0, &gbcfg);
2805
2806 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2807 foreign_bss_tlli3, &rai_bss, cell_id,
2808 GPRS_SAPI_GMM, bss_nu++,
2809 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2810
2811 dump_peers(stdout, 0, 0, &gbcfg);
2812
2813 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
2814 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
2815 GPRS_SAPI_GMM, sgsn_nu++,
2816 dtap_attach_acc, sizeof(dtap_attach_acc));
2817
2818 dump_peers(stdout, 0, 0, &gbcfg);
2819
2820 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2821 local_bss_tlli3, &rai_bss, cell_id,
2822 GPRS_SAPI_GMM, bss_nu++,
2823 dtap_attach_complete, sizeof(dtap_attach_complete));
2824
2825 dump_peers(stdout, 0, 0, &gbcfg);
2826
2827 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2828 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2829 GPRS_SAPI_GMM, sgsn_nu++,
2830 dtap_gmm_information, sizeof(dtap_gmm_information));
2831
2832 dump_peers(stdout, 0, 0, &gbcfg);
2833
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002834 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2835
2836 /* Detach */
2837 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2838 local_bss_tlli, &rai_bss, cell_id,
2839 GPRS_SAPI_GMM, bss_nu++,
2840 dtap_detach_req, sizeof(dtap_detach_req));
2841
2842 dump_peers(stdout, 0, 0, &gbcfg);
2843
2844 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2845 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2846 GPRS_SAPI_GMM, sgsn_nu++,
2847 dtap_detach_acc, sizeof(dtap_detach_acc));
2848
2849 dump_peers(stdout, 0, 0, &gbcfg);
2850
2851 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2852
2853 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2854 local_bss_tlli2, &rai_bss, cell_id,
2855 GPRS_SAPI_GMM, bss_nu++,
2856 dtap_detach_req, sizeof(dtap_detach_req));
2857
2858 dump_peers(stdout, 0, 0, &gbcfg);
2859
2860 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2861 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2862 GPRS_SAPI_GMM, sgsn_nu++,
2863 dtap_detach_acc, sizeof(dtap_detach_acc));
2864
2865 dump_peers(stdout, 0, 0, &gbcfg);
2866
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002867 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
2868
2869 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2870 local_bss_tlli3, &rai_bss, cell_id,
2871 GPRS_SAPI_GMM, bss_nu++,
2872 dtap_detach_req, sizeof(dtap_detach_req));
2873
2874 dump_peers(stdout, 0, 0, &gbcfg);
2875
2876 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2877 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2878 GPRS_SAPI_GMM, sgsn_nu++,
2879 dtap_detach_acc, sizeof(dtap_detach_acc));
2880
2881 dump_peers(stdout, 0, 0, &gbcfg);
2882
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002883 dump_global(stdout, 0);
2884
2885 gbprox_reset(&gbcfg);
2886 gprs_ns_destroy(nsi);
2887 nsi = NULL;
2888}
2889
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002890static void test_gbproxy_keep_info()
2891{
2892 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2893 struct sockaddr_in bss_peer[1] = {{0},};
2894 struct sockaddr_in sgsn_peer= {0};
2895 struct gprs_ra_id rai_bss =
2896 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2897 uint16_t cell_id = 0x1234;
2898
2899 const uint32_t ptmsi = 0xefe2b700;
2900 const uint32_t local_tlli = 0xefe2b700;
2901 const uint32_t foreign_tlli = 0xafe2b700;
2902
2903 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002904 struct gbproxy_tlli_info *tlli_info, *tlli_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002905 struct gbproxy_peer *peer;
2906 unsigned bss_nu = 0;
2907 unsigned sgsn_nu = 0;
2908
2909 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
2910
2911 bssgp_nsi = nsi;
2912 gbcfg.nsi = bssgp_nsi;
2913 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2914 gbcfg.patch_ptmsi = 0;
2915 gbcfg.acquire_imsi = 1;
2916 gbcfg.bss_ptmsi_state = 0;
2917 gbcfg.sgsn_tlli_state = 1;
2918 gbcfg.core_mcc = 0;
2919 gbcfg.core_mnc = 0;
2920 gbcfg.core_apn = NULL;
2921 gbcfg.core_apn_size = 0;
2922 gbcfg.route_to_sgsn2 = 0;
2923 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002924 gbcfg.keep_tlli_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002925
2926 configure_sgsn_peer(&sgsn_peer);
2927 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2928
2929 printf("=== %s ===\n", __func__);
2930 printf("--- Initialise SGSN ---\n\n");
2931
2932 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2933
2934 printf("--- Initialise BSS 1 ---\n\n");
2935
2936 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2937 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2938
2939 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2940 OSMO_ASSERT(peer != NULL);
2941
2942 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2943
2944 gprs_dump_nsi(nsi);
2945 dump_global(stdout, 0);
2946 dump_peers(stdout, 0, 0, &gbcfg);
2947
2948 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2949
2950 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2951 foreign_tlli, &rai_bss, cell_id,
2952 GPRS_SAPI_GMM, bss_nu++,
2953 dtap_attach_req, sizeof(dtap_attach_req));
2954
2955 dump_peers(stdout, 0, 0, &gbcfg);
2956
2957 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2958 OSMO_ASSERT(tlli_info);
2959 OSMO_ASSERT(tlli_info->imsi_len == 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002960 OSMO_ASSERT(!tlli_info->is_deregistered);
2961 OSMO_ASSERT(tlli_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002962
2963 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2964 foreign_tlli, &rai_bss, cell_id,
2965 GPRS_SAPI_GMM, bss_nu++,
2966 dtap_identity_resp, sizeof(dtap_identity_resp));
2967
2968 dump_peers(stdout, 0, 0, &gbcfg);
2969
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002970 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2971 OSMO_ASSERT(tlli_info);
2972 OSMO_ASSERT(tlli_info->imsi_len > 0);
2973 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
2974
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002975 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2976 foreign_tlli, 0, NULL, 0,
2977 GPRS_SAPI_GMM, sgsn_nu++,
2978 dtap_identity_req, sizeof(dtap_identity_req));
2979
2980 dump_peers(stdout, 0, 0, &gbcfg);
2981
2982 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2983 foreign_tlli, &rai_bss, cell_id,
2984 GPRS_SAPI_GMM, bss_nu++,
2985 dtap_identity_resp, sizeof(dtap_identity_resp));
2986
2987 dump_peers(stdout, 0, 0, &gbcfg);
2988
2989 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2990 OSMO_ASSERT(tlli_info);
2991 OSMO_ASSERT(tlli_info->imsi_len > 0);
2992 OSMO_ASSERT(gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi)));
2993
2994 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2995 foreign_tlli, 1, imsi, sizeof(imsi),
2996 GPRS_SAPI_GMM, sgsn_nu++,
2997 dtap_attach_acc, sizeof(dtap_attach_acc));
2998
2999 dump_peers(stdout, 0, 0, &gbcfg);
3000
3001 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3002 local_tlli, &rai_bss, cell_id,
3003 GPRS_SAPI_GMM, bss_nu++,
3004 dtap_attach_complete, sizeof(dtap_attach_complete));
3005
3006 dump_peers(stdout, 0, 0, &gbcfg);
3007
3008 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3009 local_tlli, 1, imsi, sizeof(imsi),
3010 GPRS_SAPI_GMM, sgsn_nu++,
3011 dtap_gmm_information, sizeof(dtap_gmm_information));
3012
3013 dump_peers(stdout, 0, 0, &gbcfg);
3014
3015 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3016 OSMO_ASSERT(tlli_info);
3017
3018 /* Detach (MO) */
3019 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3020 local_tlli, &rai_bss, cell_id,
3021 GPRS_SAPI_GMM, bss_nu++,
3022 dtap_detach_req, sizeof(dtap_detach_req));
3023
3024 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3025 OSMO_ASSERT(tlli_info);
3026
3027 dump_peers(stdout, 0, 0, &gbcfg);
3028
3029 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3030 local_tlli, 1, imsi, sizeof(imsi),
3031 GPRS_SAPI_GMM, sgsn_nu++,
3032 dtap_detach_acc, sizeof(dtap_detach_acc));
3033
3034 dump_peers(stdout, 0, 0, &gbcfg);
3035
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003036 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3037 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3038 OSMO_ASSERT(tlli_info);
3039 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003040
3041 /* Re-Attach */
3042 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3043 foreign_tlli, &rai_bss, cell_id,
3044 GPRS_SAPI_GMM, bss_nu++,
3045 dtap_attach_req3, sizeof(dtap_attach_req3));
3046
3047 dump_peers(stdout, 0, 0, &gbcfg);
3048
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003049 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3050 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3051 OSMO_ASSERT(tlli_info);
3052 OSMO_ASSERT(tlli_info == tlli_info2);
3053 OSMO_ASSERT(tlli_info->imsi_len != 0);
3054 OSMO_ASSERT(!tlli_info->is_deregistered);
3055 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3056
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003057 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3058 foreign_tlli, 1, imsi, sizeof(imsi),
3059 GPRS_SAPI_GMM, sgsn_nu++,
3060 dtap_attach_acc, sizeof(dtap_attach_acc));
3061
3062 dump_peers(stdout, 0, 0, &gbcfg);
3063
3064 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3065 local_tlli, &rai_bss, cell_id,
3066 GPRS_SAPI_GMM, bss_nu++,
3067 dtap_attach_complete, sizeof(dtap_attach_complete));
3068
3069 dump_peers(stdout, 0, 0, &gbcfg);
3070
3071 /* Detach (MT) */
3072 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3073 local_tlli, 1, imsi, sizeof(imsi),
3074 GPRS_SAPI_GMM, sgsn_nu++,
3075 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3076
3077 dump_peers(stdout, 0, 0, &gbcfg);
3078
3079 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3080 OSMO_ASSERT(tlli_info);
3081
3082 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3083 local_tlli, &rai_bss, cell_id,
3084 GPRS_SAPI_GMM, bss_nu++,
3085 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3086
3087 dump_peers(stdout, 0, 0, &gbcfg);
3088
3089 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003090 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3091 OSMO_ASSERT(tlli_info);
3092 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003093
3094 /* Re-Attach */
3095 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3096 foreign_tlli, &rai_bss, cell_id,
3097 GPRS_SAPI_GMM, bss_nu++,
3098 dtap_attach_req3, sizeof(dtap_attach_req3));
3099
3100 dump_peers(stdout, 0, 0, &gbcfg);
3101
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003102 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3103 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3104 OSMO_ASSERT(tlli_info);
3105 OSMO_ASSERT(tlli_info == tlli_info2);
3106 OSMO_ASSERT(tlli_info->imsi_len != 0);
3107 OSMO_ASSERT(!tlli_info->is_deregistered);
3108 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3109
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003110 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3111 foreign_tlli, 1, imsi, sizeof(imsi),
3112 GPRS_SAPI_GMM, sgsn_nu++,
3113 dtap_attach_acc, sizeof(dtap_attach_acc));
3114
3115 dump_peers(stdout, 0, 0, &gbcfg);
3116
3117 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3118 local_tlli, &rai_bss, cell_id,
3119 GPRS_SAPI_GMM, bss_nu++,
3120 dtap_attach_complete, sizeof(dtap_attach_complete));
3121
3122 dump_peers(stdout, 0, 0, &gbcfg);
3123
3124 /* Detach (MT) */
3125 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3126 local_tlli, 1, imsi, sizeof(imsi),
3127 GPRS_SAPI_GMM, sgsn_nu++,
3128 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3129
3130 dump_peers(stdout, 0, 0, &gbcfg);
3131
3132 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3133 OSMO_ASSERT(tlli_info);
3134
3135 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3136 local_tlli, &rai_bss, cell_id,
3137 GPRS_SAPI_GMM, bss_nu++,
3138 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3139
3140 dump_peers(stdout, 0, 0, &gbcfg);
3141
3142 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003143 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3144 OSMO_ASSERT(tlli_info);
3145 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003146
3147 /* Re-Attach */
3148 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3149 foreign_tlli, &rai_bss, cell_id,
3150 GPRS_SAPI_GMM, bss_nu++,
3151 dtap_attach_req3, sizeof(dtap_attach_req3));
3152
3153 dump_peers(stdout, 0, 0, &gbcfg);
3154
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003155 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3156 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3157 OSMO_ASSERT(tlli_info);
3158 OSMO_ASSERT(tlli_info == tlli_info2);
3159 OSMO_ASSERT(tlli_info->imsi_len != 0);
3160 OSMO_ASSERT(!tlli_info->is_deregistered);
3161 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
3162
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003163 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3164 foreign_tlli, 1, imsi, sizeof(imsi),
3165 GPRS_SAPI_GMM, sgsn_nu++,
3166 dtap_attach_acc, sizeof(dtap_attach_acc));
3167
3168 dump_peers(stdout, 0, 0, &gbcfg);
3169
3170 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3171 local_tlli, &rai_bss, cell_id,
3172 GPRS_SAPI_GMM, bss_nu++,
3173 dtap_attach_complete, sizeof(dtap_attach_complete));
3174
3175 dump_peers(stdout, 0, 0, &gbcfg);
3176
3177 /* RA update procedure (reject -> Detach) */
3178 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3179 local_tlli, &rai_bss, 0x7080,
3180 GPRS_SAPI_GMM, bss_nu++,
3181 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3182
3183 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3184 local_tlli, 1, imsi, sizeof(imsi),
3185 GPRS_SAPI_GMM, sgsn_nu++,
3186 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3187
3188 dump_peers(stdout, 0, 0, &gbcfg);
3189
Jacob Erlbeck85e5c8f2014-09-16 12:16:58 +02003190 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3191 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3192 OSMO_ASSERT(tlli_info);
3193 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003194
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003195 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3196 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3197 foreign_tlli, &rai_bss, cell_id,
3198 GPRS_SAPI_GMM, bss_nu++,
3199 dtap_attach_req, sizeof(dtap_attach_req));
3200
3201 dump_peers(stdout, 0, 0, &gbcfg);
3202
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003203 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3204 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3205 OSMO_ASSERT(tlli_info);
3206 OSMO_ASSERT(tlli_info != tlli_info2);
3207 OSMO_ASSERT(tlli_info->imsi_len == 0);
3208 OSMO_ASSERT(!tlli_info->is_deregistered);
3209 OSMO_ASSERT(tlli_info->imsi_acq_pending);
3210
3211 /* This wouldn't happen in reality, since the Attach Request hadn't
3212 * been forwarded to the SGSN.
3213 * TODO: Add the missing messages.
3214 */
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003215 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3216 foreign_tlli, 1, imsi, sizeof(imsi),
3217 GPRS_SAPI_GMM, sgsn_nu++,
3218 dtap_attach_acc, sizeof(dtap_attach_acc));
3219
3220 dump_peers(stdout, 0, 0, &gbcfg);
3221
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003222 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3223 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
3224 OSMO_ASSERT(tlli_info);
3225 OSMO_ASSERT(tlli_info == tlli_info2);
3226 OSMO_ASSERT(tlli_info->imsi_len >= 0);
3227 OSMO_ASSERT(!tlli_info->is_deregistered);
3228 OSMO_ASSERT(tlli_info->imsi_acq_pending);
3229
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003230 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3231 local_tlli, &rai_bss, cell_id,
3232 GPRS_SAPI_GMM, bss_nu++,
3233 dtap_attach_complete, sizeof(dtap_attach_complete));
3234
3235 dump_peers(stdout, 0, 0, &gbcfg);
3236
3237 /* Detach (MT) */
3238 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3239 local_tlli, 1, imsi, sizeof(imsi),
3240 GPRS_SAPI_GMM, sgsn_nu++,
3241 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3242
3243 dump_peers(stdout, 0, 0, &gbcfg);
3244
3245 tlli_info = gbproxy_find_tlli(peer, local_tlli);
3246 OSMO_ASSERT(tlli_info);
3247
3248 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3249 local_tlli, &rai_bss, cell_id,
3250 GPRS_SAPI_GMM, bss_nu++,
3251 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3252
3253 dump_peers(stdout, 0, 0, &gbcfg);
3254
Jacob Erlbeck16a3cd32014-09-15 11:46:42 +02003255 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
3256 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
3257 OSMO_ASSERT(tlli_info);
3258 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003259
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003260 dump_global(stdout, 0);
3261
3262 gbprox_reset(&gbcfg);
3263 gprs_ns_destroy(nsi);
3264 nsi = NULL;
3265}
3266
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003267/* TODO: Move tlv testing to libosmocore */
3268int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3269int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3270 uint8_t **value);
3271int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3272 size_t *value_len);
3273int lv_shift(uint8_t **data, size_t *data_len,
3274 uint8_t **value, size_t *value_len);
3275
3276static void check_tlv_match(uint8_t **data, size_t *data_len,
3277 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3278{
3279 uint8_t *value;
3280 size_t value_len;
3281 int rc;
3282
3283 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3284 OSMO_ASSERT(rc == 0);
3285
3286 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003287 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003288 OSMO_ASSERT(value_len == exp_len);
3289 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3290}
3291
3292static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3293 uint8_t tag, size_t len, const uint8_t *exp_val)
3294{
3295 uint8_t *value;
3296 int rc;
3297
3298 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3299 OSMO_ASSERT(rc == 0);
3300
3301 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003302 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003303 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3304}
3305
3306static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3307 size_t len, const uint8_t *exp_val)
3308{
3309 uint8_t *value;
3310 int rc;
3311
3312 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003313 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003314 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3315}
3316
3317static void check_lv_shift(uint8_t **data, size_t *data_len,
3318 size_t exp_len, const uint8_t *exp_val)
3319{
3320 uint8_t *value;
3321 size_t value_len;
3322 int rc;
3323
3324 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003325 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003326 OSMO_ASSERT(value_len == exp_len);
3327 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3328}
3329
3330static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3331 const uint8_t *test_data)
3332{
3333 uint8_t buf[300] = {0};
3334
3335 uint8_t *unchanged_ptr = buf - 1;
3336 size_t unchanged_len = 0xdead;
3337 size_t tmp_data_len = data_len;
3338 uint8_t *value = unchanged_ptr;
3339 size_t value_len = unchanged_len;
3340 uint8_t *data = buf;
3341
3342 OSMO_ASSERT(data_len <= sizeof(buf));
3343
3344 tlv_put(data, tag, len, test_data);
3345 if (data_len < len + 2) {
3346 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3347 tag, &value, &value_len));
3348 OSMO_ASSERT(tmp_data_len == 0);
3349 OSMO_ASSERT(data == buf + data_len);
3350 OSMO_ASSERT(value == unchanged_ptr);
3351 OSMO_ASSERT(value_len == unchanged_len);
3352 } else {
3353 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3354 tag, &value, &value_len));
3355 OSMO_ASSERT(value != unchanged_ptr);
3356 OSMO_ASSERT(value_len != unchanged_len);
3357 }
3358}
3359
3360static void check_tv_fixed_match_data_len(size_t data_len,
3361 uint8_t tag, size_t len,
3362 const uint8_t *test_data)
3363{
3364 uint8_t buf[300] = {0};
3365
3366 uint8_t *unchanged_ptr = buf - 1;
3367 size_t tmp_data_len = data_len;
3368 uint8_t *value = unchanged_ptr;
3369 uint8_t *data = buf;
3370
3371 OSMO_ASSERT(data_len <= sizeof(buf));
3372
3373 tv_fixed_put(data, tag, len, test_data);
3374
3375 if (data_len < len + 1) {
3376 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3377 tag, len, &value));
3378 OSMO_ASSERT(tmp_data_len == 0);
3379 OSMO_ASSERT(data == buf + data_len);
3380 OSMO_ASSERT(value == unchanged_ptr);
3381 } else {
3382 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3383 tag, len, &value));
3384 OSMO_ASSERT(value != unchanged_ptr);
3385 }
3386}
3387
3388static void check_v_fixed_shift_data_len(size_t data_len,
3389 size_t len, const uint8_t *test_data)
3390{
3391 uint8_t buf[300] = {0};
3392
3393 uint8_t *unchanged_ptr = buf - 1;
3394 size_t tmp_data_len = data_len;
3395 uint8_t *value = unchanged_ptr;
3396 uint8_t *data = buf;
3397
3398 OSMO_ASSERT(data_len <= sizeof(buf));
3399
3400 memcpy(data, test_data, len);
3401
3402 if (data_len < len) {
3403 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3404 len, &value));
3405 OSMO_ASSERT(tmp_data_len == 0);
3406 OSMO_ASSERT(data == buf + data_len);
3407 OSMO_ASSERT(value == unchanged_ptr);
3408 } else {
3409 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3410 len, &value));
3411 OSMO_ASSERT(value != unchanged_ptr);
3412 }
3413}
3414
3415static void check_lv_shift_data_len(size_t data_len,
3416 size_t len, const uint8_t *test_data)
3417{
3418 uint8_t buf[300] = {0};
3419
3420 uint8_t *unchanged_ptr = buf - 1;
3421 size_t unchanged_len = 0xdead;
3422 size_t tmp_data_len = data_len;
3423 uint8_t *value = unchanged_ptr;
3424 size_t value_len = unchanged_len;
3425 uint8_t *data = buf;
3426
3427 lv_put(data, len, test_data);
3428 if (data_len < len + 1) {
3429 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3430 &value, &value_len));
3431 OSMO_ASSERT(tmp_data_len == 0);
3432 OSMO_ASSERT(data == buf + data_len);
3433 OSMO_ASSERT(value == unchanged_ptr);
3434 OSMO_ASSERT(value_len == unchanged_len);
3435 } else {
3436 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3437 &value, &value_len));
3438 OSMO_ASSERT(value != unchanged_ptr);
3439 OSMO_ASSERT(value_len != unchanged_len);
3440 }
3441}
3442
3443static void test_tlv_shift_functions()
3444{
3445 uint8_t test_data[1024];
3446 uint8_t buf[1024];
3447 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003448 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003449 uint8_t *data;
3450 size_t data_len;
3451 const uint8_t tag = 0x1a;
3452
3453 printf("Test shift functions\n");
3454
3455 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3456 test_data[i] = (uint8_t)i;
3457
3458 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003459 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003460
3461 memset(buf, 0xee, sizeof(buf));
3462 data_end = data = buf;
3463
3464 for (i = 0; i < iterations; i++) {
3465 data_end = tlv_put(data_end, tag, len, test_data);
3466 data_end = tv_fixed_put(data_end, tag, len, test_data);
3467 /* v_fixed_put */
3468 memcpy(data_end, test_data, len);
3469 data_end += len;
3470 data_end = lv_put(data_end, len, test_data);
3471 }
3472
3473 data_len = data_end - data;
3474 OSMO_ASSERT(data_len <= sizeof(buf));
3475
3476 for (i = 0; i < iterations; i++) {
3477 check_tlv_match(&data, &data_len, tag, len, test_data);
3478 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3479 check_v_fixed_shift(&data, &data_len, len, test_data);
3480 check_lv_shift(&data, &data_len, len, test_data);
3481 }
3482
3483 OSMO_ASSERT(data == data_end);
3484
3485 /* Test at end of data */
3486
3487 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3488 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3489 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3490 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3491
3492 /* Test invalid data_len */
3493 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3494 check_tlv_match_data_len(data_len, tag, len, test_data);
3495 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3496 check_v_fixed_shift_data_len(data_len, len, test_data);
3497 check_lv_shift_data_len(data_len, len, test_data);
3498 }
3499 }
3500}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003501
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003502struct gbproxy_tlli_info *register_tlli(
3503 struct gbproxy_peer *peer, uint32_t tlli,
3504 const uint8_t *imsi, size_t imsi_len, time_t now)
3505{
3506 struct gbproxy_tlli_info *tlli_info;
3507 int enable_patching = -1;
3508 int tlli_already_known = 0;
3509
3510 /* Check, whether the IMSI matches */
3511 if (gprs_is_mi_imsi(imsi, imsi_len)) {
3512 enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
3513 if (enable_patching < 0)
3514 return NULL;
3515 }
3516
3517 tlli_info = gbproxy_find_tlli(peer, tlli);
3518
3519 if (!tlli_info) {
3520 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, imsi_len);
3521
3522 if (tlli_info) {
3523 /* TLLI has changed somehow, adjust it */
3524 LOGP(DGPRS, LOGL_INFO,
3525 "The TLLI has changed from %08x to %08x\n",
3526 tlli_info->tlli.current, tlli);
3527 tlli_info->tlli.current = tlli;
3528 }
3529 }
3530
3531 if (!tlli_info) {
3532 tlli_info = gbproxy_tlli_info_alloc(peer);
3533 tlli_info->tlli.current = tlli;
3534 } else {
3535 gbproxy_detach_tlli_info(peer, tlli_info);
3536 tlli_already_known = 1;
3537 }
3538
3539 OSMO_ASSERT(tlli_info != NULL);
3540
3541 if (!tlli_already_known)
3542 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3543
3544 gbproxy_attach_tlli_info(peer, now, tlli_info);
3545 gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
3546
3547 if (enable_patching >= 0)
3548 tlli_info->enable_patching = enable_patching;
3549
3550 return tlli_info;
3551}
3552
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003553static void test_gbproxy_tlli_expire(void)
3554{
3555 struct gbproxy_config cfg = {0};
3556 struct gbproxy_peer *peer;
3557 const char *err_msg = NULL;
3558 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3559 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003560 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003561 const uint32_t tlli1 = 1234 | 0xc0000000;
3562 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003563 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003564 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003565 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003566
3567 printf("Test TLLI info expiry\n\n");
3568
3569 gbproxy_init_config(&cfg);
3570
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003571 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003572 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3573 err_msg);
3574 OSMO_ASSERT(err_msg == NULL);
3575 }
3576
3577 {
3578 struct gbproxy_tlli_info *tlli_info;
3579
3580 printf("Test TLLI replacement:\n");
3581
3582 cfg.tlli_max_len = 0;
3583 cfg.tlli_max_age = 0;
3584 peer = gbproxy_peer_alloc(&cfg, 20);
3585 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3586
3587 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003588 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003589 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003590 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003591 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003592 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3593
3594 /* replace the old entry */
3595 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003596 tlli_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003597 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003598 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003599 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003600 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3601
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003602 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003603
3604 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003605 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003606 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003607 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003608 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003609 OSMO_ASSERT(!tlli_info);
3610
3611 printf("\n");
3612
3613 gbproxy_peer_free(peer);
3614 }
3615
3616 {
3617 struct gbproxy_tlli_info *tlli_info;
3618
3619 printf("Test IMSI replacement:\n");
3620
3621 cfg.tlli_max_len = 0;
3622 cfg.tlli_max_age = 0;
3623 peer = gbproxy_peer_alloc(&cfg, 20);
3624 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3625
3626 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003627 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003628 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003629 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003630 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003631 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3632
3633 /* try to replace the old entry */
3634 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003635 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003636 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003637 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003638 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003639 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3640
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003641 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003642
3643 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003644 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003645 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003646 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003647 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003648 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003649
3650 printf("\n");
3651
3652 gbproxy_peer_free(peer);
3653 }
3654
3655 {
3656 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003657 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003658
3659 printf("Test TLLI expiry, max_len == 1:\n");
3660
3661 cfg.tlli_max_len = 1;
3662 cfg.tlli_max_age = 0;
3663 peer = gbproxy_peer_alloc(&cfg, 20);
3664 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3665
3666 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003667 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003668 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3669
3670 /* replace the old entry */
3671 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003672 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003673 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3674
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003675 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003676 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003677 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3678
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003679 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003680
3681 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003682 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003683 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003684 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003685 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003686 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003687
3688 printf("\n");
3689
3690 gbproxy_peer_free(peer);
3691 }
3692
3693 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003694 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003695 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003696
3697 printf("Test TLLI expiry, max_age == 1:\n");
3698
3699 cfg.tlli_max_len = 0;
3700 cfg.tlli_max_age = 1;
3701 peer = gbproxy_peer_alloc(&cfg, 20);
3702 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3703
3704 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003705 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003706 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3707
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003708 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003709 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003710 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003711 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3712
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003713 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003714 OSMO_ASSERT(num_removed == 1);
3715 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3716
3717 dump_peers(stdout, 2, now + 2, &cfg);
3718
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003719 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003720 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003721 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003722 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003723 OSMO_ASSERT(tlli_info);
3724 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
3725
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003726 printf("\n");
3727
3728 gbproxy_peer_free(peer);
3729 }
3730
3731 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003732 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003733 int num_removed;
3734
3735 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
3736
3737 cfg.tlli_max_len = 0;
3738 cfg.tlli_max_age = 1;
3739 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003740 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3741
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003742 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003743 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003744 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3745
3746 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003747 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003748 now + 1);
3749 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3750
3751 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003752 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003753 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003754 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
3755
3756 dump_peers(stdout, 2, now + 2, &cfg);
3757
3758 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003759 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003760 OSMO_ASSERT(num_removed == 2);
3761 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3762
3763 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003764
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003765 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003766 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003767 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003768 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003769 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003770 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003771 OSMO_ASSERT(tlli_info);
3772 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
3773
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003774 printf("\n");
3775
3776 gbproxy_peer_free(peer);
3777 }
3778}
3779
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003780static void test_gbproxy_imsi_matching(void)
3781{
3782 struct gbproxy_config cfg = {0};
3783 struct gbproxy_peer *peer;
3784 const char *err_msg = NULL;
3785 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3786 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3787 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3788 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3789 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3790 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3791 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3792 const char *filter_re1 = ".*";
3793 const char *filter_re2 = "^1234";
3794 const char *filter_re3 = "^4321";
3795 const char *filter_re4_bad = "^12[";
3796
3797 printf("=== Test IMSI/TMSI matching ===\n\n");
3798
3799 gbproxy_init_config(&cfg);
3800 OSMO_ASSERT(cfg.check_imsi == 0);
3801
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003802 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003803 OSMO_ASSERT(cfg.check_imsi == 1);
3804
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003805 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003806 OSMO_ASSERT(cfg.check_imsi == 1);
3807
3808 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003809 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003810 OSMO_ASSERT(err_msg != NULL);
3811 OSMO_ASSERT(cfg.check_imsi == 0);
3812
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003813 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003814 OSMO_ASSERT(cfg.check_imsi == 1);
3815
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003816 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003817 OSMO_ASSERT(cfg.check_imsi == 0);
3818
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003819 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003820 OSMO_ASSERT(cfg.check_imsi == 1);
3821
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003822 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003823 OSMO_ASSERT(cfg.check_imsi == 0);
3824
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003825 peer = gbproxy_peer_alloc(&cfg, 20);
3826
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003827 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003828 OSMO_ASSERT(cfg.check_imsi == 1);
3829
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003830 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3831 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003832 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003833 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003834 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003835 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3836 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3837 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3838 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3839 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003840
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003841 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003842 OSMO_ASSERT(cfg.check_imsi == 1);
3843
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003844 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3845 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3846 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3847 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3848 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3849 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3850 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003851
3852 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3853
3854 gbproxy_peer_free(peer);
3855}
3856
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003857static struct log_info_cat gprs_categories[] = {
3858 [DGPRS] = {
3859 .name = "DGPRS",
3860 .description = "GPRS Packet Service",
3861 .enabled = 1, .loglevel = LOGL_DEBUG,
3862 },
3863 [DNS] = {
3864 .name = "DNS",
3865 .description = "GPRS Network Service (NS)",
3866 .enabled = 1, .loglevel = LOGL_INFO,
3867 },
3868 [DBSSGP] = {
3869 .name = "DBSSGP",
3870 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3871 .enabled = 1, .loglevel = LOGL_DEBUG,
3872 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003873};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003874
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003875static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003876 .cat = gprs_categories,
3877 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003878};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003879
3880int main(int argc, char **argv)
3881{
3882 osmo_init_logging(&info);
3883 log_set_use_color(osmo_stderr_target, 0);
3884 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003885 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003886
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003887 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003888 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3889 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003890
3891 rate_ctr_init(NULL);
3892
3893 setlinebuf(stdout);
3894
3895 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003896 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003897 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003898 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003899 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003900 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02003901 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003902 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003903 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003904 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003905 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003906 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003907 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003908 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003909
3910 exit(EXIT_SUCCESS);
3911}