blob: 06fea69d288d695f1ae198f619d6d9b17372874c [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 Erlbeck5f4ef322014-08-22 17:10:01 +0200160 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200161 if (rc < 0)
162 return rc;
163 }
164 }
165
166 return 0;
167}
168
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200169const uint8_t *convert_ra(struct gprs_ra_id *raid)
170{
171 static uint8_t buf[6];
172 gsm48_construct_ra(buf, raid);
173 return buf;
174}
175
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200176/* DTAP - Attach Request */
177static const unsigned char dtap_attach_req[] = {
178 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
179 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
180 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
181 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
182 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
183 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200184};
185
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200186/* DTAP - Attach Request (invalid RAI) */
187static const unsigned char dtap_attach_req2[] = {
188 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
189 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
190 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
191 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
192 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
193 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
194};
195
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200196/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
197static const unsigned char dtap_attach_req3[] = {
198 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
199 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
200 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
201 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
202 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
203 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
204};
205
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200206/* DTAP - Identity Request */
207static const unsigned char dtap_identity_req[] = {
208 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200209};
210
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200211/* DTAP - Identity Response */
212static const unsigned char dtap_identity_resp[] = {
213 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
214 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200215};
216
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200217/* DTAP - Identity Response, IMSI 2 */
218static const unsigned char dtap_identity2_resp[] = {
219 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
220 0x16, 0x17, 0x18
221};
222
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200223/* DTAP - Attach Accept */
224static const unsigned char dtap_attach_acc[] = {
225 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
226 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
227 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200228};
229
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200230/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200231static const unsigned char dtap_attach_acc2[] = {
232 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
233 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
234 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
235};
236
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200237/* DTAP - Attach Complete */
238static const unsigned char dtap_attach_complete[] = {
239 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200240};
241
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200242/* DTAP - GMM Information */
243static const unsigned char dtap_gmm_information[] = {
244 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200245};
246
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200247/* DTAP - Routing Area Update Request */
248static const unsigned char dtap_ra_upd_req[] = {
249 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
250 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
251 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
252 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
253 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
254 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
255 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200256};
257
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200258/* DTAP - Routing Area Update Accept */
259static const unsigned char dtap_ra_upd_acc[] = {
260 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
261 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
262 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200263};
264
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200265/* DTAP - Routing Area Update Accept, P-TMSI 2 */
266static const unsigned char dtap_ra_upd_acc2[] = {
267 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
268 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
269 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
270};
271
272/* DTAP - Routing Area Update Accept, P-TMSI 3 */
273static const unsigned char dtap_ra_upd_acc3[] = {
274 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
275 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
276 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
277};
278
279/* DTAP - Routing Area Update Complete */
280static const unsigned char dtap_ra_upd_complete[] = {
281 0x08, 0x0a
282};
283
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200284/* DTAP - Routing Area Update Reject */
285/* cause = 10 ("Implicitly detached"), force_standby = 0 */
286static const unsigned char dtap_ra_upd_rej[] = {
287 0x08, 0x0b, 0x0a, 0x00,
288};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200289
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200290/* DTAP - Activate PDP Context Request */
291static const unsigned char dtap_act_pdp_ctx_req[] = {
292 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200293 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
295 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
296 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
297 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200298 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200299};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200300
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200301/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200302/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200303static const unsigned char dtap_detach_po_req[] = {
304 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
305 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200306};
307
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200308/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200309/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200310static const unsigned char dtap_detach_req[] = {
311 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
312 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200313};
314
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200315/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200316static const unsigned char dtap_detach_acc[] = {
317 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200318};
319
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200320/* DTAP - Detach Request (MT) */
321/* normal detach, reattach required, implicitly detached */
322static const unsigned char dtap_mt_detach_rea_req[] = {
323 0x08, 0x05, 0x01, 0x25, 0x0a
324};
325
326/* DTAP - Detach Request (MT) */
327/* normal detach, reattach not required, implicitly detached */
328static const unsigned char dtap_mt_detach_req[] = {
329 0x08, 0x05, 0x02, 0x25, 0x0a
330};
331
332/* DTAP - Detach Accept (MT) */
333static const unsigned char dtap_mt_detach_acc[] = {
334 0x08, 0x06
335};
336
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200337/* GPRS-LLC - SAPI: LLGMM, U, XID */
338static const unsigned char llc_u_xid_ul[] = {
339 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
340 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
341};
342
343/* GPRS-LLC - SAPI: LLGMM, U, XID */
344static const unsigned char llc_u_xid_dl[] = {
345 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
346 0xe4, 0xa9, 0x1a, 0x9e
347};
348
349/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
350static const unsigned char llc_ui_ll11_dns_query_ul[] = {
351 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
352 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
353 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
354 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
355 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
356 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
357 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
358 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
359 0x8f, 0x07
360};
361
362/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
363static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
364 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
365 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
366 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
367 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
368 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
369 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
370 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
371 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
372 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
373 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
374 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
375 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
376 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
377 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
378 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
379 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
380 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
381 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
382 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
383 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
384 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
385 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
386 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
387 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
388 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
389 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
390};
391
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200392static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
393 struct sockaddr_in *peer, const unsigned char* data,
394 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200395
396static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
397 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
398{
399 /* GPRS Network Service, PDU type: NS_RESET,
400 */
401 unsigned char msg[12] = {
402 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
403 0x04, 0x82, 0x11, 0x22
404 };
405
406 msg[3] = cause;
407 msg[6] = nsvci / 256;
408 msg[7] = nsvci % 256;
409 msg[10] = nsei / 256;
410 msg[11] = nsei % 256;
411
412 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
413}
414
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200415static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
416 uint16_t nsvci, uint16_t nsei)
417{
418 /* GPRS Network Service, PDU type: NS_RESET_ACK,
419 */
420 unsigned char msg[9] = {
421 0x03, 0x01, 0x82, 0x11, 0x22,
422 0x04, 0x82, 0x11, 0x22
423 };
424
425 msg[3] = nsvci / 256;
426 msg[4] = nsvci % 256;
427 msg[7] = nsei / 256;
428 msg[8] = nsei % 256;
429
430 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
431}
432
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200433static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
434{
435 /* GPRS Network Service, PDU type: NS_ALIVE */
436 unsigned char msg[1] = {
437 0x0a
438 };
439
440 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
441}
442
443static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
444{
445 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
446 unsigned char msg[1] = {
447 0x0b
448 };
449
450 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
451}
452
453static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
454{
455 /* GPRS Network Service, PDU type: NS_UNBLOCK */
456 unsigned char msg[1] = {
457 0x06
458 };
459
460 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
461}
462
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200463static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
464{
465 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
466 unsigned char msg[1] = {
467 0x07
468 };
469
470 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
471}
472
473static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
474 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200475 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
476{
477 /* GPRS Network Service, PDU type: NS_UNITDATA */
478 unsigned char msg[4096] = {
479 0x00, 0x00, 0x00, 0x00
480 };
481
482 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
483
484 msg[2] = nsbvci / 256;
485 msg[3] = nsbvci % 256;
486 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
487
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200488 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200489}
490
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200491static void send_bssgp_ul_unitdata(
492 struct gprs_ns_inst *nsi, const char *text,
493 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
494 struct gprs_ra_id *raid, uint16_t cell_id,
495 const uint8_t *llc_msg, size_t llc_msg_size)
496{
497 /* GPRS Network Service, PDU type: NS_UNITDATA */
498 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
499 unsigned char msg[4096] = {
500 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
501 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
502 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
503 };
504
505 size_t bssgp_msg_size = 23 + llc_msg_size;
506
507 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
508
509 gsm48_construct_ra(msg + 10, raid);
510 msg[1] = (uint8_t)(tlli >> 24);
511 msg[2] = (uint8_t)(tlli >> 16);
512 msg[3] = (uint8_t)(tlli >> 8);
513 msg[4] = (uint8_t)(tlli >> 0);
514 msg[16] = cell_id / 256;
515 msg[17] = cell_id % 256;
516 msg[21] = llc_msg_size / 256;
517 msg[22] = llc_msg_size % 256;
518 memcpy(msg + 23, llc_msg, llc_msg_size);
519
520 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
521 src_addr, nsbvci, msg, bssgp_msg_size);
522}
523
524static void send_bssgp_dl_unitdata(
525 struct gprs_ns_inst *nsi, const char *text,
526 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
527 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
528 const uint8_t *llc_msg, size_t llc_msg_size)
529{
530 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
531 unsigned char msg[4096] = {
532 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
533 0x16, 0x82, 0x02, 0x58,
534 };
535 unsigned char racap_drx[] = {
536 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
537 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
538 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
539 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
540 };
541
542 size_t bssgp_msg_size = 0;
543
544 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
545
546 msg[1] = (uint8_t)(tlli >> 24);
547 msg[2] = (uint8_t)(tlli >> 16);
548 msg[3] = (uint8_t)(tlli >> 8);
549 msg[4] = (uint8_t)(tlli >> 0);
550
551 bssgp_msg_size = 12;
552
553 if (with_racap_drx) {
554 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
555 bssgp_msg_size += sizeof(racap_drx);
556 }
557
558 if (imsi) {
559 OSMO_ASSERT(imsi_size <= 127);
560 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
561 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
562 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
563 bssgp_msg_size += 2 + imsi_size;
564 }
565
566 if ((bssgp_msg_size % 4) != 0) {
567 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
568 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
569 msg[bssgp_msg_size + 1] = 0x80 | abytes;
570 memset(msg + bssgp_msg_size + 2, 0, abytes);
571 bssgp_msg_size += 2 + abytes;
572 }
573
574 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
575 if (llc_msg_size < 128) {
576 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
577 bssgp_msg_size += 2;
578 } else {
579 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
580 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
581 bssgp_msg_size += 3;
582 }
583 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
584 bssgp_msg_size += llc_msg_size;
585
586
587 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
588 src_addr, nsbvci, msg, bssgp_msg_size);
589}
590
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200591static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
592 uint16_t bvci)
593{
594 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
595 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200596 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200597 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200598 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
599 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200600 };
601
602 msg[3] = bvci / 256;
603 msg[4] = bvci % 256;
604
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200605 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
606}
607
608static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
609 struct sockaddr_in *src_addr, uint16_t bvci)
610{
611 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
612 * BSSGP RESET_ACK */
613 static unsigned char msg[5] = {
614 0x23, 0x04, 0x82, 0x00,
615 0x00
616 };
617
618 msg[3] = bvci / 256;
619 msg[4] = bvci % 256;
620
621 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200622}
623
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200624static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
625 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200626 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200627 struct gprs_ra_id *raid)
628{
629 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
630 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200631 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
632 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200633 };
634
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200635 msg[3] = (uint8_t)(tlli >> 24);
636 msg[4] = (uint8_t)(tlli >> 16);
637 msg[5] = (uint8_t)(tlli >> 8);
638 msg[6] = (uint8_t)(tlli >> 0);
639
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200640 gsm48_construct_ra(msg + 9, raid);
641
642 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
643}
644
645static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
646 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200647 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200648 struct gprs_ra_id *raid)
649{
650 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
651 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200652 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
653 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200654 0x81, 0x01
655 };
656
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200657 msg[3] = (uint8_t)(tlli >> 24);
658 msg[4] = (uint8_t)(tlli >> 16);
659 msg[5] = (uint8_t)(tlli >> 8);
660 msg[6] = (uint8_t)(tlli >> 0);
661
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200662 gsm48_construct_ra(msg + 9, raid);
663
664 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
665}
666
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200667static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
668 struct sockaddr_in *src_addr,
669 uint16_t bvci, uint32_t tlli,
670 unsigned n_frames, unsigned n_octets)
671{
672 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
673 unsigned char msg[] = {
674 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
675 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
676 /* n octets */ 0xff, 0xff, 0xff
677 };
678
679 msg[3] = (uint8_t)(tlli >> 24);
680 msg[4] = (uint8_t)(tlli >> 16);
681 msg[5] = (uint8_t)(tlli >> 8);
682 msg[6] = (uint8_t)(tlli >> 0);
683 msg[9] = (uint8_t)(n_frames);
684 msg[12] = (uint8_t)(bvci >> 8);
685 msg[13] = (uint8_t)(bvci >> 0);
686 msg[16] = (uint8_t)(n_octets >> 16);
687 msg[17] = (uint8_t)(n_octets >> 8);
688 msg[18] = (uint8_t)(n_octets >> 0);
689
690 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
691}
692
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200693static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
694 struct sockaddr_in *src_addr,
695 uint16_t bvci, uint8_t tag)
696{
697 /* GPRS Network Service, PDU type: NS_UNITDATA,
698 * BSSGP FLOW_CONTROL_BVC */
699 unsigned char msg[] = {
700 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
701 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
702 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
703 };
704
705 msg[3] = tag;
706
707 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
708 msg, sizeof(msg));
709}
710
711static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
712 struct sockaddr_in *src_addr,
713 uint16_t bvci, uint8_t tag)
714{
715 /* GPRS Network Service, PDU type: NS_UNITDATA,
716 * BSSGP FLOW_CONTROL_BVC_ACK */
717 unsigned char msg[] = {
718 0x27, 0x1e, 0x81, /* Tag */ 0xce
719 };
720
721 msg[3] = tag;
722
723 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
724 msg, sizeof(msg));
725}
726
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200727static void send_llc_ul_ui(
728 struct gprs_ns_inst *nsi, const char *text,
729 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
730 struct gprs_ra_id *raid, uint16_t cell_id,
731 unsigned sapi, unsigned nu,
732 const uint8_t *msg, size_t msg_size)
733{
734 unsigned char llc_msg[4096] = {
735 0x00, 0xc0, 0x01
736 };
737
738 size_t llc_msg_size = 3 + msg_size + 3;
739 uint8_t e_bit = 0;
740 uint8_t pm_bit = 1;
741 unsigned fcs;
742
743 nu &= 0x01ff;
744
745 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
746
747 llc_msg[0] = (sapi & 0x0f);
748 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
749 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
750
751 memcpy(llc_msg + 3, msg, msg_size);
752
753 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
754 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
755 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
756 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
757
758 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
759 src_addr, nsbvci, tlli, raid, cell_id,
760 llc_msg, llc_msg_size);
761}
762
763static void send_llc_dl_ui(
764 struct gprs_ns_inst *nsi, const char *text,
765 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
766 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
767 unsigned sapi, unsigned nu,
768 const uint8_t *msg, size_t msg_size)
769{
770 /* GPRS Network Service, PDU type: NS_UNITDATA */
771 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
772 unsigned char llc_msg[4096] = {
773 0x00, 0x00, 0x01
774 };
775
776 size_t llc_msg_size = 3 + msg_size + 3;
777 uint8_t e_bit = 0;
778 uint8_t pm_bit = 1;
779 unsigned fcs;
780
781 nu &= 0x01ff;
782
783 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
784
785 llc_msg[0] = 0x40 | (sapi & 0x0f);
786 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
787 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
788
789 memcpy(llc_msg + 3, msg, msg_size);
790
791 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
792 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
793 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
794 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
795
796 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
797 src_addr, nsbvci, tlli,
798 with_racap_drx, imsi, imsi_size,
799 llc_msg, llc_msg_size);
800}
801
802
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200803static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
804 uint16_t nsvci, uint16_t nsei)
805{
806 printf("Setup NS-VC: remote 0x%08x:%d, "
807 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
808 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
809 nsvci, nsvci, nsei, nsei);
810
811 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
812 send_ns_alive(nsi, src_addr);
813 send_ns_unblock(nsi, src_addr);
814 send_ns_alive_ack(nsi, src_addr);
815}
816
817static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
818 uint16_t bvci)
819{
820 printf("Setup BSSGP: remote 0x%08x:%d, "
821 "BVCI 0x%04x(%d)\n\n",
822 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
823 bvci, bvci);
824
825 send_bssgp_reset(nsi, src_addr, bvci);
826}
827
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200828static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
829 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200830{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200831 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
832 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200833 send_ns_alive_ack(nsi, sgsn_peer);
834 send_ns_unblock_ack(nsi, sgsn_peer);
835 send_ns_alive(nsi, sgsn_peer);
836}
837
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200838static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
839{
840 sgsn_peer->sin_family = AF_INET;
841 sgsn_peer->sin_port = htons(32000);
842 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
843}
844
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200845static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
846{
847 sgsn_peer->sin_family = AF_INET;
848 sgsn_peer->sin_port = htons(32001);
849 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
850}
851
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200852static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
853{
854 size_t i;
855
856 for (i = 0; i < size; ++i) {
857 bss_peers[i].sin_family = AF_INET;
858 bss_peers[i].sin_port = htons((i + 1) * 1111);
859 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
860 }
861}
862
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200863int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
864 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
865
866/* override */
867int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
868 struct msgb *msg, uint16_t bvci)
869{
870 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
871 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200872 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200873
874 switch (event) {
875 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200876 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200877 default:
878 break;
879 }
880 return 0;
881}
882
883/* override */
884ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
885 const struct sockaddr *dest_addr, socklen_t addrlen)
886{
887 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
888 const struct sockaddr *, socklen_t);
889 static sendto_t real_sendto = NULL;
890 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200891 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200892
893 if (!real_sendto)
894 real_sendto = dlsym(RTLD_NEXT, "sendto");
895
896 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200897 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
898 dest_host, dest_port,
899 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200900 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200901 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
902 dest_host, dest_port,
903 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200904 else if (dest_host == REMOTE_SGSN2_ADDR)
905 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
906 dest_host, dest_port,
907 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200908 else
909 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
910
911 return len;
912}
913
914/* override */
915int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
916{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200917 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
918 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200919 uint16_t bvci = msgb_bvci(msg);
920 uint16_t nsei = msgb_nsei(msg);
921
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200922 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200923
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200924 if (!real_gprs_ns_sendmsg)
925 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
926
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200927 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200928 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
929 "msg length %d (%s)\n",
930 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200931 else if (nsei == SGSN2_NSEI)
932 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
933 "msg length %d (%s)\n",
934 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200935 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200936 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
937 "msg length %d (%s)\n",
938 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200939
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200940 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200941}
942
943static void dump_rate_ctr_group(FILE *stream, const char *prefix,
944 struct rate_ctr_group *ctrg)
945{
946 unsigned int i;
947
948 for (i = 0; i < ctrg->desc->num_ctr; i++) {
949 struct rate_ctr *ctr = &ctrg->ctr[i];
950 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
951 fprintf(stream, " %s%s: %llu%s",
952 prefix, ctrg->desc->ctr_desc[i].description,
953 (long long)ctr->current,
954 "\n");
955 };
956}
957
958/* Signal handler for signals from NS layer */
959static int test_signal(unsigned int subsys, unsigned int signal,
960 void *handler_data, void *signal_data)
961{
962 struct ns_signal_data *nssd = signal_data;
963 int rc;
964
965 if (subsys != SS_L_NS)
966 return 0;
967
968 switch (signal) {
969 case S_NS_RESET:
970 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
971 nssd->nsvc->nsvci,
972 gprs_ns_ll_str(nssd->nsvc));
973 break;
974
975 case S_NS_ALIVE_EXP:
976 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
977 nssd->nsvc->nsvci,
978 gprs_ns_ll_str(nssd->nsvc));
979 break;
980
981 case S_NS_BLOCK:
982 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
983 nssd->nsvc->nsvci,
984 gprs_ns_ll_str(nssd->nsvc));
985 break;
986
987 case S_NS_UNBLOCK:
988 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
989 nssd->nsvc->nsvci,
990 gprs_ns_ll_str(nssd->nsvc));
991 break;
992
993 case S_NS_REPLACED:
994 printf("==> got signal NS_REPLACED: 0x%04x/%s",
995 nssd->nsvc->nsvci,
996 gprs_ns_ll_str(nssd->nsvc));
997 printf(" -> 0x%04x/%s\n",
998 nssd->old_nsvc->nsvci,
999 gprs_ns_ll_str(nssd->old_nsvc));
1000 break;
1001
1002 default:
1003 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1004 nssd->nsvc->nsvci,
1005 gprs_ns_ll_str(nssd->nsvc));
1006 break;
1007 }
1008 printf("\n");
1009 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1010 return rc;
1011}
1012
1013static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1014{
1015 struct msgb *msg;
1016 int ret;
1017 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1018 fprintf(stderr, "message too long: %d\n", data_len);
1019 return -1;
1020 }
1021
1022 msg = gprs_ns_msgb_alloc();
1023 memmove(msg->data, data, data_len);
1024 msg->l2h = msg->data;
1025 msgb_put(msg, data_len);
1026
1027 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1028 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1029 osmo_hexdump(data, data_len));
1030
1031 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1032
1033 printf("result (%s) = %d\n\n", text, ret);
1034
1035 msgb_free(msg);
1036
1037 return ret;
1038}
1039
1040static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1041{
1042 struct gprs_nsvc *nsvc;
1043
1044 printf("Current NS-VCIs:\n");
1045 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1046 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001047 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001048 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001049 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1050 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1051 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001052 );
1053 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1054 }
1055 printf("\n");
1056}
1057
1058static void test_gbproxy()
1059{
1060 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1061 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001062 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001063
1064 bssgp_nsi = nsi;
1065 gbcfg.nsi = bssgp_nsi;
1066 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1067
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001068 configure_sgsn_peer(&sgsn_peer);
1069 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001070
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001071 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001072 printf("--- Initialise SGSN ---\n\n");
1073
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001074 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001075 gprs_dump_nsi(nsi);
1076
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001077 printf("--- Initialise BSS 1 ---\n\n");
1078
1079 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1080 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1081 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001082 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001083
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001084 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1085
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001086 printf("--- Initialise BSS 2 ---\n\n");
1087
1088 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1089 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1090 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001091 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001092
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001093 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1094
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001095 printf("--- Move BSS 1 to new port ---\n\n");
1096
1097 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1098 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001099 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001100
1101 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1102
1103 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1104 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001105 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001106
1107 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1108
1109 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1110 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001111 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001112
1113 printf("--- Move BSS 2 to new port ---\n\n");
1114
1115 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1116 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001117 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001118
1119 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1120
1121 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1122 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001123 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001124
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001125 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1126
1127 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1128 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001129 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001130
1131 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1132
1133 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1134 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001135 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001136
1137 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1138
1139 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1140
1141 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1142 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001143 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001144
1145 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1146
1147 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1148
1149 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1150 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001151 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001152
1153 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1154
1155 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1156
1157 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1158
1159 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1160
1161 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1162
1163 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1164
1165 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1166
1167 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1168
1169 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1170
1171 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1172
1173 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1174
1175 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1176
1177 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1178
1179 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1180
1181 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1182 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001183 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001184
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001185 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001186
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001187 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1188
1189 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1190
1191 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1192
1193 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1194
1195 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1196
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001197 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1198
1199 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1200
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001201 /* Find peer */
1202 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1203 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1204 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1205 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1206 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1207 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1208
1209
1210 /* Cleanup */
1211 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1212 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1213 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1214 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1215 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1216
1217 dump_peers(stdout, 0, 0, &gbcfg);
1218
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001219 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001220
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001221 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001222 gprs_ns_destroy(nsi);
1223 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001224}
1225
1226static void test_gbproxy_ident_changes()
1227{
1228 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1229 struct sockaddr_in bss_peer[1] = {{0},};
1230 struct sockaddr_in sgsn_peer= {0};
1231 uint16_t nsei[2] = {0x1000, 0x2000};
1232 uint16_t nsvci[2] = {0x1001, 0x2001};
1233 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1234
1235 bssgp_nsi = nsi;
1236 gbcfg.nsi = bssgp_nsi;
1237 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1238
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001239 configure_sgsn_peer(&sgsn_peer);
1240 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001241
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001242 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001243 printf("--- Initialise SGSN ---\n\n");
1244
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001245 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001246 gprs_dump_nsi(nsi);
1247
1248 printf("--- Initialise BSS 1 ---\n\n");
1249
1250 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1251 gprs_dump_nsi(nsi);
1252
1253 printf("--- Setup BVCI 1 ---\n\n");
1254
1255 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1256 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001257 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001258
1259 printf("--- Setup BVCI 2 ---\n\n");
1260
1261 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1262 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001263 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001264
1265 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1266
1267 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1268 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1269
1270 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1271
1272 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1273 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1274
1275 printf("--- Change NSEI ---\n\n");
1276
1277 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1278 gprs_dump_nsi(nsi);
1279
1280 printf("--- Setup BVCI 1 ---\n\n");
1281
1282 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1283 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001284 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001285
1286 printf("--- Setup BVCI 3 ---\n\n");
1287
1288 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1289 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001290 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001291
1292 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1293
1294 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1295 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1296
1297 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1298 " (should fail) ---\n\n");
1299
1300 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001301 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001302 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001304
1305 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1306
1307 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1308 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1309
1310 printf("--- Change NSVCI ---\n\n");
1311
1312 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1313 gprs_dump_nsi(nsi);
1314
1315 printf("--- Setup BVCI 1 ---\n\n");
1316
1317 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1318 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001319 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001320
1321 printf("--- Setup BVCI 4 ---\n\n");
1322
1323 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1324 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001325 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001326
1327 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1328
1329 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1330 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1331
1332 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1333 " (should fail) ---\n\n");
1334
1335 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001336 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001337 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001338 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001339
1340 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1341
1342 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1343 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1344
1345 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1346
1347 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1348 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1349
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001350 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001351 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001352
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001353 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001354 gprs_ns_destroy(nsi);
1355 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001356}
1357
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001358static void test_gbproxy_ra_patching()
1359{
1360 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1361 struct sockaddr_in bss_peer[1] = {{0},};
1362 struct sockaddr_in sgsn_peer= {0};
1363 struct gprs_ra_id rai_bss =
1364 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1365 struct gprs_ra_id rai_sgsn =
1366 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1367 struct gprs_ra_id rai_unknown =
1368 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001369 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001370 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001371 const uint32_t ptmsi = 0xefe2b700;
1372 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001373 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001374 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001375 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001376 struct gbproxy_tlli_info *tlli_info;
1377 struct gbproxy_peer *peer;
1378
1379 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001380
1381 bssgp_nsi = nsi;
1382 gbcfg.nsi = bssgp_nsi;
1383 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001384 gbcfg.core_mcc = 123;
1385 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001386 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001387 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001388 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001389
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001390 configure_sgsn_peer(&sgsn_peer);
1391 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001392
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001393 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001394 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001395 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1396 gbcfg.match_re, err_msg);
1397 exit(1);
1398 }
1399
1400
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001401 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001402 printf("--- Initialise SGSN ---\n\n");
1403
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001404 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001405 gprs_dump_nsi(nsi);
1406
1407 printf("--- Initialise BSS 1 ---\n\n");
1408
1409 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1410 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1411 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001412 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001413
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001414 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001415 OSMO_ASSERT(peer != NULL);
1416
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001417 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1418
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001419 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1420 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001421
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001422 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001423 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001424
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001425 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1426 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1427
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001428 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1429
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001430 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1431 foreign_tlli, &rai_bss, cell_id,
1432 GPRS_SAPI_GMM, 0,
1433 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001434
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001435 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1436
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001437 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1438 foreign_tlli, 0, NULL, 0,
1439 GPRS_SAPI_GMM, 0,
1440 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001441
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001442 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1443 foreign_tlli, &rai_bss, cell_id,
1444 GPRS_SAPI_GMM, 3,
1445 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001446
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001447 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1448 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1449
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001450 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1451 foreign_tlli, 1, imsi, sizeof(imsi),
1452 GPRS_SAPI_GMM, 1,
1453 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001454
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001455 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1456
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001457 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1458 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1459 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1460
1461 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1462 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1463 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1464
1465 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1466 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1467 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1468
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001469 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001470 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001471 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1472 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1473 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1474 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1475 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1476 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1477 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1478 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001479
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001480 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1481 local_tlli, &rai_bss, cell_id,
1482 GPRS_SAPI_GMM, 4,
1483 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001484
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001485 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1486
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001487 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001488 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001489 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1490 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1491 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1492 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1493 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1494 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1495 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1496 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001497
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001498 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001499 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1500 local_tlli, &rai_bss, cell_id,
1501 GPRS_SAPI_GMM, 3,
1502 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001503
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001504 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1505
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001506 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001507 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001508 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1509 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1510 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1511 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1512 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1513 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1514 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1515 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001516
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001517 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1518 local_tlli, 1, imsi, sizeof(imsi),
1519 GPRS_SAPI_GMM, 2,
1520 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001521
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001522 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1523
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001524 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001525 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001526 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1527 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1528 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1529 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001530
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001531 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001532 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1533 local_tlli, &rai_bss, cell_id,
1534 GPRS_SAPI_GMM, 3,
1535 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001536
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001537 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1538
Jacob Erlbeck73685282014-05-23 20:48:07 +02001539 gbcfg.core_apn[0] = 0;
1540 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001541
1542 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001543 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1544 local_tlli, &rai_bss, cell_id,
1545 GPRS_SAPI_GMM, 3,
1546 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001547
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001548 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1549
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001550 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001551
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001552 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1554 local_tlli, &rai_bss, cell_id,
1555 GPRS_SAPI_GMM, 6,
1556 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001557
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001558 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1559 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1560
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001561 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1562 local_tlli, 1, imsi, sizeof(imsi),
1563 GPRS_SAPI_GMM, 5,
1564 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001565
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001566 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001567
1568 printf("--- RA update ---\n\n");
1569
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001570 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1571 foreign_tlli, &rai_bss, 0x7080,
1572 GPRS_SAPI_GMM, 5,
1573 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001574
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001575 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1576
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001577 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1578 foreign_tlli, 1, imsi, sizeof(imsi),
1579 GPRS_SAPI_GMM, 6,
1580 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001581
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001582 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1583
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001584 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001585 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1586 local_tlli, &rai_bss, cell_id,
1587 GPRS_SAPI_GMM, 3,
1588 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001589
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001590 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1591
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001592 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001593
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001594 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001595 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1596 local_tlli, &rai_bss, cell_id,
1597 GPRS_SAPI_GMM, 6,
1598 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001599
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001600 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1601
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001602 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001603 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001604
1605 printf("--- Bad cases ---\n\n");
1606
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001607 /* The RAI in the Attach Request message differs from the RAI in the
1608 * BSSGP message, only patch the latter */
1609
1610 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1611 foreign_tlli2, &rai_bss, cell_id,
1612 GPRS_SAPI_GMM, 0,
1613 dtap_attach_req2, sizeof(dtap_attach_req2));
1614
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001615 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1616
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001617 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001618 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1619 local_tlli, &rai_bss, cell_id,
1620 GPRS_SAPI_GMM, 3,
1621 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001622
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001623 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001624 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001625
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001626 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001627 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001628
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001629 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001630 gprs_ns_destroy(nsi);
1631 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001632}
1633
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001634static void test_gbproxy_ptmsi_patching()
1635{
1636 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1637 struct sockaddr_in bss_peer[1] = {{0},};
1638 struct sockaddr_in sgsn_peer= {0};
1639 struct gprs_ra_id rai_bss =
1640 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1641 struct gprs_ra_id rai_sgsn =
1642 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001643 struct gprs_ra_id rai_wrong_mcc_sgsn =
1644 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001645 struct gprs_ra_id rai_unknown =
1646 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1647 uint16_t cell_id = 0x1234;
1648
1649 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001650 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1651 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001652 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001653 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1654 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001655 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001656 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001657
1658 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001659 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1660 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001661 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001662 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1663 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001664 const uint32_t foreign_bss_tlli = 0x8000dead;
1665
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001666
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001667 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1668 struct gbproxy_tlli_info *tlli_info;
1669 struct gbproxy_peer *peer;
1670 unsigned bss_nu = 0;
1671 unsigned sgsn_nu = 0;
1672
1673 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001674 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1675 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1676 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1677 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1678 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001679
1680 bssgp_nsi = nsi;
1681 gbcfg.nsi = bssgp_nsi;
1682 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1683 gbcfg.core_mcc = 123;
1684 gbcfg.core_mnc = 456;
1685 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1686 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1687 gbcfg.patch_ptmsi = 1;
1688 gbcfg.bss_ptmsi_state = 0;
1689 gbcfg.sgsn_tlli_state = 1;
1690
1691 configure_sgsn_peer(&sgsn_peer);
1692 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1693
1694 printf("=== %s ===\n", __func__);
1695 printf("--- Initialise SGSN ---\n\n");
1696
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001697 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001698
1699 printf("--- Initialise BSS 1 ---\n\n");
1700
1701 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1702 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1703
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001704 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001705 OSMO_ASSERT(peer != NULL);
1706
1707 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1708
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001709 gprs_dump_nsi(nsi);
1710 dump_global(stdout, 0);
1711 dump_peers(stdout, 0, 0, &gbcfg);
1712
1713 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1714
1715 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1716 foreign_bss_tlli, &rai_unknown, cell_id,
1717 GPRS_SAPI_GMM, bss_nu++,
1718 dtap_attach_req, sizeof(dtap_attach_req));
1719
1720 dump_peers(stdout, 0, 0, &gbcfg);
1721
1722 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1723 random_sgsn_tlli, 0, NULL, 0,
1724 GPRS_SAPI_GMM, sgsn_nu++,
1725 dtap_identity_req, sizeof(dtap_identity_req));
1726
1727 dump_peers(stdout, 0, 0, &gbcfg);
1728
1729 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1730 foreign_bss_tlli, &rai_bss, cell_id,
1731 GPRS_SAPI_GMM, bss_nu++,
1732 dtap_identity_resp, sizeof(dtap_identity_resp));
1733
1734 dump_peers(stdout, 0, 0, &gbcfg);
1735
1736 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1737 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1738 GPRS_SAPI_GMM, sgsn_nu++,
1739 dtap_attach_acc, sizeof(dtap_attach_acc));
1740
1741 dump_peers(stdout, 0, 0, &gbcfg);
1742
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001743 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001744 OSMO_ASSERT(tlli_info);
1745 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1746 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1747 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1748 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1749 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1750 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1751 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1752 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1753 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1754 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1755
1756 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1757 local_bss_tlli, &rai_bss, cell_id,
1758 GPRS_SAPI_GMM, bss_nu++,
1759 dtap_attach_complete, sizeof(dtap_attach_complete));
1760
1761 dump_peers(stdout, 0, 0, &gbcfg);
1762
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001763 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001764 OSMO_ASSERT(tlli_info);
1765 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1766 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1767 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1768 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1769 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1770 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1771 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1772 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1773
1774 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1775 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1776 GPRS_SAPI_GMM, sgsn_nu++,
1777 dtap_gmm_information, sizeof(dtap_gmm_information));
1778
1779 dump_peers(stdout, 0, 0, &gbcfg);
1780
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001781 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001782 OSMO_ASSERT(tlli_info);
1783 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1784 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1785 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1786 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1787
Jacob Erlbeck82add782014-09-05 18:08:12 +02001788 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1789 local_bss_tlli, &rai_bss, cell_id,
1790 GPRS_SAPI_GMM, bss_nu++,
1791 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1792
1793 dump_peers(stdout, 0, 0, &gbcfg);
1794
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001795 /* Non-DTAP */
1796 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1797 local_bss_tlli, &rai_bss, cell_id,
1798 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1799
1800 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1801 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1802 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1803
1804 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1805 local_bss_tlli, &rai_bss, cell_id,
1806 llc_ui_ll11_dns_query_ul,
1807 sizeof(llc_ui_ll11_dns_query_ul));
1808
1809 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1810 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1811 llc_ui_ll11_dns_resp_dl,
1812 sizeof(llc_ui_ll11_dns_resp_dl));
1813
1814 dump_peers(stdout, 0, 0, &gbcfg);
1815
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001816 /* Repeated RA Update Requests */
1817 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1818 local_bss_tlli, &rai_bss, 0x7080,
1819 GPRS_SAPI_GMM, bss_nu++,
1820 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1821
1822 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1823 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1824 GPRS_SAPI_GMM, sgsn_nu++,
1825 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1826
1827 dump_peers(stdout, 0, 0, &gbcfg);
1828
1829 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1830 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1831 OSMO_ASSERT(tlli_info);
1832 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1833 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1834 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1835 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1836 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1837 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1838 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1839 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1840 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1841 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1842
1843 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1844 local_bss_tlli2, &rai_bss, 0x7080,
1845 GPRS_SAPI_GMM, bss_nu++,
1846 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1847
1848 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1849 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1850 GPRS_SAPI_GMM, sgsn_nu++,
1851 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1852
1853 dump_peers(stdout, 0, 0, &gbcfg);
1854
1855 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1856 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1857 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1858 OSMO_ASSERT(tlli_info);
1859 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1860 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1861 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1862 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1863 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1864 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1865 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1866 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1867 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1868 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1869
1870 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1871 local_bss_tlli3, &rai_bss, 0x7080,
1872 GPRS_SAPI_GMM, bss_nu++,
1873 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1874
1875 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1876
1877 OSMO_ASSERT(tlli_info);
1878 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1879 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1880 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1881 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1882
1883 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1884 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1885 GPRS_SAPI_GMM, sgsn_nu++,
1886 dtap_gmm_information, sizeof(dtap_gmm_information));
1887
1888 dump_peers(stdout, 0, 0, &gbcfg);
1889
1890 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1891 OSMO_ASSERT(tlli_info);
1892 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1893 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1894 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1895 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1896
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001897 /* Other messages */
1898 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001899 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001900
1901 dump_peers(stdout, 0, 0, &gbcfg);
1902
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001903 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001904
1905 dump_peers(stdout, 0, 0, &gbcfg);
1906
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001907 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001908
1909 dump_peers(stdout, 0, 0, &gbcfg);
1910
1911 /* Bad case: Invalid BVCI */
1912 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001913 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001914 dump_global(stdout, 0);
1915
1916 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001917 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001918
1919 dump_global(stdout, 0);
1920
1921 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001922 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001923 &rai_wrong_mcc_sgsn);
1924
1925 dump_global(stdout, 0);
1926
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001927 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
1928 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1929 unknown_sgsn_tlli, 1, NULL, 0,
1930 GPRS_SAPI_GMM, 2,
1931 dtap_gmm_information, sizeof(dtap_gmm_information));
1932
1933 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
1934 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1935 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
1936 GPRS_SAPI_GMM, 3,
1937 dtap_gmm_information, sizeof(dtap_gmm_information));
1938
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001939 /* Detach */
1940 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001941 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001942 GPRS_SAPI_GMM, bss_nu++,
1943 dtap_detach_req, sizeof(dtap_detach_req));
1944
1945 dump_peers(stdout, 0, 0, &gbcfg);
1946
1947 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001948 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001949 GPRS_SAPI_GMM, sgsn_nu++,
1950 dtap_detach_acc, sizeof(dtap_detach_acc));
1951
1952 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001953
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001954 dump_global(stdout, 0);
1955
1956 gbprox_reset(&gbcfg);
1957 gprs_ns_destroy(nsi);
1958 nsi = NULL;
1959}
1960
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001961static void test_gbproxy_imsi_acquisition()
1962{
1963 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1964 struct sockaddr_in bss_peer[1] = {{0},};
1965 struct sockaddr_in sgsn_peer= {0};
1966 struct gprs_ra_id rai_bss =
1967 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1968 struct gprs_ra_id rai_sgsn =
1969 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1970 struct gprs_ra_id rai_wrong_mcc_sgsn =
1971 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1972 struct gprs_ra_id rai_unknown =
1973 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1974 uint16_t cell_id = 0x1234;
1975
1976 const uint32_t sgsn_ptmsi = 0xefe2b700;
1977 const uint32_t local_sgsn_tlli = 0xefe2b700;
1978 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1979
1980 const uint32_t bss_ptmsi = 0xc00f7304;
1981 const uint32_t local_bss_tlli = 0xc00f7304;
1982 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001983 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001984
1985 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1986 struct gbproxy_tlli_info *tlli_info;
1987 struct gbproxy_peer *peer;
1988 unsigned bss_nu = 0;
1989 unsigned sgsn_nu = 0;
1990
1991 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1992
1993 bssgp_nsi = nsi;
1994 gbcfg.nsi = bssgp_nsi;
1995 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1996 gbcfg.core_mcc = 123;
1997 gbcfg.core_mnc = 456;
1998 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1999 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2000 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002001 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002002 gbcfg.bss_ptmsi_state = 0;
2003 gbcfg.sgsn_tlli_state = 1;
2004
2005 configure_sgsn_peer(&sgsn_peer);
2006 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2007
2008 printf("=== %s ===\n", __func__);
2009 printf("--- Initialise SGSN ---\n\n");
2010
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002011 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002012
2013 printf("--- Initialise BSS 1 ---\n\n");
2014
2015 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2016 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2017
2018 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2019 OSMO_ASSERT(peer != NULL);
2020
2021 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2022
2023 gprs_dump_nsi(nsi);
2024 dump_global(stdout, 0);
2025 dump_peers(stdout, 0, 0, &gbcfg);
2026
2027 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2028
2029 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002030 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002031 GPRS_SAPI_GMM, bss_nu++,
2032 dtap_attach_req, sizeof(dtap_attach_req));
2033
2034 dump_peers(stdout, 0, 0, &gbcfg);
2035
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002036 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2037 foreign_bss_tlli, &rai_bss, cell_id,
2038 GPRS_SAPI_GMM, bss_nu++,
2039 dtap_identity_resp, sizeof(dtap_identity_resp));
2040
2041 dump_peers(stdout, 0, 0, &gbcfg);
2042
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002043 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2044 random_sgsn_tlli, 0, NULL, 0,
2045 GPRS_SAPI_GMM, sgsn_nu++,
2046 dtap_identity_req, sizeof(dtap_identity_req));
2047
2048 dump_peers(stdout, 0, 0, &gbcfg);
2049
2050 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2051 foreign_bss_tlli, &rai_bss, cell_id,
2052 GPRS_SAPI_GMM, bss_nu++,
2053 dtap_identity_resp, sizeof(dtap_identity_resp));
2054
2055 dump_peers(stdout, 0, 0, &gbcfg);
2056
2057 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2058 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2059 GPRS_SAPI_GMM, sgsn_nu++,
2060 dtap_attach_acc, sizeof(dtap_attach_acc));
2061
2062 dump_peers(stdout, 0, 0, &gbcfg);
2063
2064 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2065 OSMO_ASSERT(tlli_info);
2066 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2067 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2068 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2069 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2070 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2071 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2072 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2073 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2074 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2075 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2076
2077 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2078 local_bss_tlli, &rai_bss, cell_id,
2079 GPRS_SAPI_GMM, bss_nu++,
2080 dtap_attach_complete, sizeof(dtap_attach_complete));
2081
2082 dump_peers(stdout, 0, 0, &gbcfg);
2083
2084 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2085 OSMO_ASSERT(tlli_info);
2086 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2087 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2088 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2089 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2090 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2091 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2092 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2093 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2094
2095 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2096 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2097 GPRS_SAPI_GMM, sgsn_nu++,
2098 dtap_gmm_information, sizeof(dtap_gmm_information));
2099
2100 dump_peers(stdout, 0, 0, &gbcfg);
2101
2102 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2103 OSMO_ASSERT(tlli_info);
2104 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2105 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2106 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2107 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2108
2109 /* Non-DTAP */
2110 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2111 local_bss_tlli, &rai_bss, cell_id,
2112 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2113
2114 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2115 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2116 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2117
2118 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2119 local_bss_tlli, &rai_bss, cell_id,
2120 llc_ui_ll11_dns_query_ul,
2121 sizeof(llc_ui_ll11_dns_query_ul));
2122
2123 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2124 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2125 llc_ui_ll11_dns_resp_dl,
2126 sizeof(llc_ui_ll11_dns_resp_dl));
2127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
2130 /* Other messages */
2131 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2132 local_bss_tlli, 1, 12);
2133
2134 dump_peers(stdout, 0, 0, &gbcfg);
2135
2136 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2137 local_sgsn_tlli, 1, 12);
2138
2139 dump_peers(stdout, 0, 0, &gbcfg);
2140
2141 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2142
2143 dump_peers(stdout, 0, 0, &gbcfg);
2144
2145 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2146
2147 dump_peers(stdout, 0, 0, &gbcfg);
2148
2149 /* Bad case: Invalid BVCI */
2150 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2151 local_bss_tlli, 1, 12);
2152 dump_global(stdout, 0);
2153
2154 /* Bad case: Invalid RAI */
2155 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2156
2157 dump_global(stdout, 0);
2158
2159 /* Bad case: Invalid MCC (LAC ok) */
2160 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2161 &rai_wrong_mcc_sgsn);
2162
2163 dump_global(stdout, 0);
2164
2165 /* Detach */
2166 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2167 local_bss_tlli, &rai_bss, cell_id,
2168 GPRS_SAPI_GMM, bss_nu++,
2169 dtap_detach_req, sizeof(dtap_detach_req));
2170
2171 dump_peers(stdout, 0, 0, &gbcfg);
2172
2173 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2174 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2175 GPRS_SAPI_GMM, sgsn_nu++,
2176 dtap_detach_acc, sizeof(dtap_detach_acc));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002180 /* Special case: Repeated Attach Requests */
2181
2182 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2183 foreign_bss_tlli, &rai_unknown, cell_id,
2184 GPRS_SAPI_GMM, bss_nu++,
2185 dtap_attach_req, sizeof(dtap_attach_req));
2186
2187 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2188 foreign_bss_tlli, &rai_unknown, cell_id,
2189 GPRS_SAPI_GMM, bss_nu++,
2190 dtap_attach_req, sizeof(dtap_attach_req));
2191
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002192 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2193 foreign_bss_tlli, &rai_bss, cell_id,
2194 GPRS_SAPI_GMM, bss_nu++,
2195 dtap_detach_req, sizeof(dtap_detach_req));
2196
2197 dump_peers(stdout, 0, 0, &gbcfg);
2198
2199 /* Special case: Detach from an unknown TLLI */
2200
2201 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2202 other_bss_tlli, &rai_bss, cell_id,
2203 GPRS_SAPI_GMM, bss_nu++,
2204 dtap_detach_req, sizeof(dtap_detach_req));
2205
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002206 dump_peers(stdout, 0, 0, &gbcfg);
2207
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002208 dump_global(stdout, 0);
2209
2210 gbprox_reset(&gbcfg);
2211 gprs_ns_destroy(nsi);
2212 nsi = NULL;
2213}
2214
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002215static void test_gbproxy_secondary_sgsn()
2216{
2217 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2218 struct sockaddr_in bss_peer[1] = {{0},};
2219 struct sockaddr_in sgsn_peer[2]= {{0},};
2220 struct gprs_ra_id rai_bss =
2221 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2222 struct gprs_ra_id rai_sgsn =
2223 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2224 struct gprs_ra_id rai_unknown =
2225 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2226 uint16_t cell_id = 0x1234;
2227
2228 const uint32_t sgsn_ptmsi = 0xefe2b700;
2229 const uint32_t local_sgsn_tlli = 0xefe2b700;
2230 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2231
2232 const uint32_t bss_ptmsi = 0xc00f7304;
2233 const uint32_t local_bss_tlli = 0xc00f7304;
2234 const uint32_t foreign_bss_tlli = 0x8000dead;
2235
2236 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2237 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2238 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2239 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2240 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2241 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2242
2243 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2244 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2245 struct gbproxy_tlli_info *tlli_info;
2246 struct gbproxy_peer *peer;
2247 unsigned bss_nu = 0;
2248 unsigned sgsn_nu = 0;
2249
2250 const char *err_msg = NULL;
2251 const char *filter_re = "999999";
2252
2253 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2254 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2255
2256 bssgp_nsi = nsi;
2257 gbcfg.nsi = bssgp_nsi;
2258 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2259 gbcfg.core_mcc = 123;
2260 gbcfg.core_mnc = 456;
2261 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2262 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2263 gbcfg.patch_ptmsi = 1;
2264 gbcfg.acquire_imsi = 1;
2265 gbcfg.bss_ptmsi_state = 0;
2266 gbcfg.sgsn_tlli_state = 1;
2267 gbcfg.route_to_sgsn2 = 1;
2268 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2269
2270 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2271 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2272 err_msg);
2273 OSMO_ASSERT(err_msg == NULL);
2274 }
2275
2276 configure_sgsn_peer(&sgsn_peer[0]);
2277 configure_sgsn2_peer(&sgsn_peer[1]);
2278 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2279
2280 printf("=== %s ===\n", __func__);
2281 printf("--- Initialise SGSN 1 ---\n\n");
2282
2283 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2284
2285 printf("--- Initialise SGSN 2 ---\n\n");
2286
2287 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2288
2289 printf("--- Initialise BSS 1 ---\n\n");
2290
2291 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2292 setup_bssgp(nsi, &bss_peer[0], 0x0);
2293 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2294 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2295 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2296 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2297
2298 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2299 OSMO_ASSERT(peer != NULL);
2300
2301 gprs_dump_nsi(nsi);
2302 dump_global(stdout, 0);
2303 dump_peers(stdout, 0, 0, &gbcfg);
2304
2305 printf("--- Flow control ---\n\n");
2306
2307 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2308 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2309 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2310
2311 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2312
2313 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2314 foreign_bss_tlli, &rai_unknown, cell_id,
2315 GPRS_SAPI_GMM, bss_nu++,
2316 dtap_attach_req, sizeof(dtap_attach_req));
2317
2318 dump_peers(stdout, 0, 0, &gbcfg);
2319
2320 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2321 foreign_bss_tlli, &rai_bss, cell_id,
2322 GPRS_SAPI_GMM, bss_nu++,
2323 dtap_identity_resp, sizeof(dtap_identity_resp));
2324
2325 dump_peers(stdout, 0, 0, &gbcfg);
2326
2327 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2328 random_sgsn_tlli, 0, NULL, 0,
2329 GPRS_SAPI_GMM, sgsn_nu++,
2330 dtap_identity_req, sizeof(dtap_identity_req));
2331
2332 dump_peers(stdout, 0, 0, &gbcfg);
2333
2334 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2335 foreign_bss_tlli, &rai_bss, cell_id,
2336 GPRS_SAPI_GMM, bss_nu++,
2337 dtap_identity_resp, sizeof(dtap_identity_resp));
2338
2339 dump_peers(stdout, 0, 0, &gbcfg);
2340
2341 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2342 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2343 GPRS_SAPI_GMM, sgsn_nu++,
2344 dtap_attach_acc, sizeof(dtap_attach_acc));
2345
2346 dump_peers(stdout, 0, 0, &gbcfg);
2347
2348 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2349 OSMO_ASSERT(tlli_info);
2350 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2351 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2352 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2353 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2354 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2355 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2356 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2357 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2358 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2359 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2360
2361 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2362 local_bss_tlli, &rai_bss, cell_id,
2363 GPRS_SAPI_GMM, bss_nu++,
2364 dtap_attach_complete, sizeof(dtap_attach_complete));
2365
2366 dump_peers(stdout, 0, 0, &gbcfg);
2367
2368 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2369 OSMO_ASSERT(tlli_info);
2370 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2371 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2372 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2373 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2374 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2375 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2376 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2377 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2378
2379 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2380 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2381 GPRS_SAPI_GMM, sgsn_nu++,
2382 dtap_gmm_information, sizeof(dtap_gmm_information));
2383
2384 dump_peers(stdout, 0, 0, &gbcfg);
2385
2386 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2387 OSMO_ASSERT(tlli_info);
2388 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2389 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2390 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2391 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2392
2393 /* Non-DTAP */
2394 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2395 local_bss_tlli, &rai_bss, cell_id,
2396 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2397
2398 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2399 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2400 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2401
2402 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2403 local_bss_tlli, &rai_bss, cell_id,
2404 llc_ui_ll11_dns_query_ul,
2405 sizeof(llc_ui_ll11_dns_query_ul));
2406
2407 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2408 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2409 llc_ui_ll11_dns_resp_dl,
2410 sizeof(llc_ui_ll11_dns_resp_dl));
2411
2412 dump_peers(stdout, 0, 0, &gbcfg);
2413
2414 /* Other messages */
2415 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2416 local_bss_tlli, 1, 12);
2417
2418 dump_peers(stdout, 0, 0, &gbcfg);
2419
2420 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2421 local_sgsn_tlli, 1, 12);
2422
2423 dump_peers(stdout, 0, 0, &gbcfg);
2424
2425 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2426
2427 dump_peers(stdout, 0, 0, &gbcfg);
2428
2429 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2430
2431 dump_peers(stdout, 0, 0, &gbcfg);
2432
2433 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2434
2435 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2436 foreign_bss_tlli2, &rai_unknown, cell_id,
2437 GPRS_SAPI_GMM, bss_nu++,
2438 dtap_attach_req, sizeof(dtap_attach_req));
2439
2440 dump_peers(stdout, 0, 0, &gbcfg);
2441
2442 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2443 foreign_bss_tlli2, &rai_bss, cell_id,
2444 GPRS_SAPI_GMM, bss_nu++,
2445 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2446
2447 dump_peers(stdout, 0, 0, &gbcfg);
2448
2449 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2450 random_sgsn_tlli2, 0, NULL, 0,
2451 GPRS_SAPI_GMM, sgsn_nu++,
2452 dtap_identity_req, sizeof(dtap_identity_req));
2453
2454 dump_peers(stdout, 0, 0, &gbcfg);
2455
2456 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2457 foreign_bss_tlli2, &rai_bss, cell_id,
2458 GPRS_SAPI_GMM, bss_nu++,
2459 dtap_identity_resp, sizeof(dtap_identity_resp));
2460
2461 dump_peers(stdout, 0, 0, &gbcfg);
2462
2463 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2464 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2465 GPRS_SAPI_GMM, sgsn_nu++,
2466 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2467
2468 dump_peers(stdout, 0, 0, &gbcfg);
2469
2470 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2471 OSMO_ASSERT(tlli_info);
2472 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2473 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2474 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2475 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2476 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2477 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2478 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2479 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2480 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2481 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2482
2483 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2484 local_bss_tlli2, &rai_bss, cell_id,
2485 GPRS_SAPI_GMM, bss_nu++,
2486 dtap_attach_complete, sizeof(dtap_attach_complete));
2487
2488 dump_peers(stdout, 0, 0, &gbcfg);
2489
2490 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2491 OSMO_ASSERT(tlli_info);
2492 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2493 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2494 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2495 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2496 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2497 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2498 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2499 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2500
2501 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2502 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2503 GPRS_SAPI_GMM, sgsn_nu++,
2504 dtap_gmm_information, sizeof(dtap_gmm_information));
2505
2506 dump_peers(stdout, 0, 0, &gbcfg);
2507
2508 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2509 OSMO_ASSERT(tlli_info);
2510 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2511 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2512 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2513 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2514
2515 /* Non-DTAP */
2516 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2517 local_bss_tlli2, &rai_bss, cell_id,
2518 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2519
2520 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2521 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2522 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2523
2524 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2525 local_bss_tlli2, &rai_bss, cell_id,
2526 llc_ui_ll11_dns_query_ul,
2527 sizeof(llc_ui_ll11_dns_query_ul));
2528
2529 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2530 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2531 llc_ui_ll11_dns_resp_dl,
2532 sizeof(llc_ui_ll11_dns_resp_dl));
2533
2534 dump_peers(stdout, 0, 0, &gbcfg);
2535
2536 /* Other messages */
2537 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2538 local_bss_tlli2, 1, 12);
2539
2540 dump_peers(stdout, 0, 0, &gbcfg);
2541
2542 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2543 local_sgsn_tlli2, 1, 12);
2544
2545 dump_peers(stdout, 0, 0, &gbcfg);
2546
2547 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2548
2549 dump_peers(stdout, 0, 0, &gbcfg);
2550
2551 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2552
2553 dump_peers(stdout, 0, 0, &gbcfg);
2554
2555 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2556
2557 /* Detach */
2558 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2559 local_bss_tlli, &rai_bss, cell_id,
2560 GPRS_SAPI_GMM, bss_nu++,
2561 dtap_detach_req, sizeof(dtap_detach_req));
2562
2563 dump_peers(stdout, 0, 0, &gbcfg);
2564
2565 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2566 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2567 GPRS_SAPI_GMM, sgsn_nu++,
2568 dtap_detach_acc, sizeof(dtap_detach_acc));
2569
2570 dump_peers(stdout, 0, 0, &gbcfg);
2571
2572 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2573
2574 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2575 local_bss_tlli2, &rai_bss, cell_id,
2576 GPRS_SAPI_GMM, bss_nu++,
2577 dtap_detach_req, sizeof(dtap_detach_req));
2578
2579 dump_peers(stdout, 0, 0, &gbcfg);
2580
2581 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2582 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2583 GPRS_SAPI_GMM, sgsn_nu++,
2584 dtap_detach_acc, sizeof(dtap_detach_acc));
2585
2586 dump_peers(stdout, 0, 0, &gbcfg);
2587
2588 dump_global(stdout, 0);
2589
2590 gbprox_reset(&gbcfg);
2591 gprs_ns_destroy(nsi);
2592 nsi = NULL;
2593}
2594
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002595static void test_gbproxy_keep_info()
2596{
2597 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2598 struct sockaddr_in bss_peer[1] = {{0},};
2599 struct sockaddr_in sgsn_peer= {0};
2600 struct gprs_ra_id rai_bss =
2601 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2602 uint16_t cell_id = 0x1234;
2603
2604 const uint32_t ptmsi = 0xefe2b700;
2605 const uint32_t local_tlli = 0xefe2b700;
2606 const uint32_t foreign_tlli = 0xafe2b700;
2607
2608 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2609 struct gbproxy_tlli_info *tlli_info;
2610 struct gbproxy_peer *peer;
2611 unsigned bss_nu = 0;
2612 unsigned sgsn_nu = 0;
2613
2614 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
2615
2616 bssgp_nsi = nsi;
2617 gbcfg.nsi = bssgp_nsi;
2618 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2619 gbcfg.patch_ptmsi = 0;
2620 gbcfg.acquire_imsi = 1;
2621 gbcfg.bss_ptmsi_state = 0;
2622 gbcfg.sgsn_tlli_state = 1;
2623 gbcfg.core_mcc = 0;
2624 gbcfg.core_mnc = 0;
2625 gbcfg.core_apn = NULL;
2626 gbcfg.core_apn_size = 0;
2627 gbcfg.route_to_sgsn2 = 0;
2628 gbcfg.nsip_sgsn2_nsei = 0xffff;
2629
2630 configure_sgsn_peer(&sgsn_peer);
2631 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2632
2633 printf("=== %s ===\n", __func__);
2634 printf("--- Initialise SGSN ---\n\n");
2635
2636 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2637
2638 printf("--- Initialise BSS 1 ---\n\n");
2639
2640 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2641 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2642
2643 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2644 OSMO_ASSERT(peer != NULL);
2645
2646 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2647
2648 gprs_dump_nsi(nsi);
2649 dump_global(stdout, 0);
2650 dump_peers(stdout, 0, 0, &gbcfg);
2651
2652 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2653
2654 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2655 foreign_tlli, &rai_bss, cell_id,
2656 GPRS_SAPI_GMM, bss_nu++,
2657 dtap_attach_req, sizeof(dtap_attach_req));
2658
2659 dump_peers(stdout, 0, 0, &gbcfg);
2660
2661 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2662 OSMO_ASSERT(tlli_info);
2663 OSMO_ASSERT(tlli_info->imsi_len == 0);
2664
2665 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2666 foreign_tlli, &rai_bss, cell_id,
2667 GPRS_SAPI_GMM, bss_nu++,
2668 dtap_identity_resp, sizeof(dtap_identity_resp));
2669
2670 dump_peers(stdout, 0, 0, &gbcfg);
2671
2672 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2673 foreign_tlli, 0, NULL, 0,
2674 GPRS_SAPI_GMM, sgsn_nu++,
2675 dtap_identity_req, sizeof(dtap_identity_req));
2676
2677 dump_peers(stdout, 0, 0, &gbcfg);
2678
2679 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2680 foreign_tlli, &rai_bss, cell_id,
2681 GPRS_SAPI_GMM, bss_nu++,
2682 dtap_identity_resp, sizeof(dtap_identity_resp));
2683
2684 dump_peers(stdout, 0, 0, &gbcfg);
2685
2686 tlli_info = gbproxy_find_tlli(peer, foreign_tlli);
2687 OSMO_ASSERT(tlli_info);
2688 OSMO_ASSERT(tlli_info->imsi_len > 0);
2689 OSMO_ASSERT(gbproxy_find_tlli_by_imsi(peer, imsi, sizeof(imsi)));
2690
2691 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2692 foreign_tlli, 1, imsi, sizeof(imsi),
2693 GPRS_SAPI_GMM, sgsn_nu++,
2694 dtap_attach_acc, sizeof(dtap_attach_acc));
2695
2696 dump_peers(stdout, 0, 0, &gbcfg);
2697
2698 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2699 local_tlli, &rai_bss, cell_id,
2700 GPRS_SAPI_GMM, bss_nu++,
2701 dtap_attach_complete, sizeof(dtap_attach_complete));
2702
2703 dump_peers(stdout, 0, 0, &gbcfg);
2704
2705 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2706 local_tlli, 1, imsi, sizeof(imsi),
2707 GPRS_SAPI_GMM, sgsn_nu++,
2708 dtap_gmm_information, sizeof(dtap_gmm_information));
2709
2710 dump_peers(stdout, 0, 0, &gbcfg);
2711
2712 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2713 OSMO_ASSERT(tlli_info);
2714
2715 /* Detach (MO) */
2716 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2717 local_tlli, &rai_bss, cell_id,
2718 GPRS_SAPI_GMM, bss_nu++,
2719 dtap_detach_req, sizeof(dtap_detach_req));
2720
2721 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2722 OSMO_ASSERT(tlli_info);
2723
2724 dump_peers(stdout, 0, 0, &gbcfg);
2725
2726 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2727 local_tlli, 1, imsi, sizeof(imsi),
2728 GPRS_SAPI_GMM, sgsn_nu++,
2729 dtap_detach_acc, sizeof(dtap_detach_acc));
2730
2731 dump_peers(stdout, 0, 0, &gbcfg);
2732
2733 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2734 OSMO_ASSERT(tlli_info == NULL);
2735
2736 /* Re-Attach */
2737 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2738 foreign_tlli, &rai_bss, cell_id,
2739 GPRS_SAPI_GMM, bss_nu++,
2740 dtap_attach_req3, sizeof(dtap_attach_req3));
2741
2742 dump_peers(stdout, 0, 0, &gbcfg);
2743
2744 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2745 foreign_tlli, 1, imsi, sizeof(imsi),
2746 GPRS_SAPI_GMM, sgsn_nu++,
2747 dtap_attach_acc, sizeof(dtap_attach_acc));
2748
2749 dump_peers(stdout, 0, 0, &gbcfg);
2750
2751 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2752 local_tlli, &rai_bss, cell_id,
2753 GPRS_SAPI_GMM, bss_nu++,
2754 dtap_attach_complete, sizeof(dtap_attach_complete));
2755
2756 dump_peers(stdout, 0, 0, &gbcfg);
2757
2758 /* Detach (MT) */
2759 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
2760 local_tlli, 1, imsi, sizeof(imsi),
2761 GPRS_SAPI_GMM, sgsn_nu++,
2762 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
2763
2764 dump_peers(stdout, 0, 0, &gbcfg);
2765
2766 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2767 OSMO_ASSERT(tlli_info);
2768
2769 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2770 local_tlli, &rai_bss, cell_id,
2771 GPRS_SAPI_GMM, bss_nu++,
2772 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2773
2774 dump_peers(stdout, 0, 0, &gbcfg);
2775
2776 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
2777
2778 /* Re-Attach */
2779 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2780 foreign_tlli, &rai_bss, cell_id,
2781 GPRS_SAPI_GMM, bss_nu++,
2782 dtap_attach_req3, sizeof(dtap_attach_req3));
2783
2784 dump_peers(stdout, 0, 0, &gbcfg);
2785
2786 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2787 foreign_tlli, 1, imsi, sizeof(imsi),
2788 GPRS_SAPI_GMM, sgsn_nu++,
2789 dtap_attach_acc, sizeof(dtap_attach_acc));
2790
2791 dump_peers(stdout, 0, 0, &gbcfg);
2792
2793 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2794 local_tlli, &rai_bss, cell_id,
2795 GPRS_SAPI_GMM, bss_nu++,
2796 dtap_attach_complete, sizeof(dtap_attach_complete));
2797
2798 dump_peers(stdout, 0, 0, &gbcfg);
2799
2800 /* Detach (MT) */
2801 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
2802 local_tlli, 1, imsi, sizeof(imsi),
2803 GPRS_SAPI_GMM, sgsn_nu++,
2804 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
2805
2806 dump_peers(stdout, 0, 0, &gbcfg);
2807
2808 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2809 OSMO_ASSERT(tlli_info);
2810
2811 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2812 local_tlli, &rai_bss, cell_id,
2813 GPRS_SAPI_GMM, bss_nu++,
2814 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2815
2816 dump_peers(stdout, 0, 0, &gbcfg);
2817
2818 OSMO_ASSERT(!gbproxy_find_tlli(peer, local_tlli));
2819
2820 /* Re-Attach */
2821 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2822 foreign_tlli, &rai_bss, cell_id,
2823 GPRS_SAPI_GMM, bss_nu++,
2824 dtap_attach_req3, sizeof(dtap_attach_req3));
2825
2826 dump_peers(stdout, 0, 0, &gbcfg);
2827
2828 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2829 foreign_tlli, 1, imsi, sizeof(imsi),
2830 GPRS_SAPI_GMM, sgsn_nu++,
2831 dtap_attach_acc, sizeof(dtap_attach_acc));
2832
2833 dump_peers(stdout, 0, 0, &gbcfg);
2834
2835 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2836 local_tlli, &rai_bss, cell_id,
2837 GPRS_SAPI_GMM, bss_nu++,
2838 dtap_attach_complete, sizeof(dtap_attach_complete));
2839
2840 dump_peers(stdout, 0, 0, &gbcfg);
2841
2842 /* RA update procedure (reject -> Detach) */
2843 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2844 local_tlli, &rai_bss, 0x7080,
2845 GPRS_SAPI_GMM, bss_nu++,
2846 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2847
2848 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
2849 local_tlli, 1, imsi, sizeof(imsi),
2850 GPRS_SAPI_GMM, sgsn_nu++,
2851 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
2852
2853 dump_peers(stdout, 0, 0, &gbcfg);
2854
2855 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
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_req, sizeof(dtap_attach_req));
2860
2861 dump_peers(stdout, 0, 0, &gbcfg);
2862
2863 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2864 foreign_tlli, 1, imsi, sizeof(imsi),
2865 GPRS_SAPI_GMM, sgsn_nu++,
2866 dtap_attach_acc, sizeof(dtap_attach_acc));
2867
2868 dump_peers(stdout, 0, 0, &gbcfg);
2869
2870 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2871 local_tlli, &rai_bss, cell_id,
2872 GPRS_SAPI_GMM, bss_nu++,
2873 dtap_attach_complete, sizeof(dtap_attach_complete));
2874
2875 dump_peers(stdout, 0, 0, &gbcfg);
2876
2877 /* Detach (MT) */
2878 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
2879 local_tlli, 1, imsi, sizeof(imsi),
2880 GPRS_SAPI_GMM, sgsn_nu++,
2881 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
2882
2883 dump_peers(stdout, 0, 0, &gbcfg);
2884
2885 tlli_info = gbproxy_find_tlli(peer, local_tlli);
2886 OSMO_ASSERT(tlli_info);
2887
2888 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2889 local_tlli, &rai_bss, cell_id,
2890 GPRS_SAPI_GMM, bss_nu++,
2891 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
2892
2893 dump_peers(stdout, 0, 0, &gbcfg);
2894
2895 dump_global(stdout, 0);
2896
2897 gbprox_reset(&gbcfg);
2898 gprs_ns_destroy(nsi);
2899 nsi = NULL;
2900}
2901
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002902/* TODO: Move tlv testing to libosmocore */
2903int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2904int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2905 uint8_t **value);
2906int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2907 size_t *value_len);
2908int lv_shift(uint8_t **data, size_t *data_len,
2909 uint8_t **value, size_t *value_len);
2910
2911static void check_tlv_match(uint8_t **data, size_t *data_len,
2912 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2913{
2914 uint8_t *value;
2915 size_t value_len;
2916 int rc;
2917
2918 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2919 OSMO_ASSERT(rc == 0);
2920
2921 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002922 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002923 OSMO_ASSERT(value_len == exp_len);
2924 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2925}
2926
2927static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2928 uint8_t tag, size_t len, const uint8_t *exp_val)
2929{
2930 uint8_t *value;
2931 int rc;
2932
2933 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2934 OSMO_ASSERT(rc == 0);
2935
2936 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002937 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002938 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2939}
2940
2941static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2942 size_t len, const uint8_t *exp_val)
2943{
2944 uint8_t *value;
2945 int rc;
2946
2947 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002948 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002949 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2950}
2951
2952static void check_lv_shift(uint8_t **data, size_t *data_len,
2953 size_t exp_len, const uint8_t *exp_val)
2954{
2955 uint8_t *value;
2956 size_t value_len;
2957 int rc;
2958
2959 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002960 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002961 OSMO_ASSERT(value_len == exp_len);
2962 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2963}
2964
2965static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2966 const uint8_t *test_data)
2967{
2968 uint8_t buf[300] = {0};
2969
2970 uint8_t *unchanged_ptr = buf - 1;
2971 size_t unchanged_len = 0xdead;
2972 size_t tmp_data_len = data_len;
2973 uint8_t *value = unchanged_ptr;
2974 size_t value_len = unchanged_len;
2975 uint8_t *data = buf;
2976
2977 OSMO_ASSERT(data_len <= sizeof(buf));
2978
2979 tlv_put(data, tag, len, test_data);
2980 if (data_len < len + 2) {
2981 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2982 tag, &value, &value_len));
2983 OSMO_ASSERT(tmp_data_len == 0);
2984 OSMO_ASSERT(data == buf + data_len);
2985 OSMO_ASSERT(value == unchanged_ptr);
2986 OSMO_ASSERT(value_len == unchanged_len);
2987 } else {
2988 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2989 tag, &value, &value_len));
2990 OSMO_ASSERT(value != unchanged_ptr);
2991 OSMO_ASSERT(value_len != unchanged_len);
2992 }
2993}
2994
2995static void check_tv_fixed_match_data_len(size_t data_len,
2996 uint8_t tag, size_t len,
2997 const uint8_t *test_data)
2998{
2999 uint8_t buf[300] = {0};
3000
3001 uint8_t *unchanged_ptr = buf - 1;
3002 size_t tmp_data_len = data_len;
3003 uint8_t *value = unchanged_ptr;
3004 uint8_t *data = buf;
3005
3006 OSMO_ASSERT(data_len <= sizeof(buf));
3007
3008 tv_fixed_put(data, tag, len, test_data);
3009
3010 if (data_len < len + 1) {
3011 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3012 tag, len, &value));
3013 OSMO_ASSERT(tmp_data_len == 0);
3014 OSMO_ASSERT(data == buf + data_len);
3015 OSMO_ASSERT(value == unchanged_ptr);
3016 } else {
3017 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3018 tag, len, &value));
3019 OSMO_ASSERT(value != unchanged_ptr);
3020 }
3021}
3022
3023static void check_v_fixed_shift_data_len(size_t data_len,
3024 size_t len, const uint8_t *test_data)
3025{
3026 uint8_t buf[300] = {0};
3027
3028 uint8_t *unchanged_ptr = buf - 1;
3029 size_t tmp_data_len = data_len;
3030 uint8_t *value = unchanged_ptr;
3031 uint8_t *data = buf;
3032
3033 OSMO_ASSERT(data_len <= sizeof(buf));
3034
3035 memcpy(data, test_data, len);
3036
3037 if (data_len < len) {
3038 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3039 len, &value));
3040 OSMO_ASSERT(tmp_data_len == 0);
3041 OSMO_ASSERT(data == buf + data_len);
3042 OSMO_ASSERT(value == unchanged_ptr);
3043 } else {
3044 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3045 len, &value));
3046 OSMO_ASSERT(value != unchanged_ptr);
3047 }
3048}
3049
3050static void check_lv_shift_data_len(size_t data_len,
3051 size_t len, const uint8_t *test_data)
3052{
3053 uint8_t buf[300] = {0};
3054
3055 uint8_t *unchanged_ptr = buf - 1;
3056 size_t unchanged_len = 0xdead;
3057 size_t tmp_data_len = data_len;
3058 uint8_t *value = unchanged_ptr;
3059 size_t value_len = unchanged_len;
3060 uint8_t *data = buf;
3061
3062 lv_put(data, len, test_data);
3063 if (data_len < len + 1) {
3064 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3065 &value, &value_len));
3066 OSMO_ASSERT(tmp_data_len == 0);
3067 OSMO_ASSERT(data == buf + data_len);
3068 OSMO_ASSERT(value == unchanged_ptr);
3069 OSMO_ASSERT(value_len == unchanged_len);
3070 } else {
3071 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3072 &value, &value_len));
3073 OSMO_ASSERT(value != unchanged_ptr);
3074 OSMO_ASSERT(value_len != unchanged_len);
3075 }
3076}
3077
3078static void test_tlv_shift_functions()
3079{
3080 uint8_t test_data[1024];
3081 uint8_t buf[1024];
3082 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003083 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003084 uint8_t *data;
3085 size_t data_len;
3086 const uint8_t tag = 0x1a;
3087
3088 printf("Test shift functions\n");
3089
3090 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3091 test_data[i] = (uint8_t)i;
3092
3093 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003094 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003095
3096 memset(buf, 0xee, sizeof(buf));
3097 data_end = data = buf;
3098
3099 for (i = 0; i < iterations; i++) {
3100 data_end = tlv_put(data_end, tag, len, test_data);
3101 data_end = tv_fixed_put(data_end, tag, len, test_data);
3102 /* v_fixed_put */
3103 memcpy(data_end, test_data, len);
3104 data_end += len;
3105 data_end = lv_put(data_end, len, test_data);
3106 }
3107
3108 data_len = data_end - data;
3109 OSMO_ASSERT(data_len <= sizeof(buf));
3110
3111 for (i = 0; i < iterations; i++) {
3112 check_tlv_match(&data, &data_len, tag, len, test_data);
3113 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3114 check_v_fixed_shift(&data, &data_len, len, test_data);
3115 check_lv_shift(&data, &data_len, len, test_data);
3116 }
3117
3118 OSMO_ASSERT(data == data_end);
3119
3120 /* Test at end of data */
3121
3122 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3123 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3124 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3125 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3126
3127 /* Test invalid data_len */
3128 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3129 check_tlv_match_data_len(data_len, tag, len, test_data);
3130 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3131 check_v_fixed_shift_data_len(data_len, len, test_data);
3132 check_lv_shift_data_len(data_len, len, test_data);
3133 }
3134 }
3135}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003136
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003137struct gbproxy_tlli_info *register_tlli(
3138 struct gbproxy_peer *peer, uint32_t tlli,
3139 const uint8_t *imsi, size_t imsi_len, time_t now)
3140{
3141 struct gbproxy_tlli_info *tlli_info;
3142 int enable_patching = -1;
3143 int tlli_already_known = 0;
3144
3145 /* Check, whether the IMSI matches */
3146 if (gprs_is_mi_imsi(imsi, imsi_len)) {
3147 enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
3148 if (enable_patching < 0)
3149 return NULL;
3150 }
3151
3152 tlli_info = gbproxy_find_tlli(peer, tlli);
3153
3154 if (!tlli_info) {
3155 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi, imsi_len);
3156
3157 if (tlli_info) {
3158 /* TLLI has changed somehow, adjust it */
3159 LOGP(DGPRS, LOGL_INFO,
3160 "The TLLI has changed from %08x to %08x\n",
3161 tlli_info->tlli.current, tlli);
3162 tlli_info->tlli.current = tlli;
3163 }
3164 }
3165
3166 if (!tlli_info) {
3167 tlli_info = gbproxy_tlli_info_alloc(peer);
3168 tlli_info->tlli.current = tlli;
3169 } else {
3170 gbproxy_detach_tlli_info(peer, tlli_info);
3171 tlli_already_known = 1;
3172 }
3173
3174 OSMO_ASSERT(tlli_info != NULL);
3175
3176 if (!tlli_already_known)
3177 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3178
3179 gbproxy_attach_tlli_info(peer, now, tlli_info);
3180 gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
3181
3182 if (enable_patching >= 0)
3183 tlli_info->enable_patching = enable_patching;
3184
3185 return tlli_info;
3186}
3187
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003188static void test_gbproxy_tlli_expire(void)
3189{
3190 struct gbproxy_config cfg = {0};
3191 struct gbproxy_peer *peer;
3192 const char *err_msg = NULL;
3193 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3194 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003195 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003196 const uint32_t tlli1 = 1234 | 0xc0000000;
3197 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003198 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003199 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003200 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003201
3202 printf("Test TLLI info expiry\n\n");
3203
3204 gbproxy_init_config(&cfg);
3205
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003206 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003207 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3208 err_msg);
3209 OSMO_ASSERT(err_msg == NULL);
3210 }
3211
3212 {
3213 struct gbproxy_tlli_info *tlli_info;
3214
3215 printf("Test TLLI replacement:\n");
3216
3217 cfg.tlli_max_len = 0;
3218 cfg.tlli_max_age = 0;
3219 peer = gbproxy_peer_alloc(&cfg, 20);
3220 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3221
3222 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003223 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003224 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003225 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003226 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003227 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3228
3229 /* replace the old entry */
3230 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003231 tlli_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003232 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003233 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003234 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003235 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3236
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003237 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003238
3239 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003240 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003241 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003242 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003243 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003244 OSMO_ASSERT(!tlli_info);
3245
3246 printf("\n");
3247
3248 gbproxy_peer_free(peer);
3249 }
3250
3251 {
3252 struct gbproxy_tlli_info *tlli_info;
3253
3254 printf("Test IMSI replacement:\n");
3255
3256 cfg.tlli_max_len = 0;
3257 cfg.tlli_max_age = 0;
3258 peer = gbproxy_peer_alloc(&cfg, 20);
3259 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3260
3261 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003262 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003263 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003264 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003265 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003266 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3267
3268 /* try to replace the old entry */
3269 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003270 tlli_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003271 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02003272 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003273 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003274 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3275
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003276 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003277
3278 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003279 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003280 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003281 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003282 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003283 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003284
3285 printf("\n");
3286
3287 gbproxy_peer_free(peer);
3288 }
3289
3290 {
3291 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003292 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003293
3294 printf("Test TLLI expiry, max_len == 1:\n");
3295
3296 cfg.tlli_max_len = 1;
3297 cfg.tlli_max_age = 0;
3298 peer = gbproxy_peer_alloc(&cfg, 20);
3299 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3300
3301 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003302 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003303 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3304
3305 /* replace the old entry */
3306 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003307 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003308 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3309
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003310 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003311 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003312 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3313
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003314 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003315
3316 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003317 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003318 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003319 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003320 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003321 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003322
3323 printf("\n");
3324
3325 gbproxy_peer_free(peer);
3326 }
3327
3328 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003329 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003330 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003331
3332 printf("Test TLLI expiry, max_age == 1:\n");
3333
3334 cfg.tlli_max_len = 0;
3335 cfg.tlli_max_age = 1;
3336 peer = gbproxy_peer_alloc(&cfg, 20);
3337 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3338
3339 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003340 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003341 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3342
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003343 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003344 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003345 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003346 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3347
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003348 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003349 OSMO_ASSERT(num_removed == 1);
3350 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3351
3352 dump_peers(stdout, 2, now + 2, &cfg);
3353
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003354 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003355 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003356 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003357 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003358 OSMO_ASSERT(tlli_info);
3359 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
3360
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003361 printf("\n");
3362
3363 gbproxy_peer_free(peer);
3364 }
3365
3366 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003367 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003368 int num_removed;
3369
3370 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
3371
3372 cfg.tlli_max_len = 0;
3373 cfg.tlli_max_age = 1;
3374 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003375 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
3376
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003377 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003378 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003379 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3380
3381 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003382 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003383 now + 1);
3384 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
3385
3386 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003387 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003388 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003389 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
3390
3391 dump_peers(stdout, 2, now + 2, &cfg);
3392
3393 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003394 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003395 OSMO_ASSERT(num_removed == 2);
3396 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3397
3398 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003399
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003400 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003401 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003402 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003403 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003404 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003405 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003406 OSMO_ASSERT(tlli_info);
3407 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
3408
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003409 printf("\n");
3410
3411 gbproxy_peer_free(peer);
3412 }
3413}
3414
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003415static void test_gbproxy_imsi_matching(void)
3416{
3417 struct gbproxy_config cfg = {0};
3418 struct gbproxy_peer *peer;
3419 const char *err_msg = NULL;
3420 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3421 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3422 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3423 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3424 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3425 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3426 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3427 const char *filter_re1 = ".*";
3428 const char *filter_re2 = "^1234";
3429 const char *filter_re3 = "^4321";
3430 const char *filter_re4_bad = "^12[";
3431
3432 printf("=== Test IMSI/TMSI matching ===\n\n");
3433
3434 gbproxy_init_config(&cfg);
3435 OSMO_ASSERT(cfg.check_imsi == 0);
3436
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003437 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003438 OSMO_ASSERT(cfg.check_imsi == 1);
3439
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003440 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003441 OSMO_ASSERT(cfg.check_imsi == 1);
3442
3443 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003444 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003445 OSMO_ASSERT(err_msg != NULL);
3446 OSMO_ASSERT(cfg.check_imsi == 0);
3447
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003448 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003449 OSMO_ASSERT(cfg.check_imsi == 1);
3450
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003451 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003452 OSMO_ASSERT(cfg.check_imsi == 0);
3453
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003454 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003455 OSMO_ASSERT(cfg.check_imsi == 1);
3456
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003457 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003458 OSMO_ASSERT(cfg.check_imsi == 0);
3459
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003460 peer = gbproxy_peer_alloc(&cfg, 20);
3461
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003462 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003463 OSMO_ASSERT(cfg.check_imsi == 1);
3464
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003465 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3466 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003467 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003468 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003469 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003470 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3471 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3472 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3473 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3474 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003475
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003476 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003477 OSMO_ASSERT(cfg.check_imsi == 1);
3478
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003479 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3480 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3481 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3482 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3483 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3484 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3485 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003486
3487 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3488
3489 gbproxy_peer_free(peer);
3490}
3491
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003492static struct log_info_cat gprs_categories[] = {
3493 [DGPRS] = {
3494 .name = "DGPRS",
3495 .description = "GPRS Packet Service",
3496 .enabled = 1, .loglevel = LOGL_DEBUG,
3497 },
3498 [DNS] = {
3499 .name = "DNS",
3500 .description = "GPRS Network Service (NS)",
3501 .enabled = 1, .loglevel = LOGL_INFO,
3502 },
3503 [DBSSGP] = {
3504 .name = "DBSSGP",
3505 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3506 .enabled = 1, .loglevel = LOGL_DEBUG,
3507 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003508};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003509
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003510static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003511 .cat = gprs_categories,
3512 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003513};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003514
3515int main(int argc, char **argv)
3516{
3517 osmo_init_logging(&info);
3518 log_set_use_color(osmo_stderr_target, 0);
3519 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003520 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003521
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003522 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003523 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3524 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003525
3526 rate_ctr_init(NULL);
3527
3528 setlinebuf(stdout);
3529
3530 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003531 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003532 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003533 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003534 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003535 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003536 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003537 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003538 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003539 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003540 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003541 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003542 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003543
3544 exit(EXIT_SUCCESS);
3545}