blob: f2f8546f62e3bb0c68838592ae7f91650e778cef [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 Erlbeckc53f2a62014-08-15 14:56:28 +0200196/* DTAP - Identity Request */
197static const unsigned char dtap_identity_req[] = {
198 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200199};
200
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200201/* DTAP - Identity Response */
202static const unsigned char dtap_identity_resp[] = {
203 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
204 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200205};
206
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200207/* DTAP - Identity Response, IMSI 2 */
208static const unsigned char dtap_identity2_resp[] = {
209 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
210 0x16, 0x17, 0x18
211};
212
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200213/* DTAP - Attach Accept */
214static const unsigned char dtap_attach_acc[] = {
215 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
216 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
217 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200218};
219
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200220/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200221static const unsigned char dtap_attach_acc2[] = {
222 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
223 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
224 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
225};
226
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200227/* DTAP - Attach Complete */
228static const unsigned char dtap_attach_complete[] = {
229 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200230};
231
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200232/* DTAP - GMM Information */
233static const unsigned char dtap_gmm_information[] = {
234 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200235};
236
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200237/* DTAP - Routing Area Update Request */
238static const unsigned char dtap_ra_upd_req[] = {
239 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
240 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
241 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
242 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
243 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
244 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
245 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200246};
247
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200248/* DTAP - Routing Area Update Accept */
249static const unsigned char dtap_ra_upd_acc[] = {
250 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
251 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
252 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200253};
254
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200255/* DTAP - Routing Area Update Accept, P-TMSI 2 */
256static const unsigned char dtap_ra_upd_acc2[] = {
257 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
258 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
259 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
260};
261
262/* DTAP - Routing Area Update Accept, P-TMSI 3 */
263static const unsigned char dtap_ra_upd_acc3[] = {
264 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
265 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
266 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
267};
268
269/* DTAP - Routing Area Update Complete */
270static const unsigned char dtap_ra_upd_complete[] = {
271 0x08, 0x0a
272};
273
274
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200275/* DTAP - Activate PDP Context Request */
276static const unsigned char dtap_act_pdp_ctx_req[] = {
277 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200278 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
280 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
281 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
282 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200283 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200284};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200285
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200286/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200287/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200288static const unsigned char dtap_detach_po_req[] = {
289 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
290 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200291};
292
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200293/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200294/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200295static const unsigned char dtap_detach_req[] = {
296 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
297 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200298};
299
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200300/* DTAP - Detach Accept */
301static const unsigned char dtap_detach_acc[] = {
302 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200303};
304
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200305/* GPRS-LLC - SAPI: LLGMM, U, XID */
306static const unsigned char llc_u_xid_ul[] = {
307 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
308 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
309};
310
311/* GPRS-LLC - SAPI: LLGMM, U, XID */
312static const unsigned char llc_u_xid_dl[] = {
313 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
314 0xe4, 0xa9, 0x1a, 0x9e
315};
316
317/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
318static const unsigned char llc_ui_ll11_dns_query_ul[] = {
319 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
320 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
321 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
322 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
323 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
324 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
325 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
326 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
327 0x8f, 0x07
328};
329
330/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
331static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
332 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
333 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
334 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
335 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
336 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
337 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
338 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
339 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
340 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
341 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
342 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
343 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
344 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
345 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
346 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
347 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
348 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
349 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
350 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
351 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
352 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
353 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
354 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
355 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
356 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
357 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
358};
359
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200360static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
361 struct sockaddr_in *peer, const unsigned char* data,
362 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200363
364static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
365 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
366{
367 /* GPRS Network Service, PDU type: NS_RESET,
368 */
369 unsigned char msg[12] = {
370 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
371 0x04, 0x82, 0x11, 0x22
372 };
373
374 msg[3] = cause;
375 msg[6] = nsvci / 256;
376 msg[7] = nsvci % 256;
377 msg[10] = nsei / 256;
378 msg[11] = nsei % 256;
379
380 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
381}
382
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200383static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
384 uint16_t nsvci, uint16_t nsei)
385{
386 /* GPRS Network Service, PDU type: NS_RESET_ACK,
387 */
388 unsigned char msg[9] = {
389 0x03, 0x01, 0x82, 0x11, 0x22,
390 0x04, 0x82, 0x11, 0x22
391 };
392
393 msg[3] = nsvci / 256;
394 msg[4] = nsvci % 256;
395 msg[7] = nsei / 256;
396 msg[8] = nsei % 256;
397
398 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
399}
400
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200401static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
402{
403 /* GPRS Network Service, PDU type: NS_ALIVE */
404 unsigned char msg[1] = {
405 0x0a
406 };
407
408 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
409}
410
411static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
412{
413 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
414 unsigned char msg[1] = {
415 0x0b
416 };
417
418 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
419}
420
421static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
422{
423 /* GPRS Network Service, PDU type: NS_UNBLOCK */
424 unsigned char msg[1] = {
425 0x06
426 };
427
428 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
429}
430
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200431static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
432{
433 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
434 unsigned char msg[1] = {
435 0x07
436 };
437
438 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
439}
440
441static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
442 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200443 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
444{
445 /* GPRS Network Service, PDU type: NS_UNITDATA */
446 unsigned char msg[4096] = {
447 0x00, 0x00, 0x00, 0x00
448 };
449
450 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
451
452 msg[2] = nsbvci / 256;
453 msg[3] = nsbvci % 256;
454 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
455
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200456 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200457}
458
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200459static void send_bssgp_ul_unitdata(
460 struct gprs_ns_inst *nsi, const char *text,
461 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
462 struct gprs_ra_id *raid, uint16_t cell_id,
463 const uint8_t *llc_msg, size_t llc_msg_size)
464{
465 /* GPRS Network Service, PDU type: NS_UNITDATA */
466 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
467 unsigned char msg[4096] = {
468 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
469 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
470 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
471 };
472
473 size_t bssgp_msg_size = 23 + llc_msg_size;
474
475 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
476
477 gsm48_construct_ra(msg + 10, raid);
478 msg[1] = (uint8_t)(tlli >> 24);
479 msg[2] = (uint8_t)(tlli >> 16);
480 msg[3] = (uint8_t)(tlli >> 8);
481 msg[4] = (uint8_t)(tlli >> 0);
482 msg[16] = cell_id / 256;
483 msg[17] = cell_id % 256;
484 msg[21] = llc_msg_size / 256;
485 msg[22] = llc_msg_size % 256;
486 memcpy(msg + 23, llc_msg, llc_msg_size);
487
488 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
489 src_addr, nsbvci, msg, bssgp_msg_size);
490}
491
492static void send_bssgp_dl_unitdata(
493 struct gprs_ns_inst *nsi, const char *text,
494 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
495 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
496 const uint8_t *llc_msg, size_t llc_msg_size)
497{
498 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
499 unsigned char msg[4096] = {
500 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
501 0x16, 0x82, 0x02, 0x58,
502 };
503 unsigned char racap_drx[] = {
504 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
505 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
506 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
507 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
508 };
509
510 size_t bssgp_msg_size = 0;
511
512 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
513
514 msg[1] = (uint8_t)(tlli >> 24);
515 msg[2] = (uint8_t)(tlli >> 16);
516 msg[3] = (uint8_t)(tlli >> 8);
517 msg[4] = (uint8_t)(tlli >> 0);
518
519 bssgp_msg_size = 12;
520
521 if (with_racap_drx) {
522 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
523 bssgp_msg_size += sizeof(racap_drx);
524 }
525
526 if (imsi) {
527 OSMO_ASSERT(imsi_size <= 127);
528 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
529 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
530 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
531 bssgp_msg_size += 2 + imsi_size;
532 }
533
534 if ((bssgp_msg_size % 4) != 0) {
535 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
536 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
537 msg[bssgp_msg_size + 1] = 0x80 | abytes;
538 memset(msg + bssgp_msg_size + 2, 0, abytes);
539 bssgp_msg_size += 2 + abytes;
540 }
541
542 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
543 if (llc_msg_size < 128) {
544 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
545 bssgp_msg_size += 2;
546 } else {
547 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
548 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
549 bssgp_msg_size += 3;
550 }
551 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
552 bssgp_msg_size += llc_msg_size;
553
554
555 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
556 src_addr, nsbvci, msg, bssgp_msg_size);
557}
558
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200559static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
560 uint16_t bvci)
561{
562 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
563 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200564 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200565 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200566 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
567 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200568 };
569
570 msg[3] = bvci / 256;
571 msg[4] = bvci % 256;
572
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200573 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
574}
575
576static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
577 struct sockaddr_in *src_addr, uint16_t bvci)
578{
579 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
580 * BSSGP RESET_ACK */
581 static unsigned char msg[5] = {
582 0x23, 0x04, 0x82, 0x00,
583 0x00
584 };
585
586 msg[3] = bvci / 256;
587 msg[4] = bvci % 256;
588
589 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200590}
591
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200592static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
593 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200594 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200595 struct gprs_ra_id *raid)
596{
597 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
598 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200599 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
600 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200601 };
602
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200603 msg[3] = (uint8_t)(tlli >> 24);
604 msg[4] = (uint8_t)(tlli >> 16);
605 msg[5] = (uint8_t)(tlli >> 8);
606 msg[6] = (uint8_t)(tlli >> 0);
607
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200608 gsm48_construct_ra(msg + 9, raid);
609
610 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
611}
612
613static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
614 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200615 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200616 struct gprs_ra_id *raid)
617{
618 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
619 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200620 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
621 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200622 0x81, 0x01
623 };
624
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200625 msg[3] = (uint8_t)(tlli >> 24);
626 msg[4] = (uint8_t)(tlli >> 16);
627 msg[5] = (uint8_t)(tlli >> 8);
628 msg[6] = (uint8_t)(tlli >> 0);
629
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200630 gsm48_construct_ra(msg + 9, raid);
631
632 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
633}
634
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200635static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
636 struct sockaddr_in *src_addr,
637 uint16_t bvci, uint32_t tlli,
638 unsigned n_frames, unsigned n_octets)
639{
640 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
641 unsigned char msg[] = {
642 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
643 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
644 /* n octets */ 0xff, 0xff, 0xff
645 };
646
647 msg[3] = (uint8_t)(tlli >> 24);
648 msg[4] = (uint8_t)(tlli >> 16);
649 msg[5] = (uint8_t)(tlli >> 8);
650 msg[6] = (uint8_t)(tlli >> 0);
651 msg[9] = (uint8_t)(n_frames);
652 msg[12] = (uint8_t)(bvci >> 8);
653 msg[13] = (uint8_t)(bvci >> 0);
654 msg[16] = (uint8_t)(n_octets >> 16);
655 msg[17] = (uint8_t)(n_octets >> 8);
656 msg[18] = (uint8_t)(n_octets >> 0);
657
658 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
659}
660
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200661static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
662 struct sockaddr_in *src_addr,
663 uint16_t bvci, uint8_t tag)
664{
665 /* GPRS Network Service, PDU type: NS_UNITDATA,
666 * BSSGP FLOW_CONTROL_BVC */
667 unsigned char msg[] = {
668 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
669 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
670 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
671 };
672
673 msg[3] = tag;
674
675 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
676 msg, sizeof(msg));
677}
678
679static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
680 struct sockaddr_in *src_addr,
681 uint16_t bvci, uint8_t tag)
682{
683 /* GPRS Network Service, PDU type: NS_UNITDATA,
684 * BSSGP FLOW_CONTROL_BVC_ACK */
685 unsigned char msg[] = {
686 0x27, 0x1e, 0x81, /* Tag */ 0xce
687 };
688
689 msg[3] = tag;
690
691 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
692 msg, sizeof(msg));
693}
694
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200695static void send_llc_ul_ui(
696 struct gprs_ns_inst *nsi, const char *text,
697 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
698 struct gprs_ra_id *raid, uint16_t cell_id,
699 unsigned sapi, unsigned nu,
700 const uint8_t *msg, size_t msg_size)
701{
702 unsigned char llc_msg[4096] = {
703 0x00, 0xc0, 0x01
704 };
705
706 size_t llc_msg_size = 3 + msg_size + 3;
707 uint8_t e_bit = 0;
708 uint8_t pm_bit = 1;
709 unsigned fcs;
710
711 nu &= 0x01ff;
712
713 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
714
715 llc_msg[0] = (sapi & 0x0f);
716 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
717 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
718
719 memcpy(llc_msg + 3, msg, msg_size);
720
721 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
722 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
723 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
724 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
725
726 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
727 src_addr, nsbvci, tlli, raid, cell_id,
728 llc_msg, llc_msg_size);
729}
730
731static void send_llc_dl_ui(
732 struct gprs_ns_inst *nsi, const char *text,
733 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
734 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
735 unsigned sapi, unsigned nu,
736 const uint8_t *msg, size_t msg_size)
737{
738 /* GPRS Network Service, PDU type: NS_UNITDATA */
739 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
740 unsigned char llc_msg[4096] = {
741 0x00, 0x00, 0x01
742 };
743
744 size_t llc_msg_size = 3 + msg_size + 3;
745 uint8_t e_bit = 0;
746 uint8_t pm_bit = 1;
747 unsigned fcs;
748
749 nu &= 0x01ff;
750
751 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
752
753 llc_msg[0] = 0x40 | (sapi & 0x0f);
754 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
755 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
756
757 memcpy(llc_msg + 3, msg, msg_size);
758
759 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
760 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
761 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
762 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
763
764 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
765 src_addr, nsbvci, tlli,
766 with_racap_drx, imsi, imsi_size,
767 llc_msg, llc_msg_size);
768}
769
770
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200771static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
772 uint16_t nsvci, uint16_t nsei)
773{
774 printf("Setup NS-VC: remote 0x%08x:%d, "
775 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
776 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
777 nsvci, nsvci, nsei, nsei);
778
779 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
780 send_ns_alive(nsi, src_addr);
781 send_ns_unblock(nsi, src_addr);
782 send_ns_alive_ack(nsi, src_addr);
783}
784
785static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
786 uint16_t bvci)
787{
788 printf("Setup BSSGP: remote 0x%08x:%d, "
789 "BVCI 0x%04x(%d)\n\n",
790 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
791 bvci, bvci);
792
793 send_bssgp_reset(nsi, src_addr, bvci);
794}
795
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200796static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
797 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200798{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200799 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
800 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200801 send_ns_alive_ack(nsi, sgsn_peer);
802 send_ns_unblock_ack(nsi, sgsn_peer);
803 send_ns_alive(nsi, sgsn_peer);
804}
805
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200806static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
807{
808 sgsn_peer->sin_family = AF_INET;
809 sgsn_peer->sin_port = htons(32000);
810 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
811}
812
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200813static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
814{
815 sgsn_peer->sin_family = AF_INET;
816 sgsn_peer->sin_port = htons(32001);
817 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
818}
819
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200820static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
821{
822 size_t i;
823
824 for (i = 0; i < size; ++i) {
825 bss_peers[i].sin_family = AF_INET;
826 bss_peers[i].sin_port = htons((i + 1) * 1111);
827 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
828 }
829}
830
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200831int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
832 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
833
834/* override */
835int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
836 struct msgb *msg, uint16_t bvci)
837{
838 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
839 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200840 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200841
842 switch (event) {
843 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200844 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200845 default:
846 break;
847 }
848 return 0;
849}
850
851/* override */
852ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
853 const struct sockaddr *dest_addr, socklen_t addrlen)
854{
855 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
856 const struct sockaddr *, socklen_t);
857 static sendto_t real_sendto = NULL;
858 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200859 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200860
861 if (!real_sendto)
862 real_sendto = dlsym(RTLD_NEXT, "sendto");
863
864 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200865 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
866 dest_host, dest_port,
867 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200868 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200869 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
870 dest_host, dest_port,
871 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200872 else if (dest_host == REMOTE_SGSN2_ADDR)
873 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
874 dest_host, dest_port,
875 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200876 else
877 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
878
879 return len;
880}
881
882/* override */
883int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
884{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200885 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
886 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200887 uint16_t bvci = msgb_bvci(msg);
888 uint16_t nsei = msgb_nsei(msg);
889
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200890 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200891
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200892 if (!real_gprs_ns_sendmsg)
893 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
894
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200895 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200896 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
897 "msg length %d (%s)\n",
898 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200899 else if (nsei == SGSN2_NSEI)
900 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
901 "msg length %d (%s)\n",
902 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200903 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200904 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
905 "msg length %d (%s)\n",
906 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200907
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200908 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200909}
910
911static void dump_rate_ctr_group(FILE *stream, const char *prefix,
912 struct rate_ctr_group *ctrg)
913{
914 unsigned int i;
915
916 for (i = 0; i < ctrg->desc->num_ctr; i++) {
917 struct rate_ctr *ctr = &ctrg->ctr[i];
918 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
919 fprintf(stream, " %s%s: %llu%s",
920 prefix, ctrg->desc->ctr_desc[i].description,
921 (long long)ctr->current,
922 "\n");
923 };
924}
925
926/* Signal handler for signals from NS layer */
927static int test_signal(unsigned int subsys, unsigned int signal,
928 void *handler_data, void *signal_data)
929{
930 struct ns_signal_data *nssd = signal_data;
931 int rc;
932
933 if (subsys != SS_L_NS)
934 return 0;
935
936 switch (signal) {
937 case S_NS_RESET:
938 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
939 nssd->nsvc->nsvci,
940 gprs_ns_ll_str(nssd->nsvc));
941 break;
942
943 case S_NS_ALIVE_EXP:
944 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
945 nssd->nsvc->nsvci,
946 gprs_ns_ll_str(nssd->nsvc));
947 break;
948
949 case S_NS_BLOCK:
950 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
951 nssd->nsvc->nsvci,
952 gprs_ns_ll_str(nssd->nsvc));
953 break;
954
955 case S_NS_UNBLOCK:
956 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
957 nssd->nsvc->nsvci,
958 gprs_ns_ll_str(nssd->nsvc));
959 break;
960
961 case S_NS_REPLACED:
962 printf("==> got signal NS_REPLACED: 0x%04x/%s",
963 nssd->nsvc->nsvci,
964 gprs_ns_ll_str(nssd->nsvc));
965 printf(" -> 0x%04x/%s\n",
966 nssd->old_nsvc->nsvci,
967 gprs_ns_ll_str(nssd->old_nsvc));
968 break;
969
970 default:
971 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
972 nssd->nsvc->nsvci,
973 gprs_ns_ll_str(nssd->nsvc));
974 break;
975 }
976 printf("\n");
977 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
978 return rc;
979}
980
981static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
982{
983 struct msgb *msg;
984 int ret;
985 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
986 fprintf(stderr, "message too long: %d\n", data_len);
987 return -1;
988 }
989
990 msg = gprs_ns_msgb_alloc();
991 memmove(msg->data, data, data_len);
992 msg->l2h = msg->data;
993 msgb_put(msg, data_len);
994
995 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
996 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
997 osmo_hexdump(data, data_len));
998
999 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1000
1001 printf("result (%s) = %d\n\n", text, ret);
1002
1003 msgb_free(msg);
1004
1005 return ret;
1006}
1007
1008static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1009{
1010 struct gprs_nsvc *nsvc;
1011
1012 printf("Current NS-VCIs:\n");
1013 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1014 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001015 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001016 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001017 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1018 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1019 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001020 );
1021 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1022 }
1023 printf("\n");
1024}
1025
1026static void test_gbproxy()
1027{
1028 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1029 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001030 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001031
1032 bssgp_nsi = nsi;
1033 gbcfg.nsi = bssgp_nsi;
1034 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1035
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001036 configure_sgsn_peer(&sgsn_peer);
1037 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001038
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001039 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001040 printf("--- Initialise SGSN ---\n\n");
1041
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001042 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001043 gprs_dump_nsi(nsi);
1044
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001045 printf("--- Initialise BSS 1 ---\n\n");
1046
1047 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1048 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1049 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001050 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001051
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001052 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1053
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001054 printf("--- Initialise BSS 2 ---\n\n");
1055
1056 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1057 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1058 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001059 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001060
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001061 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1062
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001063 printf("--- Move BSS 1 to new port ---\n\n");
1064
1065 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1066 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001067 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001068
1069 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1070
1071 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1072 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001073 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001074
1075 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1076
1077 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1078 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001079 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001080
1081 printf("--- Move BSS 2 to new port ---\n\n");
1082
1083 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1084 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001085 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001086
1087 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1088
1089 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
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 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1094
1095 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1096 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001097 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001098
1099 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1100
1101 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1102 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001103 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001104
1105 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1106
1107 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1108
1109 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1110 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001111 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001112
1113 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1114
1115 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1116
1117 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1118 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001119 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001120
1121 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1122
1123 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1124
1125 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1126
1127 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1128
1129 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1130
1131 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1132
1133 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1134
1135 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1136
1137 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1138
1139 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1140
1141 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1142
1143 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1144
1145 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1146
1147 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1148
1149 setup_bssgp(nsi, &bss_peer[2], 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
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001153 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001154
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001155 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1156
1157 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1158
1159 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1160
1161 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1162
1163 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1164
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001165 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1166
1167 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1168
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001169 /* Find peer */
1170 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1171 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1172 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1173 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1174 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1175 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1176
1177
1178 /* Cleanup */
1179 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1180 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1181 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1182 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1183 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1184
1185 dump_peers(stdout, 0, 0, &gbcfg);
1186
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001187 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001188
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001189 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001190 gprs_ns_destroy(nsi);
1191 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001192}
1193
1194static void test_gbproxy_ident_changes()
1195{
1196 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1197 struct sockaddr_in bss_peer[1] = {{0},};
1198 struct sockaddr_in sgsn_peer= {0};
1199 uint16_t nsei[2] = {0x1000, 0x2000};
1200 uint16_t nsvci[2] = {0x1001, 0x2001};
1201 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1202
1203 bssgp_nsi = nsi;
1204 gbcfg.nsi = bssgp_nsi;
1205 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1206
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001207 configure_sgsn_peer(&sgsn_peer);
1208 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001209
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001210 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001211 printf("--- Initialise SGSN ---\n\n");
1212
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001213 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001214 gprs_dump_nsi(nsi);
1215
1216 printf("--- Initialise BSS 1 ---\n\n");
1217
1218 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1219 gprs_dump_nsi(nsi);
1220
1221 printf("--- Setup BVCI 1 ---\n\n");
1222
1223 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1224 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001225 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001226
1227 printf("--- Setup BVCI 2 ---\n\n");
1228
1229 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1230 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001231 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001232
1233 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1234
1235 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1236 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1237
1238 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1239
1240 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1241 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1242
1243 printf("--- Change NSEI ---\n\n");
1244
1245 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1246 gprs_dump_nsi(nsi);
1247
1248 printf("--- Setup BVCI 1 ---\n\n");
1249
1250 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1251 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001252 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001253
1254 printf("--- Setup BVCI 3 ---\n\n");
1255
1256 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1257 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001258 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001259
1260 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1261
1262 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1263 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1264
1265 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1266 " (should fail) ---\n\n");
1267
1268 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001269 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001270 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001271 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001272
1273 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1274
1275 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1276 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1277
1278 printf("--- Change NSVCI ---\n\n");
1279
1280 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1281 gprs_dump_nsi(nsi);
1282
1283 printf("--- Setup BVCI 1 ---\n\n");
1284
1285 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1286 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001287 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001288
1289 printf("--- Setup BVCI 4 ---\n\n");
1290
1291 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1292 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001293 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001294
1295 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1296
1297 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1298 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1299
1300 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1301 " (should fail) ---\n\n");
1302
1303 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001304 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001305 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001306 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001307
1308 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1309
1310 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1311 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1312
1313 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1314
1315 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1316 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1317
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001318 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001319 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001320
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001321 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001322 gprs_ns_destroy(nsi);
1323 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001324}
1325
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001326static void test_gbproxy_ra_patching()
1327{
1328 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1329 struct sockaddr_in bss_peer[1] = {{0},};
1330 struct sockaddr_in sgsn_peer= {0};
1331 struct gprs_ra_id rai_bss =
1332 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1333 struct gprs_ra_id rai_sgsn =
1334 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1335 struct gprs_ra_id rai_unknown =
1336 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001337 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001338 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001339 const uint32_t ptmsi = 0xefe2b700;
1340 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001341 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001342 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001343 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001344 struct gbproxy_tlli_info *tlli_info;
1345 struct gbproxy_peer *peer;
1346
1347 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001348
1349 bssgp_nsi = nsi;
1350 gbcfg.nsi = bssgp_nsi;
1351 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001352 gbcfg.core_mcc = 123;
1353 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001354 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001355 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001356 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001357
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001358 configure_sgsn_peer(&sgsn_peer);
1359 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001360
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001361 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001362 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001363 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1364 gbcfg.match_re, err_msg);
1365 exit(1);
1366 }
1367
1368
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001369 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001370 printf("--- Initialise SGSN ---\n\n");
1371
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001372 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001373 gprs_dump_nsi(nsi);
1374
1375 printf("--- Initialise BSS 1 ---\n\n");
1376
1377 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1378 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1379 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001380 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001381
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001382 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001383 OSMO_ASSERT(peer != NULL);
1384
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001385 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1386
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001387 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1388 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001389
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001390 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001391 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001392
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001393 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1394 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1395
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001396 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1397
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001398 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1399 foreign_tlli, &rai_bss, cell_id,
1400 GPRS_SAPI_GMM, 0,
1401 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001402
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001403 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1404
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001405 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1406 foreign_tlli, 0, NULL, 0,
1407 GPRS_SAPI_GMM, 0,
1408 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001409
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001410 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1411 foreign_tlli, &rai_bss, cell_id,
1412 GPRS_SAPI_GMM, 3,
1413 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001414
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001415 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1416 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1417
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001418 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1419 foreign_tlli, 1, imsi, sizeof(imsi),
1420 GPRS_SAPI_GMM, 1,
1421 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001422
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001423 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1424
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001425 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1426 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1427 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1428
1429 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1430 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1431 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1432
1433 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1434 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1435 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1436
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001437 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001438 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001439 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1440 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1441 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1442 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1443 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1444 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1445 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1446 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001447
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001448 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1449 local_tlli, &rai_bss, cell_id,
1450 GPRS_SAPI_GMM, 4,
1451 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001452
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001453 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1454
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001455 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001456 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001457 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1458 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1459 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1460 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1461 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1462 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1463 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1464 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001465
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001466 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001467 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1468 local_tlli, &rai_bss, cell_id,
1469 GPRS_SAPI_GMM, 3,
1470 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001471
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001472 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1473
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001474 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001475 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001476 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1477 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1478 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1479 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1480 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1481 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1482 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1483 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001484
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001485 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1486 local_tlli, 1, imsi, sizeof(imsi),
1487 GPRS_SAPI_GMM, 2,
1488 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001489
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001490 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1491
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001492 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001493 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001494 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1495 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1496 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1497 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001498
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001499 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001500 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1501 local_tlli, &rai_bss, cell_id,
1502 GPRS_SAPI_GMM, 3,
1503 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001504
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001505 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1506
Jacob Erlbeck73685282014-05-23 20:48:07 +02001507 gbcfg.core_apn[0] = 0;
1508 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001509
1510 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001511 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1512 local_tlli, &rai_bss, cell_id,
1513 GPRS_SAPI_GMM, 3,
1514 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001515
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001516 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1517
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001518 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001519
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001520 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001521 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1522 local_tlli, &rai_bss, cell_id,
1523 GPRS_SAPI_GMM, 6,
1524 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001525
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001526 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1527 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1528
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001529 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1530 local_tlli, 1, imsi, sizeof(imsi),
1531 GPRS_SAPI_GMM, 5,
1532 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001533
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001534 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001535
1536 printf("--- RA update ---\n\n");
1537
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001538 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1539 foreign_tlli, &rai_bss, 0x7080,
1540 GPRS_SAPI_GMM, 5,
1541 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001542
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001543 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1544
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001545 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1546 foreign_tlli, 1, imsi, sizeof(imsi),
1547 GPRS_SAPI_GMM, 6,
1548 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001549
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001550 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1551
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001552 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1554 local_tlli, &rai_bss, cell_id,
1555 GPRS_SAPI_GMM, 3,
1556 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001557
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001558 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1559
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001560 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001561
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001562 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001563 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1564 local_tlli, &rai_bss, cell_id,
1565 GPRS_SAPI_GMM, 6,
1566 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001567
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001568 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1569
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001570 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001571 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001572
1573 printf("--- Bad cases ---\n\n");
1574
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001575 /* The RAI in the Attach Request message differs from the RAI in the
1576 * BSSGP message, only patch the latter */
1577
1578 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1579 foreign_tlli2, &rai_bss, cell_id,
1580 GPRS_SAPI_GMM, 0,
1581 dtap_attach_req2, sizeof(dtap_attach_req2));
1582
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001583 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1584
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001585 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001586 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1587 local_tlli, &rai_bss, cell_id,
1588 GPRS_SAPI_GMM, 3,
1589 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001590
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001591 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001592 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001593
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001594 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001595 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001596
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001597 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001598 gprs_ns_destroy(nsi);
1599 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001600}
1601
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001602static void test_gbproxy_ptmsi_patching()
1603{
1604 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1605 struct sockaddr_in bss_peer[1] = {{0},};
1606 struct sockaddr_in sgsn_peer= {0};
1607 struct gprs_ra_id rai_bss =
1608 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1609 struct gprs_ra_id rai_sgsn =
1610 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001611 struct gprs_ra_id rai_wrong_mcc_sgsn =
1612 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001613 struct gprs_ra_id rai_unknown =
1614 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1615 uint16_t cell_id = 0x1234;
1616
1617 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001618 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1619 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001620 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001621 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1622 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001623 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001624 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001625
1626 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001627 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1628 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001629 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001630 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1631 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001632 const uint32_t foreign_bss_tlli = 0x8000dead;
1633
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001634
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001635 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1636 struct gbproxy_tlli_info *tlli_info;
1637 struct gbproxy_peer *peer;
1638 unsigned bss_nu = 0;
1639 unsigned sgsn_nu = 0;
1640
1641 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001642 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1643 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1644 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1645 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1646 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001647
1648 bssgp_nsi = nsi;
1649 gbcfg.nsi = bssgp_nsi;
1650 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1651 gbcfg.core_mcc = 123;
1652 gbcfg.core_mnc = 456;
1653 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1654 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1655 gbcfg.patch_ptmsi = 1;
1656 gbcfg.bss_ptmsi_state = 0;
1657 gbcfg.sgsn_tlli_state = 1;
1658
1659 configure_sgsn_peer(&sgsn_peer);
1660 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1661
1662 printf("=== %s ===\n", __func__);
1663 printf("--- Initialise SGSN ---\n\n");
1664
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001665 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001666
1667 printf("--- Initialise BSS 1 ---\n\n");
1668
1669 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1670 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1671
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001672 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001673 OSMO_ASSERT(peer != NULL);
1674
1675 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1676
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001677 gprs_dump_nsi(nsi);
1678 dump_global(stdout, 0);
1679 dump_peers(stdout, 0, 0, &gbcfg);
1680
1681 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1682
1683 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1684 foreign_bss_tlli, &rai_unknown, cell_id,
1685 GPRS_SAPI_GMM, bss_nu++,
1686 dtap_attach_req, sizeof(dtap_attach_req));
1687
1688 dump_peers(stdout, 0, 0, &gbcfg);
1689
1690 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1691 random_sgsn_tlli, 0, NULL, 0,
1692 GPRS_SAPI_GMM, sgsn_nu++,
1693 dtap_identity_req, sizeof(dtap_identity_req));
1694
1695 dump_peers(stdout, 0, 0, &gbcfg);
1696
1697 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1698 foreign_bss_tlli, &rai_bss, cell_id,
1699 GPRS_SAPI_GMM, bss_nu++,
1700 dtap_identity_resp, sizeof(dtap_identity_resp));
1701
1702 dump_peers(stdout, 0, 0, &gbcfg);
1703
1704 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1705 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1706 GPRS_SAPI_GMM, sgsn_nu++,
1707 dtap_attach_acc, sizeof(dtap_attach_acc));
1708
1709 dump_peers(stdout, 0, 0, &gbcfg);
1710
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001711 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001712 OSMO_ASSERT(tlli_info);
1713 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1714 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1715 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1716 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1717 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1718 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1719 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1720 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1721 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1722 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1723
1724 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1725 local_bss_tlli, &rai_bss, cell_id,
1726 GPRS_SAPI_GMM, bss_nu++,
1727 dtap_attach_complete, sizeof(dtap_attach_complete));
1728
1729 dump_peers(stdout, 0, 0, &gbcfg);
1730
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001731 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001732 OSMO_ASSERT(tlli_info);
1733 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1734 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1735 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1736 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1737 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1738 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1739 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1740 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1741
1742 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1743 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1744 GPRS_SAPI_GMM, sgsn_nu++,
1745 dtap_gmm_information, sizeof(dtap_gmm_information));
1746
1747 dump_peers(stdout, 0, 0, &gbcfg);
1748
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001749 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001750 OSMO_ASSERT(tlli_info);
1751 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1752 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1753 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1754 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1755
Jacob Erlbeck82add782014-09-05 18:08:12 +02001756 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1757 local_bss_tlli, &rai_bss, cell_id,
1758 GPRS_SAPI_GMM, bss_nu++,
1759 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1760
1761 dump_peers(stdout, 0, 0, &gbcfg);
1762
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001763 /* Non-DTAP */
1764 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1765 local_bss_tlli, &rai_bss, cell_id,
1766 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1767
1768 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1769 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1770 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1771
1772 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1773 local_bss_tlli, &rai_bss, cell_id,
1774 llc_ui_ll11_dns_query_ul,
1775 sizeof(llc_ui_ll11_dns_query_ul));
1776
1777 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1778 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1779 llc_ui_ll11_dns_resp_dl,
1780 sizeof(llc_ui_ll11_dns_resp_dl));
1781
1782 dump_peers(stdout, 0, 0, &gbcfg);
1783
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001784 /* Repeated RA Update Requests */
1785 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1786 local_bss_tlli, &rai_bss, 0x7080,
1787 GPRS_SAPI_GMM, bss_nu++,
1788 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1789
1790 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1791 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1792 GPRS_SAPI_GMM, sgsn_nu++,
1793 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1794
1795 dump_peers(stdout, 0, 0, &gbcfg);
1796
1797 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1798 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1799 OSMO_ASSERT(tlli_info);
1800 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1801 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1802 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1803 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1804 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1805 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1806 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1807 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1808 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1809 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1810
1811 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1812 local_bss_tlli2, &rai_bss, 0x7080,
1813 GPRS_SAPI_GMM, bss_nu++,
1814 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1815
1816 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1817 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1818 GPRS_SAPI_GMM, sgsn_nu++,
1819 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1820
1821 dump_peers(stdout, 0, 0, &gbcfg);
1822
1823 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1824 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1825 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1826 OSMO_ASSERT(tlli_info);
1827 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1828 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1829 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1830 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1831 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1832 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1833 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1834 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1835 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1836 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1837
1838 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1839 local_bss_tlli3, &rai_bss, 0x7080,
1840 GPRS_SAPI_GMM, bss_nu++,
1841 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1842
1843 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1844
1845 OSMO_ASSERT(tlli_info);
1846 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1847 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1848 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1849 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1850
1851 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1852 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1853 GPRS_SAPI_GMM, sgsn_nu++,
1854 dtap_gmm_information, sizeof(dtap_gmm_information));
1855
1856 dump_peers(stdout, 0, 0, &gbcfg);
1857
1858 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1859 OSMO_ASSERT(tlli_info);
1860 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1861 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1862 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1863 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1864
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001865 /* Other messages */
1866 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001867 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001868
1869 dump_peers(stdout, 0, 0, &gbcfg);
1870
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001871 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001872
1873 dump_peers(stdout, 0, 0, &gbcfg);
1874
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001875 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001876
1877 dump_peers(stdout, 0, 0, &gbcfg);
1878
1879 /* Bad case: Invalid BVCI */
1880 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001881 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001882 dump_global(stdout, 0);
1883
1884 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001885 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001886
1887 dump_global(stdout, 0);
1888
1889 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001890 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001891 &rai_wrong_mcc_sgsn);
1892
1893 dump_global(stdout, 0);
1894
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001895 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
1896 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1897 unknown_sgsn_tlli, 1, NULL, 0,
1898 GPRS_SAPI_GMM, 2,
1899 dtap_gmm_information, sizeof(dtap_gmm_information));
1900
1901 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
1902 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1903 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
1904 GPRS_SAPI_GMM, 3,
1905 dtap_gmm_information, sizeof(dtap_gmm_information));
1906
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001907 /* Detach */
1908 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001909 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001910 GPRS_SAPI_GMM, bss_nu++,
1911 dtap_detach_req, sizeof(dtap_detach_req));
1912
1913 dump_peers(stdout, 0, 0, &gbcfg);
1914
1915 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001916 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001917 GPRS_SAPI_GMM, sgsn_nu++,
1918 dtap_detach_acc, sizeof(dtap_detach_acc));
1919
1920 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001921
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001922 dump_global(stdout, 0);
1923
1924 gbprox_reset(&gbcfg);
1925 gprs_ns_destroy(nsi);
1926 nsi = NULL;
1927}
1928
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001929static void test_gbproxy_imsi_acquisition()
1930{
1931 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1932 struct sockaddr_in bss_peer[1] = {{0},};
1933 struct sockaddr_in sgsn_peer= {0};
1934 struct gprs_ra_id rai_bss =
1935 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1936 struct gprs_ra_id rai_sgsn =
1937 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1938 struct gprs_ra_id rai_wrong_mcc_sgsn =
1939 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1940 struct gprs_ra_id rai_unknown =
1941 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1942 uint16_t cell_id = 0x1234;
1943
1944 const uint32_t sgsn_ptmsi = 0xefe2b700;
1945 const uint32_t local_sgsn_tlli = 0xefe2b700;
1946 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1947
1948 const uint32_t bss_ptmsi = 0xc00f7304;
1949 const uint32_t local_bss_tlli = 0xc00f7304;
1950 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001951 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001952
1953 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1954 struct gbproxy_tlli_info *tlli_info;
1955 struct gbproxy_peer *peer;
1956 unsigned bss_nu = 0;
1957 unsigned sgsn_nu = 0;
1958
1959 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1960
1961 bssgp_nsi = nsi;
1962 gbcfg.nsi = bssgp_nsi;
1963 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1964 gbcfg.core_mcc = 123;
1965 gbcfg.core_mnc = 456;
1966 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1967 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1968 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001969 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001970 gbcfg.bss_ptmsi_state = 0;
1971 gbcfg.sgsn_tlli_state = 1;
1972
1973 configure_sgsn_peer(&sgsn_peer);
1974 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1975
1976 printf("=== %s ===\n", __func__);
1977 printf("--- Initialise SGSN ---\n\n");
1978
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001979 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001980
1981 printf("--- Initialise BSS 1 ---\n\n");
1982
1983 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1984 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1985
1986 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1987 OSMO_ASSERT(peer != NULL);
1988
1989 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1990
1991 gprs_dump_nsi(nsi);
1992 dump_global(stdout, 0);
1993 dump_peers(stdout, 0, 0, &gbcfg);
1994
1995 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1996
1997 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001998 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001999 GPRS_SAPI_GMM, bss_nu++,
2000 dtap_attach_req, sizeof(dtap_attach_req));
2001
2002 dump_peers(stdout, 0, 0, &gbcfg);
2003
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002004 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2005 foreign_bss_tlli, &rai_bss, cell_id,
2006 GPRS_SAPI_GMM, bss_nu++,
2007 dtap_identity_resp, sizeof(dtap_identity_resp));
2008
2009 dump_peers(stdout, 0, 0, &gbcfg);
2010
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002011 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2012 random_sgsn_tlli, 0, NULL, 0,
2013 GPRS_SAPI_GMM, sgsn_nu++,
2014 dtap_identity_req, sizeof(dtap_identity_req));
2015
2016 dump_peers(stdout, 0, 0, &gbcfg);
2017
2018 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2019 foreign_bss_tlli, &rai_bss, cell_id,
2020 GPRS_SAPI_GMM, bss_nu++,
2021 dtap_identity_resp, sizeof(dtap_identity_resp));
2022
2023 dump_peers(stdout, 0, 0, &gbcfg);
2024
2025 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2026 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2027 GPRS_SAPI_GMM, sgsn_nu++,
2028 dtap_attach_acc, sizeof(dtap_attach_acc));
2029
2030 dump_peers(stdout, 0, 0, &gbcfg);
2031
2032 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2033 OSMO_ASSERT(tlli_info);
2034 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2035 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2036 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2037 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2038 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2039 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2040 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2041 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2042 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2043 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2044
2045 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2046 local_bss_tlli, &rai_bss, cell_id,
2047 GPRS_SAPI_GMM, bss_nu++,
2048 dtap_attach_complete, sizeof(dtap_attach_complete));
2049
2050 dump_peers(stdout, 0, 0, &gbcfg);
2051
2052 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2053 OSMO_ASSERT(tlli_info);
2054 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2055 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2056 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2057 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2058 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2059 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2060 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2061 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2062
2063 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2064 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2065 GPRS_SAPI_GMM, sgsn_nu++,
2066 dtap_gmm_information, sizeof(dtap_gmm_information));
2067
2068 dump_peers(stdout, 0, 0, &gbcfg);
2069
2070 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2071 OSMO_ASSERT(tlli_info);
2072 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2073 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2074 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2075 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2076
2077 /* Non-DTAP */
2078 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2079 local_bss_tlli, &rai_bss, cell_id,
2080 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2081
2082 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2083 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2084 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2085
2086 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2087 local_bss_tlli, &rai_bss, cell_id,
2088 llc_ui_ll11_dns_query_ul,
2089 sizeof(llc_ui_ll11_dns_query_ul));
2090
2091 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2092 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2093 llc_ui_ll11_dns_resp_dl,
2094 sizeof(llc_ui_ll11_dns_resp_dl));
2095
2096 dump_peers(stdout, 0, 0, &gbcfg);
2097
2098 /* Other messages */
2099 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2100 local_bss_tlli, 1, 12);
2101
2102 dump_peers(stdout, 0, 0, &gbcfg);
2103
2104 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2105 local_sgsn_tlli, 1, 12);
2106
2107 dump_peers(stdout, 0, 0, &gbcfg);
2108
2109 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2110
2111 dump_peers(stdout, 0, 0, &gbcfg);
2112
2113 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2114
2115 dump_peers(stdout, 0, 0, &gbcfg);
2116
2117 /* Bad case: Invalid BVCI */
2118 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2119 local_bss_tlli, 1, 12);
2120 dump_global(stdout, 0);
2121
2122 /* Bad case: Invalid RAI */
2123 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2124
2125 dump_global(stdout, 0);
2126
2127 /* Bad case: Invalid MCC (LAC ok) */
2128 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2129 &rai_wrong_mcc_sgsn);
2130
2131 dump_global(stdout, 0);
2132
2133 /* Detach */
2134 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2135 local_bss_tlli, &rai_bss, cell_id,
2136 GPRS_SAPI_GMM, bss_nu++,
2137 dtap_detach_req, sizeof(dtap_detach_req));
2138
2139 dump_peers(stdout, 0, 0, &gbcfg);
2140
2141 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2142 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2143 GPRS_SAPI_GMM, sgsn_nu++,
2144 dtap_detach_acc, sizeof(dtap_detach_acc));
2145
2146 dump_peers(stdout, 0, 0, &gbcfg);
2147
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002148 /* Special case: Repeated Attach Requests */
2149
2150 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2151 foreign_bss_tlli, &rai_unknown, cell_id,
2152 GPRS_SAPI_GMM, bss_nu++,
2153 dtap_attach_req, sizeof(dtap_attach_req));
2154
2155 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2156 foreign_bss_tlli, &rai_unknown, cell_id,
2157 GPRS_SAPI_GMM, bss_nu++,
2158 dtap_attach_req, sizeof(dtap_attach_req));
2159
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002160 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2161 foreign_bss_tlli, &rai_bss, cell_id,
2162 GPRS_SAPI_GMM, bss_nu++,
2163 dtap_detach_req, sizeof(dtap_detach_req));
2164
2165 dump_peers(stdout, 0, 0, &gbcfg);
2166
2167 /* Special case: Detach from an unknown TLLI */
2168
2169 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2170 other_bss_tlli, &rai_bss, cell_id,
2171 GPRS_SAPI_GMM, bss_nu++,
2172 dtap_detach_req, sizeof(dtap_detach_req));
2173
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002174 dump_peers(stdout, 0, 0, &gbcfg);
2175
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002176 dump_global(stdout, 0);
2177
2178 gbprox_reset(&gbcfg);
2179 gprs_ns_destroy(nsi);
2180 nsi = NULL;
2181}
2182
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002183static void test_gbproxy_secondary_sgsn()
2184{
2185 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2186 struct sockaddr_in bss_peer[1] = {{0},};
2187 struct sockaddr_in sgsn_peer[2]= {{0},};
2188 struct gprs_ra_id rai_bss =
2189 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2190 struct gprs_ra_id rai_sgsn =
2191 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2192 struct gprs_ra_id rai_unknown =
2193 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2194 uint16_t cell_id = 0x1234;
2195
2196 const uint32_t sgsn_ptmsi = 0xefe2b700;
2197 const uint32_t local_sgsn_tlli = 0xefe2b700;
2198 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2199
2200 const uint32_t bss_ptmsi = 0xc00f7304;
2201 const uint32_t local_bss_tlli = 0xc00f7304;
2202 const uint32_t foreign_bss_tlli = 0x8000dead;
2203
2204 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2205 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2206 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2207 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2208 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2209 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2210
2211 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2212 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2213 struct gbproxy_tlli_info *tlli_info;
2214 struct gbproxy_peer *peer;
2215 unsigned bss_nu = 0;
2216 unsigned sgsn_nu = 0;
2217
2218 const char *err_msg = NULL;
2219 const char *filter_re = "999999";
2220
2221 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2222 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2223
2224 bssgp_nsi = nsi;
2225 gbcfg.nsi = bssgp_nsi;
2226 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2227 gbcfg.core_mcc = 123;
2228 gbcfg.core_mnc = 456;
2229 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2230 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2231 gbcfg.patch_ptmsi = 1;
2232 gbcfg.acquire_imsi = 1;
2233 gbcfg.bss_ptmsi_state = 0;
2234 gbcfg.sgsn_tlli_state = 1;
2235 gbcfg.route_to_sgsn2 = 1;
2236 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2237
2238 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2239 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2240 err_msg);
2241 OSMO_ASSERT(err_msg == NULL);
2242 }
2243
2244 configure_sgsn_peer(&sgsn_peer[0]);
2245 configure_sgsn2_peer(&sgsn_peer[1]);
2246 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2247
2248 printf("=== %s ===\n", __func__);
2249 printf("--- Initialise SGSN 1 ---\n\n");
2250
2251 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2252
2253 printf("--- Initialise SGSN 2 ---\n\n");
2254
2255 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2256
2257 printf("--- Initialise BSS 1 ---\n\n");
2258
2259 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2260 setup_bssgp(nsi, &bss_peer[0], 0x0);
2261 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2262 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2263 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2264 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2265
2266 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2267 OSMO_ASSERT(peer != NULL);
2268
2269 gprs_dump_nsi(nsi);
2270 dump_global(stdout, 0);
2271 dump_peers(stdout, 0, 0, &gbcfg);
2272
2273 printf("--- Flow control ---\n\n");
2274
2275 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2276 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2277 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2278
2279 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2280
2281 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2282 foreign_bss_tlli, &rai_unknown, cell_id,
2283 GPRS_SAPI_GMM, bss_nu++,
2284 dtap_attach_req, sizeof(dtap_attach_req));
2285
2286 dump_peers(stdout, 0, 0, &gbcfg);
2287
2288 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2289 foreign_bss_tlli, &rai_bss, cell_id,
2290 GPRS_SAPI_GMM, bss_nu++,
2291 dtap_identity_resp, sizeof(dtap_identity_resp));
2292
2293 dump_peers(stdout, 0, 0, &gbcfg);
2294
2295 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2296 random_sgsn_tlli, 0, NULL, 0,
2297 GPRS_SAPI_GMM, sgsn_nu++,
2298 dtap_identity_req, sizeof(dtap_identity_req));
2299
2300 dump_peers(stdout, 0, 0, &gbcfg);
2301
2302 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2303 foreign_bss_tlli, &rai_bss, cell_id,
2304 GPRS_SAPI_GMM, bss_nu++,
2305 dtap_identity_resp, sizeof(dtap_identity_resp));
2306
2307 dump_peers(stdout, 0, 0, &gbcfg);
2308
2309 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2310 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2311 GPRS_SAPI_GMM, sgsn_nu++,
2312 dtap_attach_acc, sizeof(dtap_attach_acc));
2313
2314 dump_peers(stdout, 0, 0, &gbcfg);
2315
2316 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2317 OSMO_ASSERT(tlli_info);
2318 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2319 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2320 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2321 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2322 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2323 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2324 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2325 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2326 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2327 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2328
2329 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2330 local_bss_tlli, &rai_bss, cell_id,
2331 GPRS_SAPI_GMM, bss_nu++,
2332 dtap_attach_complete, sizeof(dtap_attach_complete));
2333
2334 dump_peers(stdout, 0, 0, &gbcfg);
2335
2336 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2337 OSMO_ASSERT(tlli_info);
2338 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2339 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2340 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2341 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2342 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2343 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2344 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2345 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2346
2347 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2348 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2349 GPRS_SAPI_GMM, sgsn_nu++,
2350 dtap_gmm_information, sizeof(dtap_gmm_information));
2351
2352 dump_peers(stdout, 0, 0, &gbcfg);
2353
2354 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2355 OSMO_ASSERT(tlli_info);
2356 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2357 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2358 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2359 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2360
2361 /* Non-DTAP */
2362 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2363 local_bss_tlli, &rai_bss, cell_id,
2364 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2365
2366 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2367 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2368 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2369
2370 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2371 local_bss_tlli, &rai_bss, cell_id,
2372 llc_ui_ll11_dns_query_ul,
2373 sizeof(llc_ui_ll11_dns_query_ul));
2374
2375 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2376 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2377 llc_ui_ll11_dns_resp_dl,
2378 sizeof(llc_ui_ll11_dns_resp_dl));
2379
2380 dump_peers(stdout, 0, 0, &gbcfg);
2381
2382 /* Other messages */
2383 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2384 local_bss_tlli, 1, 12);
2385
2386 dump_peers(stdout, 0, 0, &gbcfg);
2387
2388 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2389 local_sgsn_tlli, 1, 12);
2390
2391 dump_peers(stdout, 0, 0, &gbcfg);
2392
2393 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2394
2395 dump_peers(stdout, 0, 0, &gbcfg);
2396
2397 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2398
2399 dump_peers(stdout, 0, 0, &gbcfg);
2400
2401 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2402
2403 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2404 foreign_bss_tlli2, &rai_unknown, cell_id,
2405 GPRS_SAPI_GMM, bss_nu++,
2406 dtap_attach_req, sizeof(dtap_attach_req));
2407
2408 dump_peers(stdout, 0, 0, &gbcfg);
2409
2410 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2411 foreign_bss_tlli2, &rai_bss, cell_id,
2412 GPRS_SAPI_GMM, bss_nu++,
2413 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2414
2415 dump_peers(stdout, 0, 0, &gbcfg);
2416
2417 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2418 random_sgsn_tlli2, 0, NULL, 0,
2419 GPRS_SAPI_GMM, sgsn_nu++,
2420 dtap_identity_req, sizeof(dtap_identity_req));
2421
2422 dump_peers(stdout, 0, 0, &gbcfg);
2423
2424 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2425 foreign_bss_tlli2, &rai_bss, cell_id,
2426 GPRS_SAPI_GMM, bss_nu++,
2427 dtap_identity_resp, sizeof(dtap_identity_resp));
2428
2429 dump_peers(stdout, 0, 0, &gbcfg);
2430
2431 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2432 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2433 GPRS_SAPI_GMM, sgsn_nu++,
2434 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2435
2436 dump_peers(stdout, 0, 0, &gbcfg);
2437
2438 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2439 OSMO_ASSERT(tlli_info);
2440 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2441 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2442 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2443 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2444 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2445 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2446 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2447 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2448 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2449 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2450
2451 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2452 local_bss_tlli2, &rai_bss, cell_id,
2453 GPRS_SAPI_GMM, bss_nu++,
2454 dtap_attach_complete, sizeof(dtap_attach_complete));
2455
2456 dump_peers(stdout, 0, 0, &gbcfg);
2457
2458 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2459 OSMO_ASSERT(tlli_info);
2460 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2461 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2462 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2463 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2464 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2465 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2466 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2467 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2468
2469 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2470 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2471 GPRS_SAPI_GMM, sgsn_nu++,
2472 dtap_gmm_information, sizeof(dtap_gmm_information));
2473
2474 dump_peers(stdout, 0, 0, &gbcfg);
2475
2476 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2477 OSMO_ASSERT(tlli_info);
2478 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2479 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2480 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2481 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2482
2483 /* Non-DTAP */
2484 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2485 local_bss_tlli2, &rai_bss, cell_id,
2486 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2487
2488 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2489 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2490 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2491
2492 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2493 local_bss_tlli2, &rai_bss, cell_id,
2494 llc_ui_ll11_dns_query_ul,
2495 sizeof(llc_ui_ll11_dns_query_ul));
2496
2497 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2498 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2499 llc_ui_ll11_dns_resp_dl,
2500 sizeof(llc_ui_ll11_dns_resp_dl));
2501
2502 dump_peers(stdout, 0, 0, &gbcfg);
2503
2504 /* Other messages */
2505 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2506 local_bss_tlli2, 1, 12);
2507
2508 dump_peers(stdout, 0, 0, &gbcfg);
2509
2510 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2511 local_sgsn_tlli2, 1, 12);
2512
2513 dump_peers(stdout, 0, 0, &gbcfg);
2514
2515 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2516
2517 dump_peers(stdout, 0, 0, &gbcfg);
2518
2519 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2520
2521 dump_peers(stdout, 0, 0, &gbcfg);
2522
2523 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2524
2525 /* Detach */
2526 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2527 local_bss_tlli, &rai_bss, cell_id,
2528 GPRS_SAPI_GMM, bss_nu++,
2529 dtap_detach_req, sizeof(dtap_detach_req));
2530
2531 dump_peers(stdout, 0, 0, &gbcfg);
2532
2533 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2534 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2535 GPRS_SAPI_GMM, sgsn_nu++,
2536 dtap_detach_acc, sizeof(dtap_detach_acc));
2537
2538 dump_peers(stdout, 0, 0, &gbcfg);
2539
2540 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2541
2542 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2543 local_bss_tlli2, &rai_bss, cell_id,
2544 GPRS_SAPI_GMM, bss_nu++,
2545 dtap_detach_req, sizeof(dtap_detach_req));
2546
2547 dump_peers(stdout, 0, 0, &gbcfg);
2548
2549 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2550 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2551 GPRS_SAPI_GMM, sgsn_nu++,
2552 dtap_detach_acc, sizeof(dtap_detach_acc));
2553
2554 dump_peers(stdout, 0, 0, &gbcfg);
2555
2556 dump_global(stdout, 0);
2557
2558 gbprox_reset(&gbcfg);
2559 gprs_ns_destroy(nsi);
2560 nsi = NULL;
2561}
2562
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002563/* TODO: Move tlv testing to libosmocore */
2564int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2565int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2566 uint8_t **value);
2567int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2568 size_t *value_len);
2569int lv_shift(uint8_t **data, size_t *data_len,
2570 uint8_t **value, size_t *value_len);
2571
2572static void check_tlv_match(uint8_t **data, size_t *data_len,
2573 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2574{
2575 uint8_t *value;
2576 size_t value_len;
2577 int rc;
2578
2579 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2580 OSMO_ASSERT(rc == 0);
2581
2582 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002583 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002584 OSMO_ASSERT(value_len == exp_len);
2585 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2586}
2587
2588static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2589 uint8_t tag, size_t len, const uint8_t *exp_val)
2590{
2591 uint8_t *value;
2592 int rc;
2593
2594 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2595 OSMO_ASSERT(rc == 0);
2596
2597 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002598 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002599 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2600}
2601
2602static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2603 size_t len, const uint8_t *exp_val)
2604{
2605 uint8_t *value;
2606 int rc;
2607
2608 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002609 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002610 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2611}
2612
2613static void check_lv_shift(uint8_t **data, size_t *data_len,
2614 size_t exp_len, const uint8_t *exp_val)
2615{
2616 uint8_t *value;
2617 size_t value_len;
2618 int rc;
2619
2620 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002621 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002622 OSMO_ASSERT(value_len == exp_len);
2623 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2624}
2625
2626static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2627 const uint8_t *test_data)
2628{
2629 uint8_t buf[300] = {0};
2630
2631 uint8_t *unchanged_ptr = buf - 1;
2632 size_t unchanged_len = 0xdead;
2633 size_t tmp_data_len = data_len;
2634 uint8_t *value = unchanged_ptr;
2635 size_t value_len = unchanged_len;
2636 uint8_t *data = buf;
2637
2638 OSMO_ASSERT(data_len <= sizeof(buf));
2639
2640 tlv_put(data, tag, len, test_data);
2641 if (data_len < len + 2) {
2642 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2643 tag, &value, &value_len));
2644 OSMO_ASSERT(tmp_data_len == 0);
2645 OSMO_ASSERT(data == buf + data_len);
2646 OSMO_ASSERT(value == unchanged_ptr);
2647 OSMO_ASSERT(value_len == unchanged_len);
2648 } else {
2649 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2650 tag, &value, &value_len));
2651 OSMO_ASSERT(value != unchanged_ptr);
2652 OSMO_ASSERT(value_len != unchanged_len);
2653 }
2654}
2655
2656static void check_tv_fixed_match_data_len(size_t data_len,
2657 uint8_t tag, size_t len,
2658 const uint8_t *test_data)
2659{
2660 uint8_t buf[300] = {0};
2661
2662 uint8_t *unchanged_ptr = buf - 1;
2663 size_t tmp_data_len = data_len;
2664 uint8_t *value = unchanged_ptr;
2665 uint8_t *data = buf;
2666
2667 OSMO_ASSERT(data_len <= sizeof(buf));
2668
2669 tv_fixed_put(data, tag, len, test_data);
2670
2671 if (data_len < len + 1) {
2672 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2673 tag, len, &value));
2674 OSMO_ASSERT(tmp_data_len == 0);
2675 OSMO_ASSERT(data == buf + data_len);
2676 OSMO_ASSERT(value == unchanged_ptr);
2677 } else {
2678 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2679 tag, len, &value));
2680 OSMO_ASSERT(value != unchanged_ptr);
2681 }
2682}
2683
2684static void check_v_fixed_shift_data_len(size_t data_len,
2685 size_t len, const uint8_t *test_data)
2686{
2687 uint8_t buf[300] = {0};
2688
2689 uint8_t *unchanged_ptr = buf - 1;
2690 size_t tmp_data_len = data_len;
2691 uint8_t *value = unchanged_ptr;
2692 uint8_t *data = buf;
2693
2694 OSMO_ASSERT(data_len <= sizeof(buf));
2695
2696 memcpy(data, test_data, len);
2697
2698 if (data_len < len) {
2699 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2700 len, &value));
2701 OSMO_ASSERT(tmp_data_len == 0);
2702 OSMO_ASSERT(data == buf + data_len);
2703 OSMO_ASSERT(value == unchanged_ptr);
2704 } else {
2705 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2706 len, &value));
2707 OSMO_ASSERT(value != unchanged_ptr);
2708 }
2709}
2710
2711static void check_lv_shift_data_len(size_t data_len,
2712 size_t len, const uint8_t *test_data)
2713{
2714 uint8_t buf[300] = {0};
2715
2716 uint8_t *unchanged_ptr = buf - 1;
2717 size_t unchanged_len = 0xdead;
2718 size_t tmp_data_len = data_len;
2719 uint8_t *value = unchanged_ptr;
2720 size_t value_len = unchanged_len;
2721 uint8_t *data = buf;
2722
2723 lv_put(data, len, test_data);
2724 if (data_len < len + 1) {
2725 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2726 &value, &value_len));
2727 OSMO_ASSERT(tmp_data_len == 0);
2728 OSMO_ASSERT(data == buf + data_len);
2729 OSMO_ASSERT(value == unchanged_ptr);
2730 OSMO_ASSERT(value_len == unchanged_len);
2731 } else {
2732 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2733 &value, &value_len));
2734 OSMO_ASSERT(value != unchanged_ptr);
2735 OSMO_ASSERT(value_len != unchanged_len);
2736 }
2737}
2738
2739static void test_tlv_shift_functions()
2740{
2741 uint8_t test_data[1024];
2742 uint8_t buf[1024];
2743 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002744 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002745 uint8_t *data;
2746 size_t data_len;
2747 const uint8_t tag = 0x1a;
2748
2749 printf("Test shift functions\n");
2750
2751 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2752 test_data[i] = (uint8_t)i;
2753
2754 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002755 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002756
2757 memset(buf, 0xee, sizeof(buf));
2758 data_end = data = buf;
2759
2760 for (i = 0; i < iterations; i++) {
2761 data_end = tlv_put(data_end, tag, len, test_data);
2762 data_end = tv_fixed_put(data_end, tag, len, test_data);
2763 /* v_fixed_put */
2764 memcpy(data_end, test_data, len);
2765 data_end += len;
2766 data_end = lv_put(data_end, len, test_data);
2767 }
2768
2769 data_len = data_end - data;
2770 OSMO_ASSERT(data_len <= sizeof(buf));
2771
2772 for (i = 0; i < iterations; i++) {
2773 check_tlv_match(&data, &data_len, tag, len, test_data);
2774 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2775 check_v_fixed_shift(&data, &data_len, len, test_data);
2776 check_lv_shift(&data, &data_len, len, test_data);
2777 }
2778
2779 OSMO_ASSERT(data == data_end);
2780
2781 /* Test at end of data */
2782
2783 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2784 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2785 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2786 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2787
2788 /* Test invalid data_len */
2789 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2790 check_tlv_match_data_len(data_len, tag, len, test_data);
2791 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2792 check_v_fixed_shift_data_len(data_len, len, test_data);
2793 check_lv_shift_data_len(data_len, len, test_data);
2794 }
2795 }
2796}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002797
2798static void test_gbproxy_tlli_expire(void)
2799{
2800 struct gbproxy_config cfg = {0};
2801 struct gbproxy_peer *peer;
2802 const char *err_msg = NULL;
2803 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2804 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002805 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002806 const uint32_t tlli1 = 1234 | 0xc0000000;
2807 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002808 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002809 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002810 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002811
2812 printf("Test TLLI info expiry\n\n");
2813
2814 gbproxy_init_config(&cfg);
2815
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002816 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002817 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2818 err_msg);
2819 OSMO_ASSERT(err_msg == NULL);
2820 }
2821
2822 {
2823 struct gbproxy_tlli_info *tlli_info;
2824
2825 printf("Test TLLI replacement:\n");
2826
2827 cfg.tlli_max_len = 0;
2828 cfg.tlli_max_age = 0;
2829 peer = gbproxy_peer_alloc(&cfg, 20);
2830 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2831
2832 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002833 tlli_info = gbproxy_register_tlli(peer, tlli1,
2834 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002835 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002836 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002837 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2838
2839 /* replace the old entry */
2840 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002841 tlli_info = gbproxy_register_tlli(peer, tlli2,
2842 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002843 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002844 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002845 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2846
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002847 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002848
2849 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002850 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002851 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002852 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002853 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002854 OSMO_ASSERT(!tlli_info);
2855
2856 printf("\n");
2857
2858 gbproxy_peer_free(peer);
2859 }
2860
2861 {
2862 struct gbproxy_tlli_info *tlli_info;
2863
2864 printf("Test IMSI replacement:\n");
2865
2866 cfg.tlli_max_len = 0;
2867 cfg.tlli_max_age = 0;
2868 peer = gbproxy_peer_alloc(&cfg, 20);
2869 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2870
2871 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002872 tlli_info = gbproxy_register_tlli(peer, tlli1,
2873 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002874 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002875 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002876 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2877
2878 /* try to replace the old entry */
2879 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002880 tlli_info = gbproxy_register_tlli(peer, tlli1,
2881 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002882 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002883 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002884 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2885
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002886 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002887
2888 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002889 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002890 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002891 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002892 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002893 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002894
2895 printf("\n");
2896
2897 gbproxy_peer_free(peer);
2898 }
2899
2900 {
2901 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002902 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002903
2904 printf("Test TLLI expiry, max_len == 1:\n");
2905
2906 cfg.tlli_max_len = 1;
2907 cfg.tlli_max_age = 0;
2908 peer = gbproxy_peer_alloc(&cfg, 20);
2909 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2910
2911 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002912 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002913 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2914
2915 /* replace the old entry */
2916 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002917 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002918 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2919
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002920 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002921 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002922 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2923
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002924 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002925
2926 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002927 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002928 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002929 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002930 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002931 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002932
2933 printf("\n");
2934
2935 gbproxy_peer_free(peer);
2936 }
2937
2938 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002939 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002940 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002941
2942 printf("Test TLLI expiry, max_age == 1:\n");
2943
2944 cfg.tlli_max_len = 0;
2945 cfg.tlli_max_age = 1;
2946 peer = gbproxy_peer_alloc(&cfg, 20);
2947 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2948
2949 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002950 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002951 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2952
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002953 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002954 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002955 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002956 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2957
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002958 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002959 OSMO_ASSERT(num_removed == 1);
2960 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2961
2962 dump_peers(stdout, 2, now + 2, &cfg);
2963
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002964 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002965 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002966 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002967 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002968 OSMO_ASSERT(tlli_info);
2969 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2970
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002971 printf("\n");
2972
2973 gbproxy_peer_free(peer);
2974 }
2975
2976 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002977 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002978 int num_removed;
2979
2980 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2981
2982 cfg.tlli_max_len = 0;
2983 cfg.tlli_max_age = 1;
2984 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002985 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2986
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002987 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002988 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002989 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2990
2991 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002992 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002993 now + 1);
2994 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2995
2996 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002997 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2998 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002999 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
3000
3001 dump_peers(stdout, 2, now + 2, &cfg);
3002
3003 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003004 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003005 OSMO_ASSERT(num_removed == 2);
3006 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
3007
3008 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003009
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003010 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003011 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003012 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003013 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003014 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02003015 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003016 OSMO_ASSERT(tlli_info);
3017 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
3018
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003019 printf("\n");
3020
3021 gbproxy_peer_free(peer);
3022 }
3023}
3024
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003025static void test_gbproxy_imsi_matching(void)
3026{
3027 struct gbproxy_config cfg = {0};
3028 struct gbproxy_peer *peer;
3029 const char *err_msg = NULL;
3030 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3031 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3032 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3033 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3034 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3035 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3036 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3037 const char *filter_re1 = ".*";
3038 const char *filter_re2 = "^1234";
3039 const char *filter_re3 = "^4321";
3040 const char *filter_re4_bad = "^12[";
3041
3042 printf("=== Test IMSI/TMSI matching ===\n\n");
3043
3044 gbproxy_init_config(&cfg);
3045 OSMO_ASSERT(cfg.check_imsi == 0);
3046
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003047 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003048 OSMO_ASSERT(cfg.check_imsi == 1);
3049
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003050 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003051 OSMO_ASSERT(cfg.check_imsi == 1);
3052
3053 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003054 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003055 OSMO_ASSERT(err_msg != NULL);
3056 OSMO_ASSERT(cfg.check_imsi == 0);
3057
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003058 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003059 OSMO_ASSERT(cfg.check_imsi == 1);
3060
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003061 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003062 OSMO_ASSERT(cfg.check_imsi == 0);
3063
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003064 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003065 OSMO_ASSERT(cfg.check_imsi == 1);
3066
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003067 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003068 OSMO_ASSERT(cfg.check_imsi == 0);
3069
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003070 peer = gbproxy_peer_alloc(&cfg, 20);
3071
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003072 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003073 OSMO_ASSERT(cfg.check_imsi == 1);
3074
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003075 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3076 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003077 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003078 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003079 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003080 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3081 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3082 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3083 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3084 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003085
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003086 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003087 OSMO_ASSERT(cfg.check_imsi == 1);
3088
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003089 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3090 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3091 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3092 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3093 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3094 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3095 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003096
3097 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3098
3099 gbproxy_peer_free(peer);
3100}
3101
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003102static struct log_info_cat gprs_categories[] = {
3103 [DGPRS] = {
3104 .name = "DGPRS",
3105 .description = "GPRS Packet Service",
3106 .enabled = 1, .loglevel = LOGL_DEBUG,
3107 },
3108 [DNS] = {
3109 .name = "DNS",
3110 .description = "GPRS Network Service (NS)",
3111 .enabled = 1, .loglevel = LOGL_INFO,
3112 },
3113 [DBSSGP] = {
3114 .name = "DBSSGP",
3115 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3116 .enabled = 1, .loglevel = LOGL_DEBUG,
3117 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003118};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003119
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003120static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003121 .cat = gprs_categories,
3122 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003123};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003124
3125int main(int argc, char **argv)
3126{
3127 osmo_init_logging(&info);
3128 log_set_use_color(osmo_stderr_target, 0);
3129 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003130 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003131
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003132 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003133 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3134 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003135
3136 rate_ctr_init(NULL);
3137
3138 setlinebuf(stdout);
3139
3140 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003141 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003142 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003143 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003144 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003145 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003146 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003147 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003148 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003149 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003150 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003151 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003152
3153 exit(EXIT_SUCCESS);
3154}