blob: 1521c5fb73807a8ec346b4851dfa6a3387ae83cd [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
1393 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1394
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001395 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1396 foreign_tlli, &rai_bss, cell_id,
1397 GPRS_SAPI_GMM, 0,
1398 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001399
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001400 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1401 foreign_tlli, 0, NULL, 0,
1402 GPRS_SAPI_GMM, 0,
1403 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001404
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001405 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1406 foreign_tlli, &rai_bss, cell_id,
1407 GPRS_SAPI_GMM, 3,
1408 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001409
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001410 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1411 foreign_tlli, 1, imsi, sizeof(imsi),
1412 GPRS_SAPI_GMM, 1,
1413 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001414
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001415 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1416 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1417 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1418
1419 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1420 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1421 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1422
1423 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1424 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1425 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1426
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001427 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001428 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001429 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1430 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1431 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1432 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1433 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1434 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1435 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1436 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001437
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001438 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1439 local_tlli, &rai_bss, cell_id,
1440 GPRS_SAPI_GMM, 4,
1441 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001442
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001443 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001444 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001445 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1446 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1447 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1448 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1449 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1450 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1451 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1452 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001453
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001454 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001455 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1456 local_tlli, &rai_bss, cell_id,
1457 GPRS_SAPI_GMM, 3,
1458 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001459
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001460 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001461 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001462 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1463 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1464 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1465 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1466 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1467 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1468 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1469 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001470
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001471 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1472 local_tlli, 1, imsi, sizeof(imsi),
1473 GPRS_SAPI_GMM, 2,
1474 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001475
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001476 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001477 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001478 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1479 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1480 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1481 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001482
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001483 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001484 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1485 local_tlli, &rai_bss, cell_id,
1486 GPRS_SAPI_GMM, 3,
1487 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001488
Jacob Erlbeck73685282014-05-23 20:48:07 +02001489 gbcfg.core_apn[0] = 0;
1490 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001491
1492 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001493 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1494 local_tlli, &rai_bss, cell_id,
1495 GPRS_SAPI_GMM, 3,
1496 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001497
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001498 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001499
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001500 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001501 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1502 local_tlli, &rai_bss, cell_id,
1503 GPRS_SAPI_GMM, 6,
1504 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001505
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001506 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1507 local_tlli, 1, imsi, sizeof(imsi),
1508 GPRS_SAPI_GMM, 5,
1509 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001510
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001511 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001512
1513 printf("--- RA update ---\n\n");
1514
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001515 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1516 foreign_tlli, &rai_bss, 0x7080,
1517 GPRS_SAPI_GMM, 5,
1518 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001519
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001520 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1521 foreign_tlli, 1, imsi, sizeof(imsi),
1522 GPRS_SAPI_GMM, 6,
1523 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001524
1525 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001526 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1527 local_tlli, &rai_bss, cell_id,
1528 GPRS_SAPI_GMM, 3,
1529 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001530
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001531 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001532
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001533 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001534 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1535 local_tlli, &rai_bss, cell_id,
1536 GPRS_SAPI_GMM, 6,
1537 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001538
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001539 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001540 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001541
1542 printf("--- Bad cases ---\n\n");
1543
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001544 /* The RAI in the Attach Request message differs from the RAI in the
1545 * BSSGP message, only patch the latter */
1546
1547 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1548 foreign_tlli2, &rai_bss, cell_id,
1549 GPRS_SAPI_GMM, 0,
1550 dtap_attach_req2, sizeof(dtap_attach_req2));
1551
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001552 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &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 Erlbeckcf02eb12014-06-19 10:23:50 +02001557
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001558 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001559 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001560
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001561 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001562 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001563
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001564 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001565 gprs_ns_destroy(nsi);
1566 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001567}
1568
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001569static void test_gbproxy_ptmsi_patching()
1570{
1571 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1572 struct sockaddr_in bss_peer[1] = {{0},};
1573 struct sockaddr_in sgsn_peer= {0};
1574 struct gprs_ra_id rai_bss =
1575 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1576 struct gprs_ra_id rai_sgsn =
1577 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001578 struct gprs_ra_id rai_wrong_mcc_sgsn =
1579 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001580 struct gprs_ra_id rai_unknown =
1581 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1582 uint16_t cell_id = 0x1234;
1583
1584 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001585 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1586 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001587 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001588 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1589 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001590 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001591 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001592
1593 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001594 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1595 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001596 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001597 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1598 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001599 const uint32_t foreign_bss_tlli = 0x8000dead;
1600
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001601
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001602 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1603 struct gbproxy_tlli_info *tlli_info;
1604 struct gbproxy_peer *peer;
1605 unsigned bss_nu = 0;
1606 unsigned sgsn_nu = 0;
1607
1608 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001609 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1610 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1611 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1612 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1613 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001614
1615 bssgp_nsi = nsi;
1616 gbcfg.nsi = bssgp_nsi;
1617 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1618 gbcfg.core_mcc = 123;
1619 gbcfg.core_mnc = 456;
1620 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1621 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1622 gbcfg.patch_ptmsi = 1;
1623 gbcfg.bss_ptmsi_state = 0;
1624 gbcfg.sgsn_tlli_state = 1;
1625
1626 configure_sgsn_peer(&sgsn_peer);
1627 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1628
1629 printf("=== %s ===\n", __func__);
1630 printf("--- Initialise SGSN ---\n\n");
1631
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001632 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001633
1634 printf("--- Initialise BSS 1 ---\n\n");
1635
1636 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1637 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1638
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001639 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001640 OSMO_ASSERT(peer != NULL);
1641
1642 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1643
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001644 gprs_dump_nsi(nsi);
1645 dump_global(stdout, 0);
1646 dump_peers(stdout, 0, 0, &gbcfg);
1647
1648 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1649
1650 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1651 foreign_bss_tlli, &rai_unknown, cell_id,
1652 GPRS_SAPI_GMM, bss_nu++,
1653 dtap_attach_req, sizeof(dtap_attach_req));
1654
1655 dump_peers(stdout, 0, 0, &gbcfg);
1656
1657 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1658 random_sgsn_tlli, 0, NULL, 0,
1659 GPRS_SAPI_GMM, sgsn_nu++,
1660 dtap_identity_req, sizeof(dtap_identity_req));
1661
1662 dump_peers(stdout, 0, 0, &gbcfg);
1663
1664 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1665 foreign_bss_tlli, &rai_bss, cell_id,
1666 GPRS_SAPI_GMM, bss_nu++,
1667 dtap_identity_resp, sizeof(dtap_identity_resp));
1668
1669 dump_peers(stdout, 0, 0, &gbcfg);
1670
1671 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1672 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1673 GPRS_SAPI_GMM, sgsn_nu++,
1674 dtap_attach_acc, sizeof(dtap_attach_acc));
1675
1676 dump_peers(stdout, 0, 0, &gbcfg);
1677
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001678 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001679 OSMO_ASSERT(tlli_info);
1680 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1681 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1682 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1683 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1684 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1685 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1686 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1687 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1688 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1689 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1690
1691 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1692 local_bss_tlli, &rai_bss, cell_id,
1693 GPRS_SAPI_GMM, bss_nu++,
1694 dtap_attach_complete, sizeof(dtap_attach_complete));
1695
1696 dump_peers(stdout, 0, 0, &gbcfg);
1697
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001698 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001699 OSMO_ASSERT(tlli_info);
1700 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1701 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1702 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1703 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1704 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1705 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1706 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1707 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1708
1709 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1710 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1711 GPRS_SAPI_GMM, sgsn_nu++,
1712 dtap_gmm_information, sizeof(dtap_gmm_information));
1713
1714 dump_peers(stdout, 0, 0, &gbcfg);
1715
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001716 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001717 OSMO_ASSERT(tlli_info);
1718 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1719 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1720 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1721 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1722
Jacob Erlbeck82add782014-09-05 18:08:12 +02001723 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1724 local_bss_tlli, &rai_bss, cell_id,
1725 GPRS_SAPI_GMM, bss_nu++,
1726 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1727
1728 dump_peers(stdout, 0, 0, &gbcfg);
1729
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001730 /* Non-DTAP */
1731 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1732 local_bss_tlli, &rai_bss, cell_id,
1733 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1734
1735 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1736 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1737 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1738
1739 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1740 local_bss_tlli, &rai_bss, cell_id,
1741 llc_ui_ll11_dns_query_ul,
1742 sizeof(llc_ui_ll11_dns_query_ul));
1743
1744 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1745 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1746 llc_ui_ll11_dns_resp_dl,
1747 sizeof(llc_ui_ll11_dns_resp_dl));
1748
1749 dump_peers(stdout, 0, 0, &gbcfg);
1750
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001751 /* Repeated RA Update Requests */
1752 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1753 local_bss_tlli, &rai_bss, 0x7080,
1754 GPRS_SAPI_GMM, bss_nu++,
1755 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1756
1757 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1758 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1759 GPRS_SAPI_GMM, sgsn_nu++,
1760 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1761
1762 dump_peers(stdout, 0, 0, &gbcfg);
1763
1764 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1765 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1766 OSMO_ASSERT(tlli_info);
1767 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1768 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1769 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1770 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1771 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1772 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1773 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1774 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1775 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1776 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1777
1778 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1779 local_bss_tlli2, &rai_bss, 0x7080,
1780 GPRS_SAPI_GMM, bss_nu++,
1781 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1782
1783 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1784 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1785 GPRS_SAPI_GMM, sgsn_nu++,
1786 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1787
1788 dump_peers(stdout, 0, 0, &gbcfg);
1789
1790 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1791 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1792 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1793 OSMO_ASSERT(tlli_info);
1794 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1795 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1796 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1797 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1798 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1799 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1800 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1801 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1802 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1803 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1804
1805 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1806 local_bss_tlli3, &rai_bss, 0x7080,
1807 GPRS_SAPI_GMM, bss_nu++,
1808 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1809
1810 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1811
1812 OSMO_ASSERT(tlli_info);
1813 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1814 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1815 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1816 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1817
1818 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1819 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1820 GPRS_SAPI_GMM, sgsn_nu++,
1821 dtap_gmm_information, sizeof(dtap_gmm_information));
1822
1823 dump_peers(stdout, 0, 0, &gbcfg);
1824
1825 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1826 OSMO_ASSERT(tlli_info);
1827 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1828 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1829 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1830 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1831
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001832 /* Other messages */
1833 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001834 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001835
1836 dump_peers(stdout, 0, 0, &gbcfg);
1837
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001838 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001839
1840 dump_peers(stdout, 0, 0, &gbcfg);
1841
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001842 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001843
1844 dump_peers(stdout, 0, 0, &gbcfg);
1845
1846 /* Bad case: Invalid BVCI */
1847 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001848 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001849 dump_global(stdout, 0);
1850
1851 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001852 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001853
1854 dump_global(stdout, 0);
1855
1856 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001857 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001858 &rai_wrong_mcc_sgsn);
1859
1860 dump_global(stdout, 0);
1861
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001862 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
1863 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1864 unknown_sgsn_tlli, 1, NULL, 0,
1865 GPRS_SAPI_GMM, 2,
1866 dtap_gmm_information, sizeof(dtap_gmm_information));
1867
1868 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
1869 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1870 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
1871 GPRS_SAPI_GMM, 3,
1872 dtap_gmm_information, sizeof(dtap_gmm_information));
1873
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001874 /* Detach */
1875 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001876 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001877 GPRS_SAPI_GMM, bss_nu++,
1878 dtap_detach_req, sizeof(dtap_detach_req));
1879
1880 dump_peers(stdout, 0, 0, &gbcfg);
1881
1882 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001883 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001884 GPRS_SAPI_GMM, sgsn_nu++,
1885 dtap_detach_acc, sizeof(dtap_detach_acc));
1886
1887 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001888
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001889 dump_global(stdout, 0);
1890
1891 gbprox_reset(&gbcfg);
1892 gprs_ns_destroy(nsi);
1893 nsi = NULL;
1894}
1895
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001896static void test_gbproxy_imsi_acquisition()
1897{
1898 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1899 struct sockaddr_in bss_peer[1] = {{0},};
1900 struct sockaddr_in sgsn_peer= {0};
1901 struct gprs_ra_id rai_bss =
1902 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1903 struct gprs_ra_id rai_sgsn =
1904 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1905 struct gprs_ra_id rai_wrong_mcc_sgsn =
1906 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1907 struct gprs_ra_id rai_unknown =
1908 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1909 uint16_t cell_id = 0x1234;
1910
1911 const uint32_t sgsn_ptmsi = 0xefe2b700;
1912 const uint32_t local_sgsn_tlli = 0xefe2b700;
1913 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1914
1915 const uint32_t bss_ptmsi = 0xc00f7304;
1916 const uint32_t local_bss_tlli = 0xc00f7304;
1917 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001918 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001919
1920 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1921 struct gbproxy_tlli_info *tlli_info;
1922 struct gbproxy_peer *peer;
1923 unsigned bss_nu = 0;
1924 unsigned sgsn_nu = 0;
1925
1926 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1927
1928 bssgp_nsi = nsi;
1929 gbcfg.nsi = bssgp_nsi;
1930 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1931 gbcfg.core_mcc = 123;
1932 gbcfg.core_mnc = 456;
1933 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1934 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1935 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001936 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001937 gbcfg.bss_ptmsi_state = 0;
1938 gbcfg.sgsn_tlli_state = 1;
1939
1940 configure_sgsn_peer(&sgsn_peer);
1941 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1942
1943 printf("=== %s ===\n", __func__);
1944 printf("--- Initialise SGSN ---\n\n");
1945
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001946 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001947
1948 printf("--- Initialise BSS 1 ---\n\n");
1949
1950 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1951 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1952
1953 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1954 OSMO_ASSERT(peer != NULL);
1955
1956 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1957
1958 gprs_dump_nsi(nsi);
1959 dump_global(stdout, 0);
1960 dump_peers(stdout, 0, 0, &gbcfg);
1961
1962 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1963
1964 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001965 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001966 GPRS_SAPI_GMM, bss_nu++,
1967 dtap_attach_req, sizeof(dtap_attach_req));
1968
1969 dump_peers(stdout, 0, 0, &gbcfg);
1970
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001971 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1972 foreign_bss_tlli, &rai_bss, cell_id,
1973 GPRS_SAPI_GMM, bss_nu++,
1974 dtap_identity_resp, sizeof(dtap_identity_resp));
1975
1976 dump_peers(stdout, 0, 0, &gbcfg);
1977
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001978 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1979 random_sgsn_tlli, 0, NULL, 0,
1980 GPRS_SAPI_GMM, sgsn_nu++,
1981 dtap_identity_req, sizeof(dtap_identity_req));
1982
1983 dump_peers(stdout, 0, 0, &gbcfg);
1984
1985 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1986 foreign_bss_tlli, &rai_bss, cell_id,
1987 GPRS_SAPI_GMM, bss_nu++,
1988 dtap_identity_resp, sizeof(dtap_identity_resp));
1989
1990 dump_peers(stdout, 0, 0, &gbcfg);
1991
1992 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1993 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1994 GPRS_SAPI_GMM, sgsn_nu++,
1995 dtap_attach_acc, sizeof(dtap_attach_acc));
1996
1997 dump_peers(stdout, 0, 0, &gbcfg);
1998
1999 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2000 OSMO_ASSERT(tlli_info);
2001 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2002 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2003 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2004 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2005 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2006 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2007 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2008 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2009 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2010 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2011
2012 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2013 local_bss_tlli, &rai_bss, cell_id,
2014 GPRS_SAPI_GMM, bss_nu++,
2015 dtap_attach_complete, sizeof(dtap_attach_complete));
2016
2017 dump_peers(stdout, 0, 0, &gbcfg);
2018
2019 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2020 OSMO_ASSERT(tlli_info);
2021 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2022 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2023 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2024 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2025 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2026 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2027 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2028 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2029
2030 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2031 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2032 GPRS_SAPI_GMM, sgsn_nu++,
2033 dtap_gmm_information, sizeof(dtap_gmm_information));
2034
2035 dump_peers(stdout, 0, 0, &gbcfg);
2036
2037 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2038 OSMO_ASSERT(tlli_info);
2039 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2040 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2041 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2042 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2043
2044 /* Non-DTAP */
2045 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2046 local_bss_tlli, &rai_bss, cell_id,
2047 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2048
2049 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2050 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2051 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2052
2053 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2054 local_bss_tlli, &rai_bss, cell_id,
2055 llc_ui_ll11_dns_query_ul,
2056 sizeof(llc_ui_ll11_dns_query_ul));
2057
2058 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2059 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2060 llc_ui_ll11_dns_resp_dl,
2061 sizeof(llc_ui_ll11_dns_resp_dl));
2062
2063 dump_peers(stdout, 0, 0, &gbcfg);
2064
2065 /* Other messages */
2066 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2067 local_bss_tlli, 1, 12);
2068
2069 dump_peers(stdout, 0, 0, &gbcfg);
2070
2071 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2072 local_sgsn_tlli, 1, 12);
2073
2074 dump_peers(stdout, 0, 0, &gbcfg);
2075
2076 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2077
2078 dump_peers(stdout, 0, 0, &gbcfg);
2079
2080 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2081
2082 dump_peers(stdout, 0, 0, &gbcfg);
2083
2084 /* Bad case: Invalid BVCI */
2085 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2086 local_bss_tlli, 1, 12);
2087 dump_global(stdout, 0);
2088
2089 /* Bad case: Invalid RAI */
2090 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2091
2092 dump_global(stdout, 0);
2093
2094 /* Bad case: Invalid MCC (LAC ok) */
2095 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2096 &rai_wrong_mcc_sgsn);
2097
2098 dump_global(stdout, 0);
2099
2100 /* Detach */
2101 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2102 local_bss_tlli, &rai_bss, cell_id,
2103 GPRS_SAPI_GMM, bss_nu++,
2104 dtap_detach_req, sizeof(dtap_detach_req));
2105
2106 dump_peers(stdout, 0, 0, &gbcfg);
2107
2108 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2109 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2110 GPRS_SAPI_GMM, sgsn_nu++,
2111 dtap_detach_acc, sizeof(dtap_detach_acc));
2112
2113 dump_peers(stdout, 0, 0, &gbcfg);
2114
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002115 /* Special case: Repeated Attach Requests */
2116
2117 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2118 foreign_bss_tlli, &rai_unknown, cell_id,
2119 GPRS_SAPI_GMM, bss_nu++,
2120 dtap_attach_req, sizeof(dtap_attach_req));
2121
2122 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2123 foreign_bss_tlli, &rai_unknown, cell_id,
2124 GPRS_SAPI_GMM, bss_nu++,
2125 dtap_attach_req, sizeof(dtap_attach_req));
2126
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002127 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2128 foreign_bss_tlli, &rai_bss, cell_id,
2129 GPRS_SAPI_GMM, bss_nu++,
2130 dtap_detach_req, sizeof(dtap_detach_req));
2131
2132 dump_peers(stdout, 0, 0, &gbcfg);
2133
2134 /* Special case: Detach from an unknown TLLI */
2135
2136 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2137 other_bss_tlli, &rai_bss, cell_id,
2138 GPRS_SAPI_GMM, bss_nu++,
2139 dtap_detach_req, sizeof(dtap_detach_req));
2140
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002141 dump_peers(stdout, 0, 0, &gbcfg);
2142
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002143 dump_global(stdout, 0);
2144
2145 gbprox_reset(&gbcfg);
2146 gprs_ns_destroy(nsi);
2147 nsi = NULL;
2148}
2149
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002150static void test_gbproxy_secondary_sgsn()
2151{
2152 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2153 struct sockaddr_in bss_peer[1] = {{0},};
2154 struct sockaddr_in sgsn_peer[2]= {{0},};
2155 struct gprs_ra_id rai_bss =
2156 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2157 struct gprs_ra_id rai_sgsn =
2158 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2159 struct gprs_ra_id rai_unknown =
2160 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2161 uint16_t cell_id = 0x1234;
2162
2163 const uint32_t sgsn_ptmsi = 0xefe2b700;
2164 const uint32_t local_sgsn_tlli = 0xefe2b700;
2165 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2166
2167 const uint32_t bss_ptmsi = 0xc00f7304;
2168 const uint32_t local_bss_tlli = 0xc00f7304;
2169 const uint32_t foreign_bss_tlli = 0x8000dead;
2170
2171 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2172 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2173 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2174 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2175 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2176 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2177
2178 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2179 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2180 struct gbproxy_tlli_info *tlli_info;
2181 struct gbproxy_peer *peer;
2182 unsigned bss_nu = 0;
2183 unsigned sgsn_nu = 0;
2184
2185 const char *err_msg = NULL;
2186 const char *filter_re = "999999";
2187
2188 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2189 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2190
2191 bssgp_nsi = nsi;
2192 gbcfg.nsi = bssgp_nsi;
2193 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2194 gbcfg.core_mcc = 123;
2195 gbcfg.core_mnc = 456;
2196 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2197 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2198 gbcfg.patch_ptmsi = 1;
2199 gbcfg.acquire_imsi = 1;
2200 gbcfg.bss_ptmsi_state = 0;
2201 gbcfg.sgsn_tlli_state = 1;
2202 gbcfg.route_to_sgsn2 = 1;
2203 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2204
2205 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2206 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2207 err_msg);
2208 OSMO_ASSERT(err_msg == NULL);
2209 }
2210
2211 configure_sgsn_peer(&sgsn_peer[0]);
2212 configure_sgsn2_peer(&sgsn_peer[1]);
2213 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2214
2215 printf("=== %s ===\n", __func__);
2216 printf("--- Initialise SGSN 1 ---\n\n");
2217
2218 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2219
2220 printf("--- Initialise SGSN 2 ---\n\n");
2221
2222 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2223
2224 printf("--- Initialise BSS 1 ---\n\n");
2225
2226 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2227 setup_bssgp(nsi, &bss_peer[0], 0x0);
2228 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2229 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2230 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2231 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2232
2233 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2234 OSMO_ASSERT(peer != NULL);
2235
2236 gprs_dump_nsi(nsi);
2237 dump_global(stdout, 0);
2238 dump_peers(stdout, 0, 0, &gbcfg);
2239
2240 printf("--- Flow control ---\n\n");
2241
2242 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2243 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2244 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2245
2246 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2247
2248 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2249 foreign_bss_tlli, &rai_unknown, cell_id,
2250 GPRS_SAPI_GMM, bss_nu++,
2251 dtap_attach_req, sizeof(dtap_attach_req));
2252
2253 dump_peers(stdout, 0, 0, &gbcfg);
2254
2255 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2256 foreign_bss_tlli, &rai_bss, cell_id,
2257 GPRS_SAPI_GMM, bss_nu++,
2258 dtap_identity_resp, sizeof(dtap_identity_resp));
2259
2260 dump_peers(stdout, 0, 0, &gbcfg);
2261
2262 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2263 random_sgsn_tlli, 0, NULL, 0,
2264 GPRS_SAPI_GMM, sgsn_nu++,
2265 dtap_identity_req, sizeof(dtap_identity_req));
2266
2267 dump_peers(stdout, 0, 0, &gbcfg);
2268
2269 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2270 foreign_bss_tlli, &rai_bss, cell_id,
2271 GPRS_SAPI_GMM, bss_nu++,
2272 dtap_identity_resp, sizeof(dtap_identity_resp));
2273
2274 dump_peers(stdout, 0, 0, &gbcfg);
2275
2276 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2277 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2278 GPRS_SAPI_GMM, sgsn_nu++,
2279 dtap_attach_acc, sizeof(dtap_attach_acc));
2280
2281 dump_peers(stdout, 0, 0, &gbcfg);
2282
2283 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2284 OSMO_ASSERT(tlli_info);
2285 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2286 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2287 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2288 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2289 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2290 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2291 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2292 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2293 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2294 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2295
2296 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2297 local_bss_tlli, &rai_bss, cell_id,
2298 GPRS_SAPI_GMM, bss_nu++,
2299 dtap_attach_complete, sizeof(dtap_attach_complete));
2300
2301 dump_peers(stdout, 0, 0, &gbcfg);
2302
2303 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2304 OSMO_ASSERT(tlli_info);
2305 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2306 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2307 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2308 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2309 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2310 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2311 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2312 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2313
2314 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2315 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2316 GPRS_SAPI_GMM, sgsn_nu++,
2317 dtap_gmm_information, sizeof(dtap_gmm_information));
2318
2319 dump_peers(stdout, 0, 0, &gbcfg);
2320
2321 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2322 OSMO_ASSERT(tlli_info);
2323 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2324 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2325 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2326 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2327
2328 /* Non-DTAP */
2329 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2330 local_bss_tlli, &rai_bss, cell_id,
2331 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2332
2333 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2334 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2335 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2336
2337 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2338 local_bss_tlli, &rai_bss, cell_id,
2339 llc_ui_ll11_dns_query_ul,
2340 sizeof(llc_ui_ll11_dns_query_ul));
2341
2342 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2343 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2344 llc_ui_ll11_dns_resp_dl,
2345 sizeof(llc_ui_ll11_dns_resp_dl));
2346
2347 dump_peers(stdout, 0, 0, &gbcfg);
2348
2349 /* Other messages */
2350 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2351 local_bss_tlli, 1, 12);
2352
2353 dump_peers(stdout, 0, 0, &gbcfg);
2354
2355 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2356 local_sgsn_tlli, 1, 12);
2357
2358 dump_peers(stdout, 0, 0, &gbcfg);
2359
2360 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2361
2362 dump_peers(stdout, 0, 0, &gbcfg);
2363
2364 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2365
2366 dump_peers(stdout, 0, 0, &gbcfg);
2367
2368 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2369
2370 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2371 foreign_bss_tlli2, &rai_unknown, cell_id,
2372 GPRS_SAPI_GMM, bss_nu++,
2373 dtap_attach_req, sizeof(dtap_attach_req));
2374
2375 dump_peers(stdout, 0, 0, &gbcfg);
2376
2377 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2378 foreign_bss_tlli2, &rai_bss, cell_id,
2379 GPRS_SAPI_GMM, bss_nu++,
2380 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2381
2382 dump_peers(stdout, 0, 0, &gbcfg);
2383
2384 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2385 random_sgsn_tlli2, 0, NULL, 0,
2386 GPRS_SAPI_GMM, sgsn_nu++,
2387 dtap_identity_req, sizeof(dtap_identity_req));
2388
2389 dump_peers(stdout, 0, 0, &gbcfg);
2390
2391 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2392 foreign_bss_tlli2, &rai_bss, cell_id,
2393 GPRS_SAPI_GMM, bss_nu++,
2394 dtap_identity_resp, sizeof(dtap_identity_resp));
2395
2396 dump_peers(stdout, 0, 0, &gbcfg);
2397
2398 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2399 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2400 GPRS_SAPI_GMM, sgsn_nu++,
2401 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2402
2403 dump_peers(stdout, 0, 0, &gbcfg);
2404
2405 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2406 OSMO_ASSERT(tlli_info);
2407 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2408 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2409 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2410 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2411 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2412 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2413 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2414 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2415 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2416 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2417
2418 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2419 local_bss_tlli2, &rai_bss, cell_id,
2420 GPRS_SAPI_GMM, bss_nu++,
2421 dtap_attach_complete, sizeof(dtap_attach_complete));
2422
2423 dump_peers(stdout, 0, 0, &gbcfg);
2424
2425 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2426 OSMO_ASSERT(tlli_info);
2427 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2428 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2429 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2430 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2431 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2432 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2433 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2434 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2435
2436 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2437 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2438 GPRS_SAPI_GMM, sgsn_nu++,
2439 dtap_gmm_information, sizeof(dtap_gmm_information));
2440
2441 dump_peers(stdout, 0, 0, &gbcfg);
2442
2443 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2444 OSMO_ASSERT(tlli_info);
2445 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2446 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2447 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2448 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2449
2450 /* Non-DTAP */
2451 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2452 local_bss_tlli2, &rai_bss, cell_id,
2453 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2454
2455 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2456 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2457 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2458
2459 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2460 local_bss_tlli2, &rai_bss, cell_id,
2461 llc_ui_ll11_dns_query_ul,
2462 sizeof(llc_ui_ll11_dns_query_ul));
2463
2464 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2465 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2466 llc_ui_ll11_dns_resp_dl,
2467 sizeof(llc_ui_ll11_dns_resp_dl));
2468
2469 dump_peers(stdout, 0, 0, &gbcfg);
2470
2471 /* Other messages */
2472 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2473 local_bss_tlli2, 1, 12);
2474
2475 dump_peers(stdout, 0, 0, &gbcfg);
2476
2477 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2478 local_sgsn_tlli2, 1, 12);
2479
2480 dump_peers(stdout, 0, 0, &gbcfg);
2481
2482 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2483
2484 dump_peers(stdout, 0, 0, &gbcfg);
2485
2486 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2487
2488 dump_peers(stdout, 0, 0, &gbcfg);
2489
2490 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2491
2492 /* Detach */
2493 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2494 local_bss_tlli, &rai_bss, cell_id,
2495 GPRS_SAPI_GMM, bss_nu++,
2496 dtap_detach_req, sizeof(dtap_detach_req));
2497
2498 dump_peers(stdout, 0, 0, &gbcfg);
2499
2500 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2501 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2502 GPRS_SAPI_GMM, sgsn_nu++,
2503 dtap_detach_acc, sizeof(dtap_detach_acc));
2504
2505 dump_peers(stdout, 0, 0, &gbcfg);
2506
2507 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2508
2509 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2510 local_bss_tlli2, &rai_bss, cell_id,
2511 GPRS_SAPI_GMM, bss_nu++,
2512 dtap_detach_req, sizeof(dtap_detach_req));
2513
2514 dump_peers(stdout, 0, 0, &gbcfg);
2515
2516 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2517 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2518 GPRS_SAPI_GMM, sgsn_nu++,
2519 dtap_detach_acc, sizeof(dtap_detach_acc));
2520
2521 dump_peers(stdout, 0, 0, &gbcfg);
2522
2523 dump_global(stdout, 0);
2524
2525 gbprox_reset(&gbcfg);
2526 gprs_ns_destroy(nsi);
2527 nsi = NULL;
2528}
2529
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002530/* TODO: Move tlv testing to libosmocore */
2531int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2532int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2533 uint8_t **value);
2534int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2535 size_t *value_len);
2536int lv_shift(uint8_t **data, size_t *data_len,
2537 uint8_t **value, size_t *value_len);
2538
2539static void check_tlv_match(uint8_t **data, size_t *data_len,
2540 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2541{
2542 uint8_t *value;
2543 size_t value_len;
2544 int rc;
2545
2546 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2547 OSMO_ASSERT(rc == 0);
2548
2549 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002550 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002551 OSMO_ASSERT(value_len == exp_len);
2552 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2553}
2554
2555static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2556 uint8_t tag, size_t len, const uint8_t *exp_val)
2557{
2558 uint8_t *value;
2559 int rc;
2560
2561 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2562 OSMO_ASSERT(rc == 0);
2563
2564 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002565 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002566 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2567}
2568
2569static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2570 size_t len, const uint8_t *exp_val)
2571{
2572 uint8_t *value;
2573 int rc;
2574
2575 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002576 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002577 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2578}
2579
2580static void check_lv_shift(uint8_t **data, size_t *data_len,
2581 size_t exp_len, const uint8_t *exp_val)
2582{
2583 uint8_t *value;
2584 size_t value_len;
2585 int rc;
2586
2587 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002588 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002589 OSMO_ASSERT(value_len == exp_len);
2590 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2591}
2592
2593static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2594 const uint8_t *test_data)
2595{
2596 uint8_t buf[300] = {0};
2597
2598 uint8_t *unchanged_ptr = buf - 1;
2599 size_t unchanged_len = 0xdead;
2600 size_t tmp_data_len = data_len;
2601 uint8_t *value = unchanged_ptr;
2602 size_t value_len = unchanged_len;
2603 uint8_t *data = buf;
2604
2605 OSMO_ASSERT(data_len <= sizeof(buf));
2606
2607 tlv_put(data, tag, len, test_data);
2608 if (data_len < len + 2) {
2609 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2610 tag, &value, &value_len));
2611 OSMO_ASSERT(tmp_data_len == 0);
2612 OSMO_ASSERT(data == buf + data_len);
2613 OSMO_ASSERT(value == unchanged_ptr);
2614 OSMO_ASSERT(value_len == unchanged_len);
2615 } else {
2616 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2617 tag, &value, &value_len));
2618 OSMO_ASSERT(value != unchanged_ptr);
2619 OSMO_ASSERT(value_len != unchanged_len);
2620 }
2621}
2622
2623static void check_tv_fixed_match_data_len(size_t data_len,
2624 uint8_t tag, size_t len,
2625 const uint8_t *test_data)
2626{
2627 uint8_t buf[300] = {0};
2628
2629 uint8_t *unchanged_ptr = buf - 1;
2630 size_t tmp_data_len = data_len;
2631 uint8_t *value = unchanged_ptr;
2632 uint8_t *data = buf;
2633
2634 OSMO_ASSERT(data_len <= sizeof(buf));
2635
2636 tv_fixed_put(data, tag, len, test_data);
2637
2638 if (data_len < len + 1) {
2639 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2640 tag, len, &value));
2641 OSMO_ASSERT(tmp_data_len == 0);
2642 OSMO_ASSERT(data == buf + data_len);
2643 OSMO_ASSERT(value == unchanged_ptr);
2644 } else {
2645 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2646 tag, len, &value));
2647 OSMO_ASSERT(value != unchanged_ptr);
2648 }
2649}
2650
2651static void check_v_fixed_shift_data_len(size_t data_len,
2652 size_t len, const uint8_t *test_data)
2653{
2654 uint8_t buf[300] = {0};
2655
2656 uint8_t *unchanged_ptr = buf - 1;
2657 size_t tmp_data_len = data_len;
2658 uint8_t *value = unchanged_ptr;
2659 uint8_t *data = buf;
2660
2661 OSMO_ASSERT(data_len <= sizeof(buf));
2662
2663 memcpy(data, test_data, len);
2664
2665 if (data_len < len) {
2666 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2667 len, &value));
2668 OSMO_ASSERT(tmp_data_len == 0);
2669 OSMO_ASSERT(data == buf + data_len);
2670 OSMO_ASSERT(value == unchanged_ptr);
2671 } else {
2672 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2673 len, &value));
2674 OSMO_ASSERT(value != unchanged_ptr);
2675 }
2676}
2677
2678static void check_lv_shift_data_len(size_t data_len,
2679 size_t len, const uint8_t *test_data)
2680{
2681 uint8_t buf[300] = {0};
2682
2683 uint8_t *unchanged_ptr = buf - 1;
2684 size_t unchanged_len = 0xdead;
2685 size_t tmp_data_len = data_len;
2686 uint8_t *value = unchanged_ptr;
2687 size_t value_len = unchanged_len;
2688 uint8_t *data = buf;
2689
2690 lv_put(data, len, test_data);
2691 if (data_len < len + 1) {
2692 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2693 &value, &value_len));
2694 OSMO_ASSERT(tmp_data_len == 0);
2695 OSMO_ASSERT(data == buf + data_len);
2696 OSMO_ASSERT(value == unchanged_ptr);
2697 OSMO_ASSERT(value_len == unchanged_len);
2698 } else {
2699 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2700 &value, &value_len));
2701 OSMO_ASSERT(value != unchanged_ptr);
2702 OSMO_ASSERT(value_len != unchanged_len);
2703 }
2704}
2705
2706static void test_tlv_shift_functions()
2707{
2708 uint8_t test_data[1024];
2709 uint8_t buf[1024];
2710 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002711 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002712 uint8_t *data;
2713 size_t data_len;
2714 const uint8_t tag = 0x1a;
2715
2716 printf("Test shift functions\n");
2717
2718 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2719 test_data[i] = (uint8_t)i;
2720
2721 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002722 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002723
2724 memset(buf, 0xee, sizeof(buf));
2725 data_end = data = buf;
2726
2727 for (i = 0; i < iterations; i++) {
2728 data_end = tlv_put(data_end, tag, len, test_data);
2729 data_end = tv_fixed_put(data_end, tag, len, test_data);
2730 /* v_fixed_put */
2731 memcpy(data_end, test_data, len);
2732 data_end += len;
2733 data_end = lv_put(data_end, len, test_data);
2734 }
2735
2736 data_len = data_end - data;
2737 OSMO_ASSERT(data_len <= sizeof(buf));
2738
2739 for (i = 0; i < iterations; i++) {
2740 check_tlv_match(&data, &data_len, tag, len, test_data);
2741 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2742 check_v_fixed_shift(&data, &data_len, len, test_data);
2743 check_lv_shift(&data, &data_len, len, test_data);
2744 }
2745
2746 OSMO_ASSERT(data == data_end);
2747
2748 /* Test at end of data */
2749
2750 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2751 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2752 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2753 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2754
2755 /* Test invalid data_len */
2756 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2757 check_tlv_match_data_len(data_len, tag, len, test_data);
2758 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2759 check_v_fixed_shift_data_len(data_len, len, test_data);
2760 check_lv_shift_data_len(data_len, len, test_data);
2761 }
2762 }
2763}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002764
2765static void test_gbproxy_tlli_expire(void)
2766{
2767 struct gbproxy_config cfg = {0};
2768 struct gbproxy_peer *peer;
2769 const char *err_msg = NULL;
2770 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2771 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002772 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002773 const uint32_t tlli1 = 1234 | 0xc0000000;
2774 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002775 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002776 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002777 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002778
2779 printf("Test TLLI info expiry\n\n");
2780
2781 gbproxy_init_config(&cfg);
2782
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002783 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002784 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2785 err_msg);
2786 OSMO_ASSERT(err_msg == NULL);
2787 }
2788
2789 {
2790 struct gbproxy_tlli_info *tlli_info;
2791
2792 printf("Test TLLI replacement:\n");
2793
2794 cfg.tlli_max_len = 0;
2795 cfg.tlli_max_age = 0;
2796 peer = gbproxy_peer_alloc(&cfg, 20);
2797 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2798
2799 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002800 tlli_info = gbproxy_register_tlli(peer, tlli1,
2801 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002802 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002803 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002804 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2805
2806 /* replace the old entry */
2807 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002808 tlli_info = gbproxy_register_tlli(peer, tlli2,
2809 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002810 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002811 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002812 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2813
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002814 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002815
2816 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002817 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002818 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002819 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002820 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002821 OSMO_ASSERT(!tlli_info);
2822
2823 printf("\n");
2824
2825 gbproxy_peer_free(peer);
2826 }
2827
2828 {
2829 struct gbproxy_tlli_info *tlli_info;
2830
2831 printf("Test IMSI replacement:\n");
2832
2833 cfg.tlli_max_len = 0;
2834 cfg.tlli_max_age = 0;
2835 peer = gbproxy_peer_alloc(&cfg, 20);
2836 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2837
2838 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002839 tlli_info = gbproxy_register_tlli(peer, tlli1,
2840 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002841 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002842 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002843 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2844
2845 /* try to replace the old entry */
2846 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002847 tlli_info = gbproxy_register_tlli(peer, tlli1,
2848 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002849 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002850 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002851 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2852
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002853 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002854
2855 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002856 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002857 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002858 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002859 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002860 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002861
2862 printf("\n");
2863
2864 gbproxy_peer_free(peer);
2865 }
2866
2867 {
2868 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002869 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002870
2871 printf("Test TLLI expiry, max_len == 1:\n");
2872
2873 cfg.tlli_max_len = 1;
2874 cfg.tlli_max_age = 0;
2875 peer = gbproxy_peer_alloc(&cfg, 20);
2876 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2877
2878 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002879 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002880 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2881
2882 /* replace the old entry */
2883 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002884 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002885 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2886
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002887 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002888 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002889 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2890
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002891 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002892
2893 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002894 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002895 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002896 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002897 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002898 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002899
2900 printf("\n");
2901
2902 gbproxy_peer_free(peer);
2903 }
2904
2905 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002906 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002907 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002908
2909 printf("Test TLLI expiry, max_age == 1:\n");
2910
2911 cfg.tlli_max_len = 0;
2912 cfg.tlli_max_age = 1;
2913 peer = gbproxy_peer_alloc(&cfg, 20);
2914 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2915
2916 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002917 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002918 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2919
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002920 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002921 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002922 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002923 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2924
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002925 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002926 OSMO_ASSERT(num_removed == 1);
2927 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2928
2929 dump_peers(stdout, 2, now + 2, &cfg);
2930
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002931 /* verify that 5678 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002932 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002933 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002934 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002935 OSMO_ASSERT(tlli_info);
2936 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2937
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002938 printf("\n");
2939
2940 gbproxy_peer_free(peer);
2941 }
2942
2943 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002944 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002945 int num_removed;
2946
2947 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2948
2949 cfg.tlli_max_len = 0;
2950 cfg.tlli_max_age = 1;
2951 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002952 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2953
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002954 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002955 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002956 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2957
2958 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002959 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002960 now + 1);
2961 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2962
2963 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002964 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2965 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002966 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2967
2968 dump_peers(stdout, 2, now + 2, &cfg);
2969
2970 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002971 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002972 OSMO_ASSERT(num_removed == 2);
2973 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2974
2975 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002976
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002977 /* verify that tlli3 has survived */
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002978 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002979 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002980 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002981 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck2fd1ba42014-09-11 14:57:03 +02002982 tlli_info = gbproxy_find_tlli_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002983 OSMO_ASSERT(tlli_info);
2984 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2985
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002986 printf("\n");
2987
2988 gbproxy_peer_free(peer);
2989 }
2990}
2991
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002992static void test_gbproxy_imsi_matching(void)
2993{
2994 struct gbproxy_config cfg = {0};
2995 struct gbproxy_peer *peer;
2996 const char *err_msg = NULL;
2997 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2998 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2999 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3000 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3001 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3002 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3003 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3004 const char *filter_re1 = ".*";
3005 const char *filter_re2 = "^1234";
3006 const char *filter_re3 = "^4321";
3007 const char *filter_re4_bad = "^12[";
3008
3009 printf("=== Test IMSI/TMSI matching ===\n\n");
3010
3011 gbproxy_init_config(&cfg);
3012 OSMO_ASSERT(cfg.check_imsi == 0);
3013
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003014 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003015 OSMO_ASSERT(cfg.check_imsi == 1);
3016
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003017 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003018 OSMO_ASSERT(cfg.check_imsi == 1);
3019
3020 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003021 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003022 OSMO_ASSERT(err_msg != NULL);
3023 OSMO_ASSERT(cfg.check_imsi == 0);
3024
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003025 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003026 OSMO_ASSERT(cfg.check_imsi == 1);
3027
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003028 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003029 OSMO_ASSERT(cfg.check_imsi == 0);
3030
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003031 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003032 OSMO_ASSERT(cfg.check_imsi == 1);
3033
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003034 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003035 OSMO_ASSERT(cfg.check_imsi == 0);
3036
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003037 peer = gbproxy_peer_alloc(&cfg, 20);
3038
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003039 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003040 OSMO_ASSERT(cfg.check_imsi == 1);
3041
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003042 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3043 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003044 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003045 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003046 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003047 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3048 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3049 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3050 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3051 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003052
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003053 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003054 OSMO_ASSERT(cfg.check_imsi == 1);
3055
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003056 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3057 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3058 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3059 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3060 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3061 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3062 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003063
3064 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3065
3066 gbproxy_peer_free(peer);
3067}
3068
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003069static struct log_info_cat gprs_categories[] = {
3070 [DGPRS] = {
3071 .name = "DGPRS",
3072 .description = "GPRS Packet Service",
3073 .enabled = 1, .loglevel = LOGL_DEBUG,
3074 },
3075 [DNS] = {
3076 .name = "DNS",
3077 .description = "GPRS Network Service (NS)",
3078 .enabled = 1, .loglevel = LOGL_INFO,
3079 },
3080 [DBSSGP] = {
3081 .name = "DBSSGP",
3082 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3083 .enabled = 1, .loglevel = LOGL_DEBUG,
3084 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003085};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003086
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003087static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003088 .cat = gprs_categories,
3089 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003090};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003091
3092int main(int argc, char **argv)
3093{
3094 osmo_init_logging(&info);
3095 log_set_use_color(osmo_stderr_target, 0);
3096 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003097 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003098
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003099 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003100 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3101 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003102
3103 rate_ctr_init(NULL);
3104
3105 setlinebuf(stdout);
3106
3107 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003108 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003109 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003110 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003111 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003112 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003113 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003114 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003115 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003116 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003117 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003118 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003119
3120 exit(EXIT_SUCCESS);
3121}