blob: c4ebc73eaf07c44c1bbc4349f3ae7c836e4c611a [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 Erlbeckc53f2a62014-08-15 14:56:28 +0200226/* DTAP - Attach Accept */
227static const unsigned char dtap_attach_acc[] = {
228 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
229 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
230 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200231};
232
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200233/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200234static const unsigned char dtap_attach_acc2[] = {
235 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
236 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
237 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
238};
239
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200240/* DTAP - Attach Complete */
241static const unsigned char dtap_attach_complete[] = {
242 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200243};
244
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200245/* DTAP - GMM Information */
246static const unsigned char dtap_gmm_information[] = {
247 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200248};
249
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200250/* DTAP - Routing Area Update Request */
251static const unsigned char dtap_ra_upd_req[] = {
252 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
253 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
254 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
255 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
256 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
257 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
258 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200259};
260
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200261/* DTAP - Routing Area Update Accept */
262static const unsigned char dtap_ra_upd_acc[] = {
263 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
264 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
265 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200266};
267
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200268/* DTAP - Routing Area Update Accept, P-TMSI 2 */
269static const unsigned char dtap_ra_upd_acc2[] = {
270 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
271 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
272 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
273};
274
275/* DTAP - Routing Area Update Accept, P-TMSI 3 */
276static const unsigned char dtap_ra_upd_acc3[] = {
277 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
278 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
279 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
280};
281
282/* DTAP - Routing Area Update Complete */
283static const unsigned char dtap_ra_upd_complete[] = {
284 0x08, 0x0a
285};
286
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200287/* DTAP - Routing Area Update Reject */
288/* cause = 10 ("Implicitly detached"), force_standby = 0 */
289static const unsigned char dtap_ra_upd_rej[] = {
290 0x08, 0x0b, 0x0a, 0x00,
291};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200292
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200293/* DTAP - Activate PDP Context Request */
294static const unsigned char dtap_act_pdp_ctx_req[] = {
295 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200296 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
298 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
299 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
300 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200301 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200302};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200303
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200304/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200305/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200306static const unsigned char dtap_detach_po_req[] = {
307 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
308 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200309};
310
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200311/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200312/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200313static const unsigned char dtap_detach_req[] = {
314 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
315 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200316};
317
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200318/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200319static const unsigned char dtap_detach_acc[] = {
320 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200321};
322
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200323/* DTAP - Detach Request (MT) */
324/* normal detach, reattach required, implicitly detached */
325static const unsigned char dtap_mt_detach_rea_req[] = {
326 0x08, 0x05, 0x01, 0x25, 0x0a
327};
328
329/* DTAP - Detach Request (MT) */
330/* normal detach, reattach not required, implicitly detached */
331static const unsigned char dtap_mt_detach_req[] = {
332 0x08, 0x05, 0x02, 0x25, 0x0a
333};
334
335/* DTAP - Detach Accept (MT) */
336static const unsigned char dtap_mt_detach_acc[] = {
337 0x08, 0x06
338};
339
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200340/* GPRS-LLC - SAPI: LLGMM, U, XID */
341static const unsigned char llc_u_xid_ul[] = {
342 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
343 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
344};
345
346/* GPRS-LLC - SAPI: LLGMM, U, XID */
347static const unsigned char llc_u_xid_dl[] = {
348 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
349 0xe4, 0xa9, 0x1a, 0x9e
350};
351
352/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
353static const unsigned char llc_ui_ll11_dns_query_ul[] = {
354 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
355 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
356 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
357 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
358 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
359 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
360 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
361 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
362 0x8f, 0x07
363};
364
365/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
366static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
367 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
368 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
369 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
370 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
371 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
372 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
373 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
374 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
375 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
376 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
377 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
378 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
379 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
380 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
381 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
382 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
383 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
384 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
385 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
386 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
387 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
388 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
389 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
390 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
391 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
392 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
393};
394
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200395static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
396 struct sockaddr_in *peer, const unsigned char* data,
397 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200398
399static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
400 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
401{
402 /* GPRS Network Service, PDU type: NS_RESET,
403 */
404 unsigned char msg[12] = {
405 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
406 0x04, 0x82, 0x11, 0x22
407 };
408
409 msg[3] = cause;
410 msg[6] = nsvci / 256;
411 msg[7] = nsvci % 256;
412 msg[10] = nsei / 256;
413 msg[11] = nsei % 256;
414
415 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
416}
417
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200418static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
419 uint16_t nsvci, uint16_t nsei)
420{
421 /* GPRS Network Service, PDU type: NS_RESET_ACK,
422 */
423 unsigned char msg[9] = {
424 0x03, 0x01, 0x82, 0x11, 0x22,
425 0x04, 0x82, 0x11, 0x22
426 };
427
428 msg[3] = nsvci / 256;
429 msg[4] = nsvci % 256;
430 msg[7] = nsei / 256;
431 msg[8] = nsei % 256;
432
433 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
434}
435
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200436static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
437{
438 /* GPRS Network Service, PDU type: NS_ALIVE */
439 unsigned char msg[1] = {
440 0x0a
441 };
442
443 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
444}
445
446static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
447{
448 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
449 unsigned char msg[1] = {
450 0x0b
451 };
452
453 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
454}
455
456static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
457{
458 /* GPRS Network Service, PDU type: NS_UNBLOCK */
459 unsigned char msg[1] = {
460 0x06
461 };
462
463 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
464}
465
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200466static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
467{
468 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
469 unsigned char msg[1] = {
470 0x07
471 };
472
473 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
474}
475
476static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
477 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200478 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
479{
480 /* GPRS Network Service, PDU type: NS_UNITDATA */
481 unsigned char msg[4096] = {
482 0x00, 0x00, 0x00, 0x00
483 };
484
485 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
486
487 msg[2] = nsbvci / 256;
488 msg[3] = nsbvci % 256;
489 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
490
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200491 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200492}
493
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200494static void send_bssgp_ul_unitdata(
495 struct gprs_ns_inst *nsi, const char *text,
496 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
497 struct gprs_ra_id *raid, uint16_t cell_id,
498 const uint8_t *llc_msg, size_t llc_msg_size)
499{
500 /* GPRS Network Service, PDU type: NS_UNITDATA */
501 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
502 unsigned char msg[4096] = {
503 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
504 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
505 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
506 };
507
508 size_t bssgp_msg_size = 23 + llc_msg_size;
509
510 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
511
512 gsm48_construct_ra(msg + 10, raid);
513 msg[1] = (uint8_t)(tlli >> 24);
514 msg[2] = (uint8_t)(tlli >> 16);
515 msg[3] = (uint8_t)(tlli >> 8);
516 msg[4] = (uint8_t)(tlli >> 0);
517 msg[16] = cell_id / 256;
518 msg[17] = cell_id % 256;
519 msg[21] = llc_msg_size / 256;
520 msg[22] = llc_msg_size % 256;
521 memcpy(msg + 23, llc_msg, llc_msg_size);
522
523 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
524 src_addr, nsbvci, msg, bssgp_msg_size);
525}
526
527static void send_bssgp_dl_unitdata(
528 struct gprs_ns_inst *nsi, const char *text,
529 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
530 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
531 const uint8_t *llc_msg, size_t llc_msg_size)
532{
533 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
534 unsigned char msg[4096] = {
535 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
536 0x16, 0x82, 0x02, 0x58,
537 };
538 unsigned char racap_drx[] = {
539 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
540 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
541 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
542 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
543 };
544
545 size_t bssgp_msg_size = 0;
546
547 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
548
549 msg[1] = (uint8_t)(tlli >> 24);
550 msg[2] = (uint8_t)(tlli >> 16);
551 msg[3] = (uint8_t)(tlli >> 8);
552 msg[4] = (uint8_t)(tlli >> 0);
553
554 bssgp_msg_size = 12;
555
556 if (with_racap_drx) {
557 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
558 bssgp_msg_size += sizeof(racap_drx);
559 }
560
561 if (imsi) {
562 OSMO_ASSERT(imsi_size <= 127);
563 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
564 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
565 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
566 bssgp_msg_size += 2 + imsi_size;
567 }
568
569 if ((bssgp_msg_size % 4) != 0) {
570 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
571 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
572 msg[bssgp_msg_size + 1] = 0x80 | abytes;
573 memset(msg + bssgp_msg_size + 2, 0, abytes);
574 bssgp_msg_size += 2 + abytes;
575 }
576
577 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
578 if (llc_msg_size < 128) {
579 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
580 bssgp_msg_size += 2;
581 } else {
582 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
583 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
584 bssgp_msg_size += 3;
585 }
586 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
587 bssgp_msg_size += llc_msg_size;
588
589
590 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
591 src_addr, nsbvci, msg, bssgp_msg_size);
592}
593
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200594static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
595 uint16_t bvci)
596{
597 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
598 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200599 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200600 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200601 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
602 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200603 };
604
605 msg[3] = bvci / 256;
606 msg[4] = bvci % 256;
607
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200608 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
609}
610
611static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
612 struct sockaddr_in *src_addr, uint16_t bvci)
613{
614 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
615 * BSSGP RESET_ACK */
616 static unsigned char msg[5] = {
617 0x23, 0x04, 0x82, 0x00,
618 0x00
619 };
620
621 msg[3] = bvci / 256;
622 msg[4] = bvci % 256;
623
624 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200625}
626
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200627static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
628 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200629 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200630 struct gprs_ra_id *raid)
631{
632 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
633 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200634 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
635 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200636 };
637
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200638 msg[3] = (uint8_t)(tlli >> 24);
639 msg[4] = (uint8_t)(tlli >> 16);
640 msg[5] = (uint8_t)(tlli >> 8);
641 msg[6] = (uint8_t)(tlli >> 0);
642
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200643 gsm48_construct_ra(msg + 9, raid);
644
645 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
646}
647
648static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
649 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200650 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200651 struct gprs_ra_id *raid)
652{
653 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
654 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200655 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
656 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200657 0x81, 0x01
658 };
659
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200660 msg[3] = (uint8_t)(tlli >> 24);
661 msg[4] = (uint8_t)(tlli >> 16);
662 msg[5] = (uint8_t)(tlli >> 8);
663 msg[6] = (uint8_t)(tlli >> 0);
664
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200665 gsm48_construct_ra(msg + 9, raid);
666
667 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
668}
669
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200670static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
671 struct sockaddr_in *src_addr,
672 uint16_t bvci, uint32_t tlli,
673 unsigned n_frames, unsigned n_octets)
674{
675 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
676 unsigned char msg[] = {
677 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
678 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
679 /* n octets */ 0xff, 0xff, 0xff
680 };
681
682 msg[3] = (uint8_t)(tlli >> 24);
683 msg[4] = (uint8_t)(tlli >> 16);
684 msg[5] = (uint8_t)(tlli >> 8);
685 msg[6] = (uint8_t)(tlli >> 0);
686 msg[9] = (uint8_t)(n_frames);
687 msg[12] = (uint8_t)(bvci >> 8);
688 msg[13] = (uint8_t)(bvci >> 0);
689 msg[16] = (uint8_t)(n_octets >> 16);
690 msg[17] = (uint8_t)(n_octets >> 8);
691 msg[18] = (uint8_t)(n_octets >> 0);
692
693 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
694}
695
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200696static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
697 struct sockaddr_in *src_addr,
698 uint16_t bvci, uint8_t tag)
699{
700 /* GPRS Network Service, PDU type: NS_UNITDATA,
701 * BSSGP FLOW_CONTROL_BVC */
702 unsigned char msg[] = {
703 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
704 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
705 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
706 };
707
708 msg[3] = tag;
709
710 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
711 msg, sizeof(msg));
712}
713
714static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
715 struct sockaddr_in *src_addr,
716 uint16_t bvci, uint8_t tag)
717{
718 /* GPRS Network Service, PDU type: NS_UNITDATA,
719 * BSSGP FLOW_CONTROL_BVC_ACK */
720 unsigned char msg[] = {
721 0x27, 0x1e, 0x81, /* Tag */ 0xce
722 };
723
724 msg[3] = tag;
725
726 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
727 msg, sizeof(msg));
728}
729
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200730static void send_llc_ul_ui(
731 struct gprs_ns_inst *nsi, const char *text,
732 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
733 struct gprs_ra_id *raid, uint16_t cell_id,
734 unsigned sapi, unsigned nu,
735 const uint8_t *msg, size_t msg_size)
736{
737 unsigned char llc_msg[4096] = {
738 0x00, 0xc0, 0x01
739 };
740
741 size_t llc_msg_size = 3 + msg_size + 3;
742 uint8_t e_bit = 0;
743 uint8_t pm_bit = 1;
744 unsigned fcs;
745
746 nu &= 0x01ff;
747
748 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
749
750 llc_msg[0] = (sapi & 0x0f);
751 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
752 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
753
754 memcpy(llc_msg + 3, msg, msg_size);
755
756 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
757 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
758 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
759 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
760
761 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
762 src_addr, nsbvci, tlli, raid, cell_id,
763 llc_msg, llc_msg_size);
764}
765
766static void send_llc_dl_ui(
767 struct gprs_ns_inst *nsi, const char *text,
768 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
769 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
770 unsigned sapi, unsigned nu,
771 const uint8_t *msg, size_t msg_size)
772{
773 /* GPRS Network Service, PDU type: NS_UNITDATA */
774 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
775 unsigned char llc_msg[4096] = {
776 0x00, 0x00, 0x01
777 };
778
779 size_t llc_msg_size = 3 + msg_size + 3;
780 uint8_t e_bit = 0;
781 uint8_t pm_bit = 1;
782 unsigned fcs;
783
784 nu &= 0x01ff;
785
786 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
787
788 llc_msg[0] = 0x40 | (sapi & 0x0f);
789 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
790 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
791
792 memcpy(llc_msg + 3, msg, msg_size);
793
794 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
795 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
796 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
797 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
798
799 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
800 src_addr, nsbvci, tlli,
801 with_racap_drx, imsi, imsi_size,
802 llc_msg, llc_msg_size);
803}
804
805
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200806static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
807 uint16_t nsvci, uint16_t nsei)
808{
809 printf("Setup NS-VC: remote 0x%08x:%d, "
810 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
811 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
812 nsvci, nsvci, nsei, nsei);
813
814 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
815 send_ns_alive(nsi, src_addr);
816 send_ns_unblock(nsi, src_addr);
817 send_ns_alive_ack(nsi, src_addr);
818}
819
820static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
821 uint16_t bvci)
822{
823 printf("Setup BSSGP: remote 0x%08x:%d, "
824 "BVCI 0x%04x(%d)\n\n",
825 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
826 bvci, bvci);
827
828 send_bssgp_reset(nsi, src_addr, bvci);
829}
830
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200831static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
832 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200833{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200834 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
835 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200836 send_ns_alive_ack(nsi, sgsn_peer);
837 send_ns_unblock_ack(nsi, sgsn_peer);
838 send_ns_alive(nsi, sgsn_peer);
839}
840
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200841static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
842{
843 sgsn_peer->sin_family = AF_INET;
844 sgsn_peer->sin_port = htons(32000);
845 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
846}
847
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200848static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
849{
850 sgsn_peer->sin_family = AF_INET;
851 sgsn_peer->sin_port = htons(32001);
852 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
853}
854
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200855static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
856{
857 size_t i;
858
859 for (i = 0; i < size; ++i) {
860 bss_peers[i].sin_family = AF_INET;
861 bss_peers[i].sin_port = htons((i + 1) * 1111);
862 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
863 }
864}
865
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200866int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
867 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
868
869/* override */
870int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
871 struct msgb *msg, uint16_t bvci)
872{
873 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
874 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200875 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200876
877 switch (event) {
878 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200879 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200880 default:
881 break;
882 }
883 return 0;
884}
885
886/* override */
887ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
888 const struct sockaddr *dest_addr, socklen_t addrlen)
889{
890 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
891 const struct sockaddr *, socklen_t);
892 static sendto_t real_sendto = NULL;
893 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200894 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200895
896 if (!real_sendto)
897 real_sendto = dlsym(RTLD_NEXT, "sendto");
898
899 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200900 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
901 dest_host, dest_port,
902 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200903 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200904 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
905 dest_host, dest_port,
906 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200907 else if (dest_host == REMOTE_SGSN2_ADDR)
908 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
909 dest_host, dest_port,
910 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200911 else
912 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
913
914 return len;
915}
916
917/* override */
918int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
919{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200920 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
921 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200922 uint16_t bvci = msgb_bvci(msg);
923 uint16_t nsei = msgb_nsei(msg);
924
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200925 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200926
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200927 if (!real_gprs_ns_sendmsg)
928 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
929
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200930 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200931 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
932 "msg length %d (%s)\n",
933 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200934 else if (nsei == SGSN2_NSEI)
935 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
936 "msg length %d (%s)\n",
937 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200938 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200939 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
940 "msg length %d (%s)\n",
941 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200942
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200943 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200944}
945
946static void dump_rate_ctr_group(FILE *stream, const char *prefix,
947 struct rate_ctr_group *ctrg)
948{
949 unsigned int i;
950
951 for (i = 0; i < ctrg->desc->num_ctr; i++) {
952 struct rate_ctr *ctr = &ctrg->ctr[i];
953 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
954 fprintf(stream, " %s%s: %llu%s",
955 prefix, ctrg->desc->ctr_desc[i].description,
956 (long long)ctr->current,
957 "\n");
958 };
959}
960
961/* Signal handler for signals from NS layer */
962static int test_signal(unsigned int subsys, unsigned int signal,
963 void *handler_data, void *signal_data)
964{
965 struct ns_signal_data *nssd = signal_data;
966 int rc;
967
968 if (subsys != SS_L_NS)
969 return 0;
970
971 switch (signal) {
972 case S_NS_RESET:
973 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
974 nssd->nsvc->nsvci,
975 gprs_ns_ll_str(nssd->nsvc));
976 break;
977
978 case S_NS_ALIVE_EXP:
979 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
980 nssd->nsvc->nsvci,
981 gprs_ns_ll_str(nssd->nsvc));
982 break;
983
984 case S_NS_BLOCK:
985 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
986 nssd->nsvc->nsvci,
987 gprs_ns_ll_str(nssd->nsvc));
988 break;
989
990 case S_NS_UNBLOCK:
991 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
992 nssd->nsvc->nsvci,
993 gprs_ns_ll_str(nssd->nsvc));
994 break;
995
996 case S_NS_REPLACED:
997 printf("==> got signal NS_REPLACED: 0x%04x/%s",
998 nssd->nsvc->nsvci,
999 gprs_ns_ll_str(nssd->nsvc));
1000 printf(" -> 0x%04x/%s\n",
1001 nssd->old_nsvc->nsvci,
1002 gprs_ns_ll_str(nssd->old_nsvc));
1003 break;
1004
1005 default:
1006 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1007 nssd->nsvc->nsvci,
1008 gprs_ns_ll_str(nssd->nsvc));
1009 break;
1010 }
1011 printf("\n");
1012 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1013 return rc;
1014}
1015
1016static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1017{
1018 struct msgb *msg;
1019 int ret;
1020 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1021 fprintf(stderr, "message too long: %d\n", data_len);
1022 return -1;
1023 }
1024
1025 msg = gprs_ns_msgb_alloc();
1026 memmove(msg->data, data, data_len);
1027 msg->l2h = msg->data;
1028 msgb_put(msg, data_len);
1029
1030 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1031 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1032 osmo_hexdump(data, data_len));
1033
1034 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1035
1036 printf("result (%s) = %d\n\n", text, ret);
1037
1038 msgb_free(msg);
1039
1040 return ret;
1041}
1042
1043static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1044{
1045 struct gprs_nsvc *nsvc;
1046
1047 printf("Current NS-VCIs:\n");
1048 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1049 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001050 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001051 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001052 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1053 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1054 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001055 );
1056 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1057 }
1058 printf("\n");
1059}
1060
1061static void test_gbproxy()
1062{
1063 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1064 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001065 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001066
1067 bssgp_nsi = nsi;
1068 gbcfg.nsi = bssgp_nsi;
1069 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1070
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001071 configure_sgsn_peer(&sgsn_peer);
1072 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001073
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001074 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001075 printf("--- Initialise SGSN ---\n\n");
1076
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001077 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001078 gprs_dump_nsi(nsi);
1079
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001080 printf("--- Initialise BSS 1 ---\n\n");
1081
1082 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1083 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1084 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001085 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001086
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001087 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1088
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001089 printf("--- Initialise BSS 2 ---\n\n");
1090
1091 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1092 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1093 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001094 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001095
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001096 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1097
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001098 printf("--- Move BSS 1 to new port ---\n\n");
1099
1100 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1101 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001102 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001103
1104 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1105
1106 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
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 1 to current BSS 2 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 2 to new port ---\n\n");
1117
1118 setup_ns(nsi, &bss_peer[3], 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 former BSS 1 port ---\n\n");
1123
1124 setup_ns(nsi, &bss_peer[2], 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
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001128 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1129
1130 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1131 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001132 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001133
1134 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1135
1136 setup_bssgp(nsi, &bss_peer[0], 0x1012);
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 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1141
1142 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1143
1144 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1145 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001146 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001147
1148 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1149
1150 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1151
1152 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1153 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001154 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001155
1156 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1157
1158 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1159
1160 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1161
1162 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1163
1164 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1165
1166 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1167
1168 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1169
1170 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1171
1172 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1173
1174 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1175
1176 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1177
1178 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1179
1180 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1181
1182 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1183
1184 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1185 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001186 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001187
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001188 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001189
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001190 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1191
1192 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1193
1194 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1195
1196 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1197
1198 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1199
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001200 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1201
1202 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1203
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001204 /* Find peer */
1205 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1206 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1207 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1208 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1209 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1210 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1211
1212
1213 /* Cleanup */
1214 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1215 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1216 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1217 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1218 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1219
1220 dump_peers(stdout, 0, 0, &gbcfg);
1221
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001222 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001223
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001224 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001225 gprs_ns_destroy(nsi);
1226 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001227}
1228
1229static void test_gbproxy_ident_changes()
1230{
1231 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1232 struct sockaddr_in bss_peer[1] = {{0},};
1233 struct sockaddr_in sgsn_peer= {0};
1234 uint16_t nsei[2] = {0x1000, 0x2000};
1235 uint16_t nsvci[2] = {0x1001, 0x2001};
1236 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1237
1238 bssgp_nsi = nsi;
1239 gbcfg.nsi = bssgp_nsi;
1240 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1241
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001242 configure_sgsn_peer(&sgsn_peer);
1243 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001244
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001245 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001246 printf("--- Initialise SGSN ---\n\n");
1247
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001248 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001249 gprs_dump_nsi(nsi);
1250
1251 printf("--- Initialise BSS 1 ---\n\n");
1252
1253 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1254 gprs_dump_nsi(nsi);
1255
1256 printf("--- Setup BVCI 1 ---\n\n");
1257
1258 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1259 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001260 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001261
1262 printf("--- Setup BVCI 2 ---\n\n");
1263
1264 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1265 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001266 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001267
1268 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1269
1270 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1271 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1272
1273 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1274
1275 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1276 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1277
1278 printf("--- Change NSEI ---\n\n");
1279
1280 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1281 gprs_dump_nsi(nsi);
1282
1283 printf("--- Setup BVCI 1 ---\n\n");
1284
1285 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1286 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001287 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001288
1289 printf("--- Setup BVCI 3 ---\n\n");
1290
1291 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1292 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001293 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001294
1295 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1296
1297 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1298 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1299
1300 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1301 " (should fail) ---\n\n");
1302
1303 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001304 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001305 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001306 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001307
1308 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1309
1310 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1311 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1312
1313 printf("--- Change NSVCI ---\n\n");
1314
1315 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1316 gprs_dump_nsi(nsi);
1317
1318 printf("--- Setup BVCI 1 ---\n\n");
1319
1320 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1321 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001322 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001323
1324 printf("--- Setup BVCI 4 ---\n\n");
1325
1326 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1327 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001328 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001329
1330 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1331
1332 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1333 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1334
1335 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1336 " (should fail) ---\n\n");
1337
1338 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001339 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001340 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001341 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001342
1343 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1344
1345 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1346 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1347
1348 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1349
1350 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1351 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1352
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001353 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001354 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001355
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001356 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001357 gprs_ns_destroy(nsi);
1358 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001359}
1360
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001361static void test_gbproxy_ra_patching()
1362{
1363 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1364 struct sockaddr_in bss_peer[1] = {{0},};
1365 struct sockaddr_in sgsn_peer= {0};
1366 struct gprs_ra_id rai_bss =
1367 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1368 struct gprs_ra_id rai_sgsn =
1369 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1370 struct gprs_ra_id rai_unknown =
1371 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001372 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001373 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001374 const uint32_t ptmsi = 0xefe2b700;
1375 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001376 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001377 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001378 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001379 struct gbproxy_tlli_info *tlli_info;
1380 struct gbproxy_peer *peer;
1381
1382 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001383
1384 bssgp_nsi = nsi;
1385 gbcfg.nsi = bssgp_nsi;
1386 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001387 gbcfg.core_mcc = 123;
1388 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001389 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001390 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001391 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001392
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001393 configure_sgsn_peer(&sgsn_peer);
1394 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001395
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001396 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001397 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001398 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1399 gbcfg.match_re, err_msg);
1400 exit(1);
1401 }
1402
1403
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001404 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001405 printf("--- Initialise SGSN ---\n\n");
1406
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001407 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001408 gprs_dump_nsi(nsi);
1409
1410 printf("--- Initialise BSS 1 ---\n\n");
1411
1412 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1413 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1414 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001415 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001416
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001417 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001418 OSMO_ASSERT(peer != NULL);
1419
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001420 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1421
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001422 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1423 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001424
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001425 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001426 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001427
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001428 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1429 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1430
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001431 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1432
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001433 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1434 foreign_tlli, &rai_bss, cell_id,
1435 GPRS_SAPI_GMM, 0,
1436 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001437
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001438 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1439
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001440 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1441 foreign_tlli, 0, NULL, 0,
1442 GPRS_SAPI_GMM, 0,
1443 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001444
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001445 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1446 foreign_tlli, &rai_bss, cell_id,
1447 GPRS_SAPI_GMM, 3,
1448 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001449
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001450 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1451 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1452
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001453 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1454 foreign_tlli, 1, imsi, sizeof(imsi),
1455 GPRS_SAPI_GMM, 1,
1456 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001457
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001458 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1459
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001460 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1461 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1462 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1463
1464 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1465 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1466 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1467
1468 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1469 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1470 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1471
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001472 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001473 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001474 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1475 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1476 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1477 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1478 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1479 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1480 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1481 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001482
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001483 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1484 local_tlli, &rai_bss, cell_id,
1485 GPRS_SAPI_GMM, 4,
1486 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001487
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001488 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1489
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001490 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001491 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001492 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1493 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1494 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1495 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1496 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1497 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1498 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1499 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001500
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001501 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001502 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1503 local_tlli, &rai_bss, cell_id,
1504 GPRS_SAPI_GMM, 3,
1505 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001506
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001507 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1508
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001509 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001510 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001511 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1512 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1513 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1514 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1515 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1516 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1517 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1518 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001519
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001520 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1521 local_tlli, 1, imsi, sizeof(imsi),
1522 GPRS_SAPI_GMM, 2,
1523 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001524
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001525 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1526
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001527 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001528 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001529 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1530 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1531 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1532 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001533
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001534 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001535 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1536 local_tlli, &rai_bss, cell_id,
1537 GPRS_SAPI_GMM, 3,
1538 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001539
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001540 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1541
Jacob Erlbeck73685282014-05-23 20:48:07 +02001542 gbcfg.core_apn[0] = 0;
1543 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001544
1545 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001546 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1547 local_tlli, &rai_bss, cell_id,
1548 GPRS_SAPI_GMM, 3,
1549 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001550
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001551 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1552
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001553 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001554
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001555 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001556 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1557 local_tlli, &rai_bss, cell_id,
1558 GPRS_SAPI_GMM, 6,
1559 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001560
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001561 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1562 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1563
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001564 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1565 local_tlli, 1, imsi, sizeof(imsi),
1566 GPRS_SAPI_GMM, 5,
1567 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001568
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001569 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001570
1571 printf("--- RA update ---\n\n");
1572
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001573 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1574 foreign_tlli, &rai_bss, 0x7080,
1575 GPRS_SAPI_GMM, 5,
1576 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001577
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001578 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1579
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001580 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1581 foreign_tlli, 1, imsi, sizeof(imsi),
1582 GPRS_SAPI_GMM, 6,
1583 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001584
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001585 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1586
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001587 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001588 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1589 local_tlli, &rai_bss, cell_id,
1590 GPRS_SAPI_GMM, 3,
1591 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001592
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001593 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1594
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001595 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001596
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001597 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001598 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1599 local_tlli, &rai_bss, cell_id,
1600 GPRS_SAPI_GMM, 6,
1601 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001602
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001603 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1604
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001605 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001606 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001607
1608 printf("--- Bad cases ---\n\n");
1609
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001610 /* The RAI in the Attach Request message differs from the RAI in the
1611 * BSSGP message, only patch the latter */
1612
1613 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1614 foreign_tlli2, &rai_bss, cell_id,
1615 GPRS_SAPI_GMM, 0,
1616 dtap_attach_req2, sizeof(dtap_attach_req2));
1617
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001618 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1619
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001620 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001621 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1622 local_tlli, &rai_bss, cell_id,
1623 GPRS_SAPI_GMM, 3,
1624 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001625
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001626 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001627 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001628
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001629 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001630 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001631
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001632 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001633 gprs_ns_destroy(nsi);
1634 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001635}
1636
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001637static void test_gbproxy_ptmsi_patching()
1638{
1639 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1640 struct sockaddr_in bss_peer[1] = {{0},};
1641 struct sockaddr_in sgsn_peer= {0};
1642 struct gprs_ra_id rai_bss =
1643 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1644 struct gprs_ra_id rai_sgsn =
1645 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001646 struct gprs_ra_id rai_wrong_mcc_sgsn =
1647 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001648 struct gprs_ra_id rai_unknown =
1649 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1650 uint16_t cell_id = 0x1234;
1651
1652 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001653 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1654 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001655 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001656 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1657 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001658 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001659 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001660
1661 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001662 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1663 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001664 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001665 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1666 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001667 const uint32_t foreign_bss_tlli = 0x8000dead;
1668
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001669
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001670 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1671 struct gbproxy_tlli_info *tlli_info;
1672 struct gbproxy_peer *peer;
1673 unsigned bss_nu = 0;
1674 unsigned sgsn_nu = 0;
1675
1676 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001677 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1678 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1679 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1680 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1681 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001682
1683 bssgp_nsi = nsi;
1684 gbcfg.nsi = bssgp_nsi;
1685 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1686 gbcfg.core_mcc = 123;
1687 gbcfg.core_mnc = 456;
1688 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1689 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1690 gbcfg.patch_ptmsi = 1;
1691 gbcfg.bss_ptmsi_state = 0;
1692 gbcfg.sgsn_tlli_state = 1;
1693
1694 configure_sgsn_peer(&sgsn_peer);
1695 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1696
1697 printf("=== %s ===\n", __func__);
1698 printf("--- Initialise SGSN ---\n\n");
1699
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001700 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001701
1702 printf("--- Initialise BSS 1 ---\n\n");
1703
1704 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1705 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1706
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001707 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001708 OSMO_ASSERT(peer != NULL);
1709
1710 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1711
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001712 gprs_dump_nsi(nsi);
1713 dump_global(stdout, 0);
1714 dump_peers(stdout, 0, 0, &gbcfg);
1715
1716 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1717
1718 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1719 foreign_bss_tlli, &rai_unknown, cell_id,
1720 GPRS_SAPI_GMM, bss_nu++,
1721 dtap_attach_req, sizeof(dtap_attach_req));
1722
1723 dump_peers(stdout, 0, 0, &gbcfg);
1724
1725 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1726 random_sgsn_tlli, 0, NULL, 0,
1727 GPRS_SAPI_GMM, sgsn_nu++,
1728 dtap_identity_req, sizeof(dtap_identity_req));
1729
1730 dump_peers(stdout, 0, 0, &gbcfg);
1731
1732 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1733 foreign_bss_tlli, &rai_bss, cell_id,
1734 GPRS_SAPI_GMM, bss_nu++,
1735 dtap_identity_resp, sizeof(dtap_identity_resp));
1736
1737 dump_peers(stdout, 0, 0, &gbcfg);
1738
1739 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1740 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1741 GPRS_SAPI_GMM, sgsn_nu++,
1742 dtap_attach_acc, sizeof(dtap_attach_acc));
1743
1744 dump_peers(stdout, 0, 0, &gbcfg);
1745
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001746 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001747 OSMO_ASSERT(tlli_info);
1748 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1749 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1750 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1751 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1752 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1753 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1754 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1755 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1756 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1757 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1758
1759 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1760 local_bss_tlli, &rai_bss, cell_id,
1761 GPRS_SAPI_GMM, bss_nu++,
1762 dtap_attach_complete, sizeof(dtap_attach_complete));
1763
1764 dump_peers(stdout, 0, 0, &gbcfg);
1765
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001766 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001767 OSMO_ASSERT(tlli_info);
1768 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1769 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1770 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1771 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1772 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1773 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1774 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1775 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1776
1777 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1778 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1779 GPRS_SAPI_GMM, sgsn_nu++,
1780 dtap_gmm_information, sizeof(dtap_gmm_information));
1781
1782 dump_peers(stdout, 0, 0, &gbcfg);
1783
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001784 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001785 OSMO_ASSERT(tlli_info);
1786 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1787 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1788 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1789 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1790
Jacob Erlbeck82add782014-09-05 18:08:12 +02001791 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1792 local_bss_tlli, &rai_bss, cell_id,
1793 GPRS_SAPI_GMM, bss_nu++,
1794 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1795
1796 dump_peers(stdout, 0, 0, &gbcfg);
1797
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001798 /* Non-DTAP */
1799 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1800 local_bss_tlli, &rai_bss, cell_id,
1801 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1802
1803 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1804 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1805 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1806
1807 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1808 local_bss_tlli, &rai_bss, cell_id,
1809 llc_ui_ll11_dns_query_ul,
1810 sizeof(llc_ui_ll11_dns_query_ul));
1811
1812 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1813 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1814 llc_ui_ll11_dns_resp_dl,
1815 sizeof(llc_ui_ll11_dns_resp_dl));
1816
1817 dump_peers(stdout, 0, 0, &gbcfg);
1818
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001819 /* Repeated RA Update Requests */
1820 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1821 local_bss_tlli, &rai_bss, 0x7080,
1822 GPRS_SAPI_GMM, bss_nu++,
1823 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1824
1825 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1826 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1827 GPRS_SAPI_GMM, sgsn_nu++,
1828 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1829
1830 dump_peers(stdout, 0, 0, &gbcfg);
1831
1832 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1833 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1834 OSMO_ASSERT(tlli_info);
1835 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1836 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1837 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1838 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1839 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1840 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1841 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1842 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1843 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1844 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1845
1846 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1847 local_bss_tlli2, &rai_bss, 0x7080,
1848 GPRS_SAPI_GMM, bss_nu++,
1849 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1850
1851 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1852 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1853 GPRS_SAPI_GMM, sgsn_nu++,
1854 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1855
1856 dump_peers(stdout, 0, 0, &gbcfg);
1857
1858 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1859 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1860 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1861 OSMO_ASSERT(tlli_info);
1862 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1863 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1864 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1865 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1866 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1867 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1868 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1869 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1870 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1871 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1872
1873 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1874 local_bss_tlli3, &rai_bss, 0x7080,
1875 GPRS_SAPI_GMM, bss_nu++,
1876 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1877
1878 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1879
1880 OSMO_ASSERT(tlli_info);
1881 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1882 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1883 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1884 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1885
1886 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1887 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1888 GPRS_SAPI_GMM, sgsn_nu++,
1889 dtap_gmm_information, sizeof(dtap_gmm_information));
1890
1891 dump_peers(stdout, 0, 0, &gbcfg);
1892
1893 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1894 OSMO_ASSERT(tlli_info);
1895 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1896 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1897 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1898 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1899
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001900 /* Other messages */
1901 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001902 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001903
1904 dump_peers(stdout, 0, 0, &gbcfg);
1905
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001906 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001907
1908 dump_peers(stdout, 0, 0, &gbcfg);
1909
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001910 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001911
1912 dump_peers(stdout, 0, 0, &gbcfg);
1913
1914 /* Bad case: Invalid BVCI */
1915 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001916 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001917 dump_global(stdout, 0);
1918
1919 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001920 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001921
1922 dump_global(stdout, 0);
1923
1924 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001925 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001926 &rai_wrong_mcc_sgsn);
1927
1928 dump_global(stdout, 0);
1929
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001930 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
1931 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1932 unknown_sgsn_tlli, 1, NULL, 0,
1933 GPRS_SAPI_GMM, 2,
1934 dtap_gmm_information, sizeof(dtap_gmm_information));
1935
1936 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
1937 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1938 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
1939 GPRS_SAPI_GMM, 3,
1940 dtap_gmm_information, sizeof(dtap_gmm_information));
1941
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001942 /* Detach */
1943 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001944 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001945 GPRS_SAPI_GMM, bss_nu++,
1946 dtap_detach_req, sizeof(dtap_detach_req));
1947
1948 dump_peers(stdout, 0, 0, &gbcfg);
1949
1950 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001951 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001952 GPRS_SAPI_GMM, sgsn_nu++,
1953 dtap_detach_acc, sizeof(dtap_detach_acc));
1954
1955 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001956
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001957 dump_global(stdout, 0);
1958
1959 gbprox_reset(&gbcfg);
1960 gprs_ns_destroy(nsi);
1961 nsi = NULL;
1962}
1963
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001964static void test_gbproxy_imsi_acquisition()
1965{
1966 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1967 struct sockaddr_in bss_peer[1] = {{0},};
1968 struct sockaddr_in sgsn_peer= {0};
1969 struct gprs_ra_id rai_bss =
1970 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1971 struct gprs_ra_id rai_sgsn =
1972 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1973 struct gprs_ra_id rai_wrong_mcc_sgsn =
1974 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1975 struct gprs_ra_id rai_unknown =
1976 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1977 uint16_t cell_id = 0x1234;
1978
1979 const uint32_t sgsn_ptmsi = 0xefe2b700;
1980 const uint32_t local_sgsn_tlli = 0xefe2b700;
1981 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1982
1983 const uint32_t bss_ptmsi = 0xc00f7304;
1984 const uint32_t local_bss_tlli = 0xc00f7304;
1985 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001986 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001987
1988 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1989 struct gbproxy_tlli_info *tlli_info;
1990 struct gbproxy_peer *peer;
1991 unsigned bss_nu = 0;
1992 unsigned sgsn_nu = 0;
1993
1994 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1995
1996 bssgp_nsi = nsi;
1997 gbcfg.nsi = bssgp_nsi;
1998 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1999 gbcfg.core_mcc = 123;
2000 gbcfg.core_mnc = 456;
2001 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2002 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2003 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002004 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002005 gbcfg.bss_ptmsi_state = 0;
2006 gbcfg.sgsn_tlli_state = 1;
2007
2008 configure_sgsn_peer(&sgsn_peer);
2009 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2010
2011 printf("=== %s ===\n", __func__);
2012 printf("--- Initialise SGSN ---\n\n");
2013
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002014 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002015
2016 printf("--- Initialise BSS 1 ---\n\n");
2017
2018 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2019 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2020
2021 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2022 OSMO_ASSERT(peer != NULL);
2023
2024 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2025
2026 gprs_dump_nsi(nsi);
2027 dump_global(stdout, 0);
2028 dump_peers(stdout, 0, 0, &gbcfg);
2029
2030 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2031
2032 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002033 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002034 GPRS_SAPI_GMM, bss_nu++,
2035 dtap_attach_req, sizeof(dtap_attach_req));
2036
2037 dump_peers(stdout, 0, 0, &gbcfg);
2038
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002039 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2040 foreign_bss_tlli, &rai_bss, cell_id,
2041 GPRS_SAPI_GMM, bss_nu++,
2042 dtap_identity_resp, sizeof(dtap_identity_resp));
2043
2044 dump_peers(stdout, 0, 0, &gbcfg);
2045
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002046 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2047 random_sgsn_tlli, 0, NULL, 0,
2048 GPRS_SAPI_GMM, sgsn_nu++,
2049 dtap_identity_req, sizeof(dtap_identity_req));
2050
2051 dump_peers(stdout, 0, 0, &gbcfg);
2052
2053 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2054 foreign_bss_tlli, &rai_bss, cell_id,
2055 GPRS_SAPI_GMM, bss_nu++,
2056 dtap_identity_resp, sizeof(dtap_identity_resp));
2057
2058 dump_peers(stdout, 0, 0, &gbcfg);
2059
2060 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2061 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2062 GPRS_SAPI_GMM, sgsn_nu++,
2063 dtap_attach_acc, sizeof(dtap_attach_acc));
2064
2065 dump_peers(stdout, 0, 0, &gbcfg);
2066
2067 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2068 OSMO_ASSERT(tlli_info);
2069 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2070 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2071 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2072 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2073 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2074 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2075 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2076 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2077 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2078 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2079
2080 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2081 local_bss_tlli, &rai_bss, cell_id,
2082 GPRS_SAPI_GMM, bss_nu++,
2083 dtap_attach_complete, sizeof(dtap_attach_complete));
2084
2085 dump_peers(stdout, 0, 0, &gbcfg);
2086
2087 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2088 OSMO_ASSERT(tlli_info);
2089 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2090 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2091 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2092 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2093 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2094 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2095 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2096 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2097
2098 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2099 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2100 GPRS_SAPI_GMM, sgsn_nu++,
2101 dtap_gmm_information, sizeof(dtap_gmm_information));
2102
2103 dump_peers(stdout, 0, 0, &gbcfg);
2104
2105 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2106 OSMO_ASSERT(tlli_info);
2107 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2108 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2109 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2110 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2111
2112 /* Non-DTAP */
2113 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2114 local_bss_tlli, &rai_bss, cell_id,
2115 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2116
2117 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2118 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2119 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2120
2121 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2122 local_bss_tlli, &rai_bss, cell_id,
2123 llc_ui_ll11_dns_query_ul,
2124 sizeof(llc_ui_ll11_dns_query_ul));
2125
2126 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2127 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2128 llc_ui_ll11_dns_resp_dl,
2129 sizeof(llc_ui_ll11_dns_resp_dl));
2130
2131 dump_peers(stdout, 0, 0, &gbcfg);
2132
2133 /* Other messages */
2134 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2135 local_bss_tlli, 1, 12);
2136
2137 dump_peers(stdout, 0, 0, &gbcfg);
2138
2139 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2140 local_sgsn_tlli, 1, 12);
2141
2142 dump_peers(stdout, 0, 0, &gbcfg);
2143
2144 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2145
2146 dump_peers(stdout, 0, 0, &gbcfg);
2147
2148 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2149
2150 dump_peers(stdout, 0, 0, &gbcfg);
2151
2152 /* Bad case: Invalid BVCI */
2153 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2154 local_bss_tlli, 1, 12);
2155 dump_global(stdout, 0);
2156
2157 /* Bad case: Invalid RAI */
2158 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2159
2160 dump_global(stdout, 0);
2161
2162 /* Bad case: Invalid MCC (LAC ok) */
2163 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2164 &rai_wrong_mcc_sgsn);
2165
2166 dump_global(stdout, 0);
2167
2168 /* Detach */
2169 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2170 local_bss_tlli, &rai_bss, cell_id,
2171 GPRS_SAPI_GMM, bss_nu++,
2172 dtap_detach_req, sizeof(dtap_detach_req));
2173
2174 dump_peers(stdout, 0, 0, &gbcfg);
2175
2176 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2177 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2178 GPRS_SAPI_GMM, sgsn_nu++,
2179 dtap_detach_acc, sizeof(dtap_detach_acc));
2180
2181 dump_peers(stdout, 0, 0, &gbcfg);
2182
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002183 /* Special case: Repeated Attach Requests */
2184
2185 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2186 foreign_bss_tlli, &rai_unknown, cell_id,
2187 GPRS_SAPI_GMM, bss_nu++,
2188 dtap_attach_req, sizeof(dtap_attach_req));
2189
2190 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2191 foreign_bss_tlli, &rai_unknown, cell_id,
2192 GPRS_SAPI_GMM, bss_nu++,
2193 dtap_attach_req, sizeof(dtap_attach_req));
2194
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002195 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2196 foreign_bss_tlli, &rai_bss, cell_id,
2197 GPRS_SAPI_GMM, bss_nu++,
2198 dtap_detach_req, sizeof(dtap_detach_req));
2199
2200 dump_peers(stdout, 0, 0, &gbcfg);
2201
2202 /* Special case: Detach from an unknown TLLI */
2203
2204 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2205 other_bss_tlli, &rai_bss, cell_id,
2206 GPRS_SAPI_GMM, bss_nu++,
2207 dtap_detach_req, sizeof(dtap_detach_req));
2208
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002209 dump_peers(stdout, 0, 0, &gbcfg);
2210
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002211 dump_global(stdout, 0);
2212
2213 gbprox_reset(&gbcfg);
2214 gprs_ns_destroy(nsi);
2215 nsi = NULL;
2216}
2217
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002218static void test_gbproxy_secondary_sgsn()
2219{
2220 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2221 struct sockaddr_in bss_peer[1] = {{0},};
2222 struct sockaddr_in sgsn_peer[2]= {{0},};
2223 struct gprs_ra_id rai_bss =
2224 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2225 struct gprs_ra_id rai_sgsn =
2226 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2227 struct gprs_ra_id rai_unknown =
2228 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2229 uint16_t cell_id = 0x1234;
2230
2231 const uint32_t sgsn_ptmsi = 0xefe2b700;
2232 const uint32_t local_sgsn_tlli = 0xefe2b700;
2233 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2234
2235 const uint32_t bss_ptmsi = 0xc00f7304;
2236 const uint32_t local_bss_tlli = 0xc00f7304;
2237 const uint32_t foreign_bss_tlli = 0x8000dead;
2238
2239 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2240 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2241 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2242 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2243 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2244 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2245
2246 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2247 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2248 struct gbproxy_tlli_info *tlli_info;
2249 struct gbproxy_peer *peer;
2250 unsigned bss_nu = 0;
2251 unsigned sgsn_nu = 0;
2252
2253 const char *err_msg = NULL;
2254 const char *filter_re = "999999";
2255
2256 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2257 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2258
2259 bssgp_nsi = nsi;
2260 gbcfg.nsi = bssgp_nsi;
2261 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2262 gbcfg.core_mcc = 123;
2263 gbcfg.core_mnc = 456;
2264 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2265 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2266 gbcfg.patch_ptmsi = 1;
2267 gbcfg.acquire_imsi = 1;
2268 gbcfg.bss_ptmsi_state = 0;
2269 gbcfg.sgsn_tlli_state = 1;
2270 gbcfg.route_to_sgsn2 = 1;
2271 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2272
2273 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2274 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2275 err_msg);
2276 OSMO_ASSERT(err_msg == NULL);
2277 }
2278
2279 configure_sgsn_peer(&sgsn_peer[0]);
2280 configure_sgsn2_peer(&sgsn_peer[1]);
2281 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2282
2283 printf("=== %s ===\n", __func__);
2284 printf("--- Initialise SGSN 1 ---\n\n");
2285
2286 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2287
2288 printf("--- Initialise SGSN 2 ---\n\n");
2289
2290 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2291
2292 printf("--- Initialise BSS 1 ---\n\n");
2293
2294 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2295 setup_bssgp(nsi, &bss_peer[0], 0x0);
2296 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2297 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2298 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2299 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2300
2301 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2302 OSMO_ASSERT(peer != NULL);
2303
2304 gprs_dump_nsi(nsi);
2305 dump_global(stdout, 0);
2306 dump_peers(stdout, 0, 0, &gbcfg);
2307
2308 printf("--- Flow control ---\n\n");
2309
2310 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2311 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2312 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2313
2314 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2315
2316 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2317 foreign_bss_tlli, &rai_unknown, cell_id,
2318 GPRS_SAPI_GMM, bss_nu++,
2319 dtap_attach_req, sizeof(dtap_attach_req));
2320
2321 dump_peers(stdout, 0, 0, &gbcfg);
2322
2323 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2324 foreign_bss_tlli, &rai_bss, cell_id,
2325 GPRS_SAPI_GMM, bss_nu++,
2326 dtap_identity_resp, sizeof(dtap_identity_resp));
2327
2328 dump_peers(stdout, 0, 0, &gbcfg);
2329
2330 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2331 random_sgsn_tlli, 0, NULL, 0,
2332 GPRS_SAPI_GMM, sgsn_nu++,
2333 dtap_identity_req, sizeof(dtap_identity_req));
2334
2335 dump_peers(stdout, 0, 0, &gbcfg);
2336
2337 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2338 foreign_bss_tlli, &rai_bss, cell_id,
2339 GPRS_SAPI_GMM, bss_nu++,
2340 dtap_identity_resp, sizeof(dtap_identity_resp));
2341
2342 dump_peers(stdout, 0, 0, &gbcfg);
2343
2344 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2345 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2346 GPRS_SAPI_GMM, sgsn_nu++,
2347 dtap_attach_acc, sizeof(dtap_attach_acc));
2348
2349 dump_peers(stdout, 0, 0, &gbcfg);
2350
2351 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2352 OSMO_ASSERT(tlli_info);
2353 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2354 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2355 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2356 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2357 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2358 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2359 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2360 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2361 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2362 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2363
2364 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2365 local_bss_tlli, &rai_bss, cell_id,
2366 GPRS_SAPI_GMM, bss_nu++,
2367 dtap_attach_complete, sizeof(dtap_attach_complete));
2368
2369 dump_peers(stdout, 0, 0, &gbcfg);
2370
2371 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2372 OSMO_ASSERT(tlli_info);
2373 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2374 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2375 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2376 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2377 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2378 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2379 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2380 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2381
2382 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2383 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2384 GPRS_SAPI_GMM, sgsn_nu++,
2385 dtap_gmm_information, sizeof(dtap_gmm_information));
2386
2387 dump_peers(stdout, 0, 0, &gbcfg);
2388
2389 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2390 OSMO_ASSERT(tlli_info);
2391 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2392 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2393 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2394 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2395
2396 /* Non-DTAP */
2397 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2398 local_bss_tlli, &rai_bss, cell_id,
2399 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2400
2401 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2402 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2403 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2404
2405 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2406 local_bss_tlli, &rai_bss, cell_id,
2407 llc_ui_ll11_dns_query_ul,
2408 sizeof(llc_ui_ll11_dns_query_ul));
2409
2410 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2411 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2412 llc_ui_ll11_dns_resp_dl,
2413 sizeof(llc_ui_ll11_dns_resp_dl));
2414
2415 dump_peers(stdout, 0, 0, &gbcfg);
2416
2417 /* Other messages */
2418 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2419 local_bss_tlli, 1, 12);
2420
2421 dump_peers(stdout, 0, 0, &gbcfg);
2422
2423 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2424 local_sgsn_tlli, 1, 12);
2425
2426 dump_peers(stdout, 0, 0, &gbcfg);
2427
2428 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2429
2430 dump_peers(stdout, 0, 0, &gbcfg);
2431
2432 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2433
2434 dump_peers(stdout, 0, 0, &gbcfg);
2435
2436 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2437
2438 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2439 foreign_bss_tlli2, &rai_unknown, cell_id,
2440 GPRS_SAPI_GMM, bss_nu++,
2441 dtap_attach_req, sizeof(dtap_attach_req));
2442
2443 dump_peers(stdout, 0, 0, &gbcfg);
2444
2445 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2446 foreign_bss_tlli2, &rai_bss, cell_id,
2447 GPRS_SAPI_GMM, bss_nu++,
2448 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2449
2450 dump_peers(stdout, 0, 0, &gbcfg);
2451
2452 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2453 random_sgsn_tlli2, 0, NULL, 0,
2454 GPRS_SAPI_GMM, sgsn_nu++,
2455 dtap_identity_req, sizeof(dtap_identity_req));
2456
2457 dump_peers(stdout, 0, 0, &gbcfg);
2458
2459 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2460 foreign_bss_tlli2, &rai_bss, cell_id,
2461 GPRS_SAPI_GMM, bss_nu++,
2462 dtap_identity_resp, sizeof(dtap_identity_resp));
2463
2464 dump_peers(stdout, 0, 0, &gbcfg);
2465
2466 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2467 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2468 GPRS_SAPI_GMM, sgsn_nu++,
2469 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2470
2471 dump_peers(stdout, 0, 0, &gbcfg);
2472
2473 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2474 OSMO_ASSERT(tlli_info);
2475 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2476 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2477 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2478 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2479 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2480 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2481 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2482 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2483 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2484 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2485
2486 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2487 local_bss_tlli2, &rai_bss, cell_id,
2488 GPRS_SAPI_GMM, bss_nu++,
2489 dtap_attach_complete, sizeof(dtap_attach_complete));
2490
2491 dump_peers(stdout, 0, 0, &gbcfg);
2492
2493 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2494 OSMO_ASSERT(tlli_info);
2495 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2496 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2497 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2498 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2499 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2500 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2501 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2502 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2503
2504 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2505 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2506 GPRS_SAPI_GMM, sgsn_nu++,
2507 dtap_gmm_information, sizeof(dtap_gmm_information));
2508
2509 dump_peers(stdout, 0, 0, &gbcfg);
2510
2511 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2512 OSMO_ASSERT(tlli_info);
2513 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2514 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2515 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2516 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2517
2518 /* Non-DTAP */
2519 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2520 local_bss_tlli2, &rai_bss, cell_id,
2521 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2522
2523 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2524 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2525 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2526
2527 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2528 local_bss_tlli2, &rai_bss, cell_id,
2529 llc_ui_ll11_dns_query_ul,
2530 sizeof(llc_ui_ll11_dns_query_ul));
2531
2532 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2533 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2534 llc_ui_ll11_dns_resp_dl,
2535 sizeof(llc_ui_ll11_dns_resp_dl));
2536
2537 dump_peers(stdout, 0, 0, &gbcfg);
2538
2539 /* Other messages */
2540 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2541 local_bss_tlli2, 1, 12);
2542
2543 dump_peers(stdout, 0, 0, &gbcfg);
2544
2545 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2546 local_sgsn_tlli2, 1, 12);
2547
2548 dump_peers(stdout, 0, 0, &gbcfg);
2549
2550 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2551
2552 dump_peers(stdout, 0, 0, &gbcfg);
2553
2554 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2555
2556 dump_peers(stdout, 0, 0, &gbcfg);
2557
2558 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2559
2560 /* Detach */
2561 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2562 local_bss_tlli, &rai_bss, cell_id,
2563 GPRS_SAPI_GMM, bss_nu++,
2564 dtap_detach_req, sizeof(dtap_detach_req));
2565
2566 dump_peers(stdout, 0, 0, &gbcfg);
2567
2568 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2569 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2570 GPRS_SAPI_GMM, sgsn_nu++,
2571 dtap_detach_acc, sizeof(dtap_detach_acc));
2572
2573 dump_peers(stdout, 0, 0, &gbcfg);
2574
2575 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2576
2577 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2578 local_bss_tlli2, &rai_bss, cell_id,
2579 GPRS_SAPI_GMM, bss_nu++,
2580 dtap_detach_req, sizeof(dtap_detach_req));
2581
2582 dump_peers(stdout, 0, 0, &gbcfg);
2583
2584 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2585 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2586 GPRS_SAPI_GMM, sgsn_nu++,
2587 dtap_detach_acc, sizeof(dtap_detach_acc));
2588
2589 dump_peers(stdout, 0, 0, &gbcfg);
2590
2591 dump_global(stdout, 0);
2592
2593 gbprox_reset(&gbcfg);
2594 gprs_ns_destroy(nsi);
2595 nsi = NULL;
2596}
2597
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002598static void test_gbproxy_keep_info()
2599{
2600 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2601 struct sockaddr_in bss_peer[1] = {{0},};
2602 struct sockaddr_in sgsn_peer= {0};
2603 struct gprs_ra_id rai_bss =
2604 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2605 uint16_t cell_id = 0x1234;
2606
2607 const uint32_t ptmsi = 0xefe2b700;
2608 const uint32_t local_tlli = 0xefe2b700;
2609 const uint32_t foreign_tlli = 0xafe2b700;
2610
2611 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002612 struct gbproxy_tlli_info *tlli_info, *tlli_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002613 struct gbproxy_peer *peer;
2614 unsigned bss_nu = 0;
2615 unsigned sgsn_nu = 0;
2616
2617 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
2618
2619 bssgp_nsi = nsi;
2620 gbcfg.nsi = bssgp_nsi;
2621 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2622 gbcfg.patch_ptmsi = 0;
2623 gbcfg.acquire_imsi = 1;
2624 gbcfg.bss_ptmsi_state = 0;
2625 gbcfg.sgsn_tlli_state = 1;
2626 gbcfg.core_mcc = 0;
2627 gbcfg.core_mnc = 0;
2628 gbcfg.core_apn = NULL;
2629 gbcfg.core_apn_size = 0;
2630 gbcfg.route_to_sgsn2 = 0;
2631 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002632 gbcfg.keep_tlli_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002633
2634 configure_sgsn_peer(&sgsn_peer);
2635 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2636
2637 printf("=== %s ===\n", __func__);
2638 printf("--- Initialise SGSN ---\n\n");
2639
2640 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2641
2642 printf("--- Initialise BSS 1 ---\n\n");
2643
2644 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2645 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2646
2647 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2648 OSMO_ASSERT(peer != NULL);
2649
2650 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2651
2652 gprs_dump_nsi(nsi);
2653 dump_global(stdout, 0);
2654 dump_peers(stdout, 0, 0, &gbcfg);
2655
2656 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2657
2658 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2659 foreign_tlli, &rai_bss, cell_id,
2660 GPRS_SAPI_GMM, bss_nu++,
2661 dtap_attach_req, sizeof(dtap_attach_req));
2662
2663 dump_peers(stdout, 0, 0, &gbcfg);
2664
2665 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2666 OSMO_ASSERT(tlli_info);
2667 OSMO_ASSERT(tlli_info->imsi_len == 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002668 OSMO_ASSERT(!tlli_info->is_deregistered);
2669 OSMO_ASSERT(tlli_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002670
2671 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2672 foreign_tlli, &rai_bss, cell_id,
2673 GPRS_SAPI_GMM, bss_nu++,
2674 dtap_identity_resp, sizeof(dtap_identity_resp));
2675
2676 dump_peers(stdout, 0, 0, &gbcfg);
2677
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002678 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2679 OSMO_ASSERT(tlli_info);
2680 OSMO_ASSERT(tlli_info->imsi_len > 0);
2681 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
2682
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002683 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2684 foreign_tlli, 0, NULL, 0,
2685 GPRS_SAPI_GMM, sgsn_nu++,
2686 dtap_identity_req, sizeof(dtap_identity_req));
2687
2688 dump_peers(stdout, 0, 0, &gbcfg);
2689
2690 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2691 foreign_tlli, &rai_bss, cell_id,
2692 GPRS_SAPI_GMM, bss_nu++,
2693 dtap_identity_resp, sizeof(dtap_identity_resp));
2694
2695 dump_peers(stdout, 0, 0, &gbcfg);
2696
2697 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2698 OSMO_ASSERT(tlli_info);
2699 OSMO_ASSERT(tlli_info->imsi_len > 0);
2700 OSMO_ASSERT(gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi)));
2701
2702 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2703 foreign_tlli, 1, imsi, sizeof(imsi),
2704 GPRS_SAPI_GMM, sgsn_nu++,
2705 dtap_attach_acc, sizeof(dtap_attach_acc));
2706
2707 dump_peers(stdout, 0, 0, &gbcfg);
2708
2709 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2710 local_tlli, &rai_bss, cell_id,
2711 GPRS_SAPI_GMM, bss_nu++,
2712 dtap_attach_complete, sizeof(dtap_attach_complete));
2713
2714 dump_peers(stdout, 0, 0, &gbcfg);
2715
2716 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2717 local_tlli, 1, imsi, sizeof(imsi),
2718 GPRS_SAPI_GMM, sgsn_nu++,
2719 dtap_gmm_information, sizeof(dtap_gmm_information));
2720
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
2723 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2724 OSMO_ASSERT(tlli_info);
2725
2726 /* Detach (MO) */
2727 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2728 local_tlli, &rai_bss, cell_id,
2729 GPRS_SAPI_GMM, bss_nu++,
2730 dtap_detach_req, sizeof(dtap_detach_req));
2731
2732 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2733 OSMO_ASSERT(tlli_info);
2734
2735 dump_peers(stdout, 0, 0, &gbcfg);
2736
2737 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2738 local_tlli, 1, imsi, sizeof(imsi),
2739 GPRS_SAPI_GMM, sgsn_nu++,
2740 dtap_detach_acc, sizeof(dtap_detach_acc));
2741
2742 dump_peers(stdout, 0, 0, &gbcfg);
2743
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002744 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
2745 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2746 OSMO_ASSERT(tlli_info);
2747 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002748
2749 /* Re-Attach */
2750 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2751 foreign_tlli, &rai_bss, cell_id,
2752 GPRS_SAPI_GMM, bss_nu++,
2753 dtap_attach_req3, sizeof(dtap_attach_req3));
2754
2755 dump_peers(stdout, 0, 0, &gbcfg);
2756
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002757 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2758 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2759 OSMO_ASSERT(tlli_info);
2760 OSMO_ASSERT(tlli_info == tlli_info2);
2761 OSMO_ASSERT(tlli_info->imsi_len != 0);
2762 OSMO_ASSERT(!tlli_info->is_deregistered);
2763 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
2764
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002765 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2766 foreign_tlli, 1, imsi, sizeof(imsi),
2767 GPRS_SAPI_GMM, sgsn_nu++,
2768 dtap_attach_acc, sizeof(dtap_attach_acc));
2769
2770 dump_peers(stdout, 0, 0, &gbcfg);
2771
2772 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2773 local_tlli, &rai_bss, cell_id,
2774 GPRS_SAPI_GMM, bss_nu++,
2775 dtap_attach_complete, sizeof(dtap_attach_complete));
2776
2777 dump_peers(stdout, 0, 0, &gbcfg);
2778
2779 /* Detach (MT) */
2780 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
2781 local_tlli, 1, imsi, sizeof(imsi),
2782 GPRS_SAPI_GMM, sgsn_nu++,
2783 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
2784
2785 dump_peers(stdout, 0, 0, &gbcfg);
2786
2787 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2788 OSMO_ASSERT(tlli_info);
2789
2790 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2791 local_tlli, &rai_bss, cell_id,
2792 GPRS_SAPI_GMM, bss_nu++,
2793 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2794
2795 dump_peers(stdout, 0, 0, &gbcfg);
2796
2797 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002798 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2799 OSMO_ASSERT(tlli_info);
2800 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002801
2802 /* Re-Attach */
2803 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2804 foreign_tlli, &rai_bss, cell_id,
2805 GPRS_SAPI_GMM, bss_nu++,
2806 dtap_attach_req3, sizeof(dtap_attach_req3));
2807
2808 dump_peers(stdout, 0, 0, &gbcfg);
2809
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002810 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2811 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2812 OSMO_ASSERT(tlli_info);
2813 OSMO_ASSERT(tlli_info == tlli_info2);
2814 OSMO_ASSERT(tlli_info->imsi_len != 0);
2815 OSMO_ASSERT(!tlli_info->is_deregistered);
2816 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
2817
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002818 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2819 foreign_tlli, 1, imsi, sizeof(imsi),
2820 GPRS_SAPI_GMM, sgsn_nu++,
2821 dtap_attach_acc, sizeof(dtap_attach_acc));
2822
2823 dump_peers(stdout, 0, 0, &gbcfg);
2824
2825 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2826 local_tlli, &rai_bss, cell_id,
2827 GPRS_SAPI_GMM, bss_nu++,
2828 dtap_attach_complete, sizeof(dtap_attach_complete));
2829
2830 dump_peers(stdout, 0, 0, &gbcfg);
2831
2832 /* Detach (MT) */
2833 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
2834 local_tlli, 1, imsi, sizeof(imsi),
2835 GPRS_SAPI_GMM, sgsn_nu++,
2836 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
2837
2838 dump_peers(stdout, 0, 0, &gbcfg);
2839
2840 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2841 OSMO_ASSERT(tlli_info);
2842
2843 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2844 local_tlli, &rai_bss, cell_id,
2845 GPRS_SAPI_GMM, bss_nu++,
2846 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2847
2848 dump_peers(stdout, 0, 0, &gbcfg);
2849
2850 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002851 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2852 OSMO_ASSERT(tlli_info);
2853 OSMO_ASSERT(tlli_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002854
2855 /* Re-Attach */
2856 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2857 foreign_tlli, &rai_bss, cell_id,
2858 GPRS_SAPI_GMM, bss_nu++,
2859 dtap_attach_req3, sizeof(dtap_attach_req3));
2860
2861 dump_peers(stdout, 0, 0, &gbcfg);
2862
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002863 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2864 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2865 OSMO_ASSERT(tlli_info);
2866 OSMO_ASSERT(tlli_info == tlli_info2);
2867 OSMO_ASSERT(tlli_info->imsi_len != 0);
2868 OSMO_ASSERT(!tlli_info->is_deregistered);
2869 OSMO_ASSERT(!tlli_info->imsi_acq_pending);
2870
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002871 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2872 foreign_tlli, 1, imsi, sizeof(imsi),
2873 GPRS_SAPI_GMM, sgsn_nu++,
2874 dtap_attach_acc, sizeof(dtap_attach_acc));
2875
2876 dump_peers(stdout, 0, 0, &gbcfg);
2877
2878 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2879 local_tlli, &rai_bss, cell_id,
2880 GPRS_SAPI_GMM, bss_nu++,
2881 dtap_attach_complete, sizeof(dtap_attach_complete));
2882
2883 dump_peers(stdout, 0, 0, &gbcfg);
2884
2885 /* RA update procedure (reject -> Detach) */
2886 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2887 local_tlli, &rai_bss, 0x7080,
2888 GPRS_SAPI_GMM, bss_nu++,
2889 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2890
2891 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
2892 local_tlli, 1, imsi, sizeof(imsi),
2893 GPRS_SAPI_GMM, sgsn_nu++,
2894 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
2895
2896 dump_peers(stdout, 0, 0, &gbcfg);
2897
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002898 /* TODO: This should have de-registered the TLLI which it did not. Add
2899 * assertions when this is fixed.
2900 */
2901
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002902 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
2903 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2904 foreign_tlli, &rai_bss, cell_id,
2905 GPRS_SAPI_GMM, bss_nu++,
2906 dtap_attach_req, sizeof(dtap_attach_req));
2907
2908 dump_peers(stdout, 0, 0, &gbcfg);
2909
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002910 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2911 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2912 OSMO_ASSERT(tlli_info);
2913 OSMO_ASSERT(tlli_info != tlli_info2);
2914 OSMO_ASSERT(tlli_info->imsi_len == 0);
2915 OSMO_ASSERT(!tlli_info->is_deregistered);
2916 OSMO_ASSERT(tlli_info->imsi_acq_pending);
2917
2918 /* This wouldn't happen in reality, since the Attach Request hadn't
2919 * been forwarded to the SGSN.
2920 * TODO: Add the missing messages.
2921 */
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002922 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2923 foreign_tlli, 1, imsi, sizeof(imsi),
2924 GPRS_SAPI_GMM, sgsn_nu++,
2925 dtap_attach_acc, sizeof(dtap_attach_acc));
2926
2927 dump_peers(stdout, 0, 0, &gbcfg);
2928
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002929 tlli_info2 = gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi));
2930 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2931 OSMO_ASSERT(tlli_info);
2932 OSMO_ASSERT(tlli_info == tlli_info2);
2933 OSMO_ASSERT(tlli_info->imsi_len >= 0);
2934 OSMO_ASSERT(!tlli_info->is_deregistered);
2935 OSMO_ASSERT(tlli_info->imsi_acq_pending);
2936
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002937 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2938 local_tlli, &rai_bss, cell_id,
2939 GPRS_SAPI_GMM, bss_nu++,
2940 dtap_attach_complete, sizeof(dtap_attach_complete));
2941
2942 dump_peers(stdout, 0, 0, &gbcfg);
2943
2944 /* Detach (MT) */
2945 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
2946 local_tlli, 1, imsi, sizeof(imsi),
2947 GPRS_SAPI_GMM, sgsn_nu++,
2948 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
2949
2950 dump_peers(stdout, 0, 0, &gbcfg);
2951
2952 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2953 OSMO_ASSERT(tlli_info);
2954
2955 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2956 local_tlli, &rai_bss, cell_id,
2957 GPRS_SAPI_GMM, bss_nu++,
2958 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2959
2960 dump_peers(stdout, 0, 0, &gbcfg);
2961
Jacob Erlbeck7430da62014-09-12 15:09:56 +02002962 /* TODO: There is one entry with this TLLI left (since there were 2
2963 * before the detach precedure started. Add assertions when
2964 * this is fixed.
2965 */
2966
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002967 dump_global(stdout, 0);
2968
2969 gbprox_reset(&gbcfg);
2970 gprs_ns_destroy(nsi);
2971 nsi = NULL;
2972}
2973
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002974/* TODO: Move tlv testing to libosmocore */
2975int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2976int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2977 uint8_t **value);
2978int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2979 size_t *value_len);
2980int lv_shift(uint8_t **data, size_t *data_len,
2981 uint8_t **value, size_t *value_len);
2982
2983static void check_tlv_match(uint8_t **data, size_t *data_len,
2984 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2985{
2986 uint8_t *value;
2987 size_t value_len;
2988 int rc;
2989
2990 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2991 OSMO_ASSERT(rc == 0);
2992
2993 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002994 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002995 OSMO_ASSERT(value_len == exp_len);
2996 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2997}
2998
2999static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3000 uint8_t tag, size_t len, const uint8_t *exp_val)
3001{
3002 uint8_t *value;
3003 int rc;
3004
3005 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3006 OSMO_ASSERT(rc == 0);
3007
3008 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003009 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003010 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3011}
3012
3013static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3014 size_t len, const uint8_t *exp_val)
3015{
3016 uint8_t *value;
3017 int rc;
3018
3019 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003020 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003021 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3022}
3023
3024static void check_lv_shift(uint8_t **data, size_t *data_len,
3025 size_t exp_len, const uint8_t *exp_val)
3026{
3027 uint8_t *value;
3028 size_t value_len;
3029 int rc;
3030
3031 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003032 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003033 OSMO_ASSERT(value_len == exp_len);
3034 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3035}
3036
3037static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3038 const uint8_t *test_data)
3039{
3040 uint8_t buf[300] = {0};
3041
3042 uint8_t *unchanged_ptr = buf - 1;
3043 size_t unchanged_len = 0xdead;
3044 size_t tmp_data_len = data_len;
3045 uint8_t *value = unchanged_ptr;
3046 size_t value_len = unchanged_len;
3047 uint8_t *data = buf;
3048
3049 OSMO_ASSERT(data_len <= sizeof(buf));
3050
3051 tlv_put(data, tag, len, test_data);
3052 if (data_len < len + 2) {
3053 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3054 tag, &value, &value_len));
3055 OSMO_ASSERT(tmp_data_len == 0);
3056 OSMO_ASSERT(data == buf + data_len);
3057 OSMO_ASSERT(value == unchanged_ptr);
3058 OSMO_ASSERT(value_len == unchanged_len);
3059 } else {
3060 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3061 tag, &value, &value_len));
3062 OSMO_ASSERT(value != unchanged_ptr);
3063 OSMO_ASSERT(value_len != unchanged_len);
3064 }
3065}
3066
3067static void check_tv_fixed_match_data_len(size_t data_len,
3068 uint8_t tag, size_t len,
3069 const uint8_t *test_data)
3070{
3071 uint8_t buf[300] = {0};
3072
3073 uint8_t *unchanged_ptr = buf - 1;
3074 size_t tmp_data_len = data_len;
3075 uint8_t *value = unchanged_ptr;
3076 uint8_t *data = buf;
3077
3078 OSMO_ASSERT(data_len <= sizeof(buf));
3079
3080 tv_fixed_put(data, tag, len, test_data);
3081
3082 if (data_len < len + 1) {
3083 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3084 tag, len, &value));
3085 OSMO_ASSERT(tmp_data_len == 0);
3086 OSMO_ASSERT(data == buf + data_len);
3087 OSMO_ASSERT(value == unchanged_ptr);
3088 } else {
3089 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3090 tag, len, &value));
3091 OSMO_ASSERT(value != unchanged_ptr);
3092 }
3093}
3094
3095static void check_v_fixed_shift_data_len(size_t data_len,
3096 size_t len, const uint8_t *test_data)
3097{
3098 uint8_t buf[300] = {0};
3099
3100 uint8_t *unchanged_ptr = buf - 1;
3101 size_t tmp_data_len = data_len;
3102 uint8_t *value = unchanged_ptr;
3103 uint8_t *data = buf;
3104
3105 OSMO_ASSERT(data_len <= sizeof(buf));
3106
3107 memcpy(data, test_data, len);
3108
3109 if (data_len < len) {
3110 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3111 len, &value));
3112 OSMO_ASSERT(tmp_data_len == 0);
3113 OSMO_ASSERT(data == buf + data_len);
3114 OSMO_ASSERT(value == unchanged_ptr);
3115 } else {
3116 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3117 len, &value));
3118 OSMO_ASSERT(value != unchanged_ptr);
3119 }
3120}
3121
3122static void check_lv_shift_data_len(size_t data_len,
3123 size_t len, const uint8_t *test_data)
3124{
3125 uint8_t buf[300] = {0};
3126
3127 uint8_t *unchanged_ptr = buf - 1;
3128 size_t unchanged_len = 0xdead;
3129 size_t tmp_data_len = data_len;
3130 uint8_t *value = unchanged_ptr;
3131 size_t value_len = unchanged_len;
3132 uint8_t *data = buf;
3133
3134 lv_put(data, len, test_data);
3135 if (data_len < len + 1) {
3136 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3137 &value, &value_len));
3138 OSMO_ASSERT(tmp_data_len == 0);
3139 OSMO_ASSERT(data == buf + data_len);
3140 OSMO_ASSERT(value == unchanged_ptr);
3141 OSMO_ASSERT(value_len == unchanged_len);
3142 } else {
3143 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3144 &value, &value_len));
3145 OSMO_ASSERT(value != unchanged_ptr);
3146 OSMO_ASSERT(value_len != unchanged_len);
3147 }
3148}
3149
3150static void test_tlv_shift_functions()
3151{
3152 uint8_t test_data[1024];
3153 uint8_t buf[1024];
3154 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003155 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003156 uint8_t *data;
3157 size_t data_len;
3158 const uint8_t tag = 0x1a;
3159
3160 printf("Test shift functions\n");
3161
3162 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3163 test_data[i] = (uint8_t)i;
3164
3165 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003166 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003167
3168 memset(buf, 0xee, sizeof(buf));
3169 data_end = data = buf;
3170
3171 for (i = 0; i < iterations; i++) {
3172 data_end = tlv_put(data_end, tag, len, test_data);
3173 data_end = tv_fixed_put(data_end, tag, len, test_data);
3174 /* v_fixed_put */
3175 memcpy(data_end, test_data, len);
3176 data_end += len;
3177 data_end = lv_put(data_end, len, test_data);
3178 }
3179
3180 data_len = data_end - data;
3181 OSMO_ASSERT(data_len <= sizeof(buf));
3182
3183 for (i = 0; i < iterations; i++) {
3184 check_tlv_match(&data, &data_len, tag, len, test_data);
3185 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3186 check_v_fixed_shift(&data, &data_len, len, test_data);
3187 check_lv_shift(&data, &data_len, len, test_data);
3188 }
3189
3190 OSMO_ASSERT(data == data_end);
3191
3192 /* Test at end of data */
3193
3194 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3195 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3196 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3197 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3198
3199 /* Test invalid data_len */
3200 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3201 check_tlv_match_data_len(data_len, tag, len, test_data);
3202 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3203 check_v_fixed_shift_data_len(data_len, len, test_data);
3204 check_lv_shift_data_len(data_len, len, test_data);
3205 }
3206 }
3207}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003208
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003209struct gbproxy_tlli_info *register_tlli(
3210 struct gbproxy_peer *peer, uint32_t tlli,
3211 const uint8_t *imsi, size_t imsi_len, time_t now)
3212{
3213 struct gbproxy_tlli_info *tlli_info;
3214 int enable_patching = -1;
3215 int tlli_already_known = 0;
3216
3217 /* Check, whether the IMSI matches */
3218 if (gprs_is_mi_imsi(imsi, imsi_len)) {
3219 enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
3220 if (enable_patching < 0)
3221 return NULL;
3222 }
3223
3224 tlli_info = gbproxy_find_tlli(peer, tlli);
3225
3226 if (!tlli_info) {
3227 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, imsi_len);
3228
3229 if (tlli_info) {
3230 /* TLLI has changed somehow, adjust it */
3231 LOGP(DGPRS, LOGL_INFO,
3232 "The TLLI has changed from %08x to %08x\n",
3233 tlli_info->tlli.current, tlli);
3234 tlli_info->tlli.current = tlli;
3235 }
3236 }
3237
3238 if (!tlli_info) {
3239 tlli_info = gbproxy_tlli_info_alloc(peer);
3240 tlli_info->tlli.current = tlli;
3241 } else {
3242 gbproxy_detach_tlli_info(peer, tlli_info);
3243 tlli_already_known = 1;
3244 }
3245
3246 OSMO_ASSERT(tlli_info != NULL);
3247
3248 if (!tlli_already_known)
3249 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3250
3251 gbproxy_attach_tlli_info(peer, now, tlli_info);
3252 gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
3253
3254 if (enable_patching >= 0)
3255 tlli_info->enable_patching = enable_patching;
3256
3257 return tlli_info;
3258}
3259
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003260static void test_gbproxy_tlli_expire(void)
3261{
3262 struct gbproxy_config cfg = {0};
3263 struct gbproxy_peer *peer;
3264 const char *err_msg = NULL;
3265 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3266 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003267 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003268 const uint32_t tlli1 = 1234 | 0xc0000000;
3269 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003270 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003271 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003272 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003273
3274 printf("Test TLLI info expiry\n\n");
3275
3276 gbproxy_init_config(&cfg);
3277
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003278 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003279 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3280 err_msg);
3281 OSMO_ASSERT(err_msg == NULL);
3282 }
3283
3284 {
3285 struct gbproxy_tlli_info *tlli_info;
3286
3287 printf("Test TLLI replacement:\n");
3288
3289 cfg.tlli_max_len = 0;
3290 cfg.tlli_max_age = 0;
3291 peer = gbproxy_peer_alloc(&cfg, 20);
3292 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3293
3294 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003295 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003296 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003297 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003298 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003299 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3300
3301 /* replace the old entry */
3302 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003303 tlli_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003304 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003305 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003306 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003307 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3308
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003309 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003310
3311 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003312 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003313 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003314 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003315 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003316 OSMO_ASSERT(!tlli_info);
3317
3318 printf("\n");
3319
3320 gbproxy_peer_free(peer);
3321 }
3322
3323 {
3324 struct gbproxy_tlli_info *tlli_info;
3325
3326 printf("Test IMSI replacement:\n");
3327
3328 cfg.tlli_max_len = 0;
3329 cfg.tlli_max_age = 0;
3330 peer = gbproxy_peer_alloc(&cfg, 20);
3331 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3332
3333 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003334 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003335 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003336 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003337 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003338 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3339
3340 /* try to replace the old entry */
3341 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003342 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003343 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003344 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003345 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003346 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3347
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003348 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003349
3350 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003351 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003352 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003353 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003354 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003355 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003356
3357 printf("\n");
3358
3359 gbproxy_peer_free(peer);
3360 }
3361
3362 {
3363 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003364 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003365
3366 printf("Test TLLI expiry, max_len == 1:\n");
3367
3368 cfg.tlli_max_len = 1;
3369 cfg.tlli_max_age = 0;
3370 peer = gbproxy_peer_alloc(&cfg, 20);
3371 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3372
3373 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003374 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003375 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3376
3377 /* replace the old entry */
3378 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003379 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003380 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3381
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003382 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003383 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003384 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3385
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003386 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003387
3388 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003389 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003390 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003391 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003392 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003393 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003394
3395 printf("\n");
3396
3397 gbproxy_peer_free(peer);
3398 }
3399
3400 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003401 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003402 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003403
3404 printf("Test TLLI expiry, max_age == 1:\n");
3405
3406 cfg.tlli_max_len = 0;
3407 cfg.tlli_max_age = 1;
3408 peer = gbproxy_peer_alloc(&cfg, 20);
3409 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3410
3411 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003412 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003413 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3414
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003415 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003416 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003417 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003418 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3419
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003420 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003421 OSMO_ASSERT(num_removed == 1);
3422 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3423
3424 dump_peers(stdout, 2, now + 2, &cfg);
3425
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003426 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003427 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003428 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003429 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003430 OSMO_ASSERT(tlli_info);
3431 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
3432
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003433 printf("\n");
3434
3435 gbproxy_peer_free(peer);
3436 }
3437
3438 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003439 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003440 int num_removed;
3441
3442 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
3443
3444 cfg.tlli_max_len = 0;
3445 cfg.tlli_max_age = 1;
3446 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003447 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3448
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003449 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003450 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003451 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3452
3453 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003454 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003455 now + 1);
3456 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3457
3458 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003459 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003460 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003461 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
3462
3463 dump_peers(stdout, 2, now + 2, &cfg);
3464
3465 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003466 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003467 OSMO_ASSERT(num_removed == 2);
3468 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3469
3470 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003471
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003472 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003473 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003474 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003475 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003476 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003477 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003478 OSMO_ASSERT(tlli_info);
3479 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
3480
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003481 printf("\n");
3482
3483 gbproxy_peer_free(peer);
3484 }
3485}
3486
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003487static void test_gbproxy_imsi_matching(void)
3488{
3489 struct gbproxy_config cfg = {0};
3490 struct gbproxy_peer *peer;
3491 const char *err_msg = NULL;
3492 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3493 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3494 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3495 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3496 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3497 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3498 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3499 const char *filter_re1 = ".*";
3500 const char *filter_re2 = "^1234";
3501 const char *filter_re3 = "^4321";
3502 const char *filter_re4_bad = "^12[";
3503
3504 printf("=== Test IMSI/TMSI matching ===\n\n");
3505
3506 gbproxy_init_config(&cfg);
3507 OSMO_ASSERT(cfg.check_imsi == 0);
3508
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003509 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003510 OSMO_ASSERT(cfg.check_imsi == 1);
3511
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003512 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003513 OSMO_ASSERT(cfg.check_imsi == 1);
3514
3515 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003516 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003517 OSMO_ASSERT(err_msg != NULL);
3518 OSMO_ASSERT(cfg.check_imsi == 0);
3519
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003520 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003521 OSMO_ASSERT(cfg.check_imsi == 1);
3522
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003523 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003524 OSMO_ASSERT(cfg.check_imsi == 0);
3525
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003526 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003527 OSMO_ASSERT(cfg.check_imsi == 1);
3528
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003529 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003530 OSMO_ASSERT(cfg.check_imsi == 0);
3531
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003532 peer = gbproxy_peer_alloc(&cfg, 20);
3533
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003534 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003535 OSMO_ASSERT(cfg.check_imsi == 1);
3536
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003537 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3538 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003539 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003540 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003541 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003542 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3543 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3544 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3545 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3546 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003547
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003548 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003549 OSMO_ASSERT(cfg.check_imsi == 1);
3550
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003551 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3552 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3553 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3554 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3555 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3556 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3557 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003558
3559 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3560
3561 gbproxy_peer_free(peer);
3562}
3563
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003564static struct log_info_cat gprs_categories[] = {
3565 [DGPRS] = {
3566 .name = "DGPRS",
3567 .description = "GPRS Packet Service",
3568 .enabled = 1, .loglevel = LOGL_DEBUG,
3569 },
3570 [DNS] = {
3571 .name = "DNS",
3572 .description = "GPRS Network Service (NS)",
3573 .enabled = 1, .loglevel = LOGL_INFO,
3574 },
3575 [DBSSGP] = {
3576 .name = "DBSSGP",
3577 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3578 .enabled = 1, .loglevel = LOGL_DEBUG,
3579 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003580};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003581
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003582static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003583 .cat = gprs_categories,
3584 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003585};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003586
3587int main(int argc, char **argv)
3588{
3589 osmo_init_logging(&info);
3590 log_set_use_color(osmo_stderr_target, 0);
3591 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003592 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003593
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003594 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003595 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3596 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003597
3598 rate_ctr_init(NULL);
3599
3600 setlinebuf(stdout);
3601
3602 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003603 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003604 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003605 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003606 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003607 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003608 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003609 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003610 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003611 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003612 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003613 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003614 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003615
3616 exit(EXIT_SUCCESS);
3617}