blob: a99986bc4c52b5cccde0260e7799b2b6e49c5031 [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) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +020090 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020091 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",
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200120 indent, "", state->logical_link_count);
121 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200122 char mi_buf[200];
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200123 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200124 int stored_msgs = 0;
125 struct llist_head *iter;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200126 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200127 stored_msgs++;
128
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200129 if (link_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 Erlbeck91d2f8a2014-09-19 15:07:27 +0200132 link_info->imsi,
133 link_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 Erlbeck91d2f8a2014-09-19 15:07:27 +0200138 indent, "", link_info->tlli.current);
139 if (link_info->tlli.assigned)
140 fprintf(stream, "/%08x", link_info->tlli.assigned);
141 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200142 fprintf(stream, " -> %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200143 link_info->sgsn_tlli.current);
144 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200145 fprintf(stream, "/%08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200146 link_info->sgsn_tlli.assigned);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200147 }
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 Erlbeck91d2f8a2014-09-19 15:07:27 +0200154 if (cfg->check_imsi && link_info->imsi_matches)
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200155 fprintf(stream, ", IMSI matches");
156
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200157 if (link_info->imsi_acq_pending)
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200158 fprintf(stream, ", IMSI acquisition in progress");
159
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200160 if (cfg->route_to_sgsn2)
161 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200162 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200163
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200164 if (link_info->is_deregistered)
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200165 fprintf(stream, ", DE-REGISTERED");
166
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200167 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200168 if (rc < 0)
169 return rc;
170 }
171 }
172
173 return 0;
174}
175
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200176const uint8_t *convert_ra(struct gprs_ra_id *raid)
177{
178 static uint8_t buf[6];
179 gsm48_construct_ra(buf, raid);
180 return buf;
181}
182
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200183/* DTAP - Attach Request */
184static const unsigned char dtap_attach_req[] = {
185 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
186 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
187 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
188 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
189 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
190 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200191};
192
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200193/* DTAP - Attach Request (invalid RAI) */
194static const unsigned char dtap_attach_req2[] = {
195 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
196 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
197 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
198 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
199 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
200 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
201};
202
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200203/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
204static const unsigned char dtap_attach_req3[] = {
205 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
206 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
207 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
208 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
209 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
210 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
211};
212
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200213/* DTAP - Identity Request */
214static const unsigned char dtap_identity_req[] = {
215 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200216};
217
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200218/* DTAP - Identity Response */
219static const unsigned char dtap_identity_resp[] = {
220 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
221 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200222};
223
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200224/* DTAP - Identity Response, IMSI 2 */
225static const unsigned char dtap_identity2_resp[] = {
226 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
227 0x16, 0x17, 0x18
228};
229
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200230/* DTAP - Identity Response, IMSI 3 */
231static const unsigned char dtap_identity3_resp[] = {
232 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
233 0x26, 0x27, 0x28
234};
235
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200236/* DTAP - Attach Accept */
237static const unsigned char dtap_attach_acc[] = {
238 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
239 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
240 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200241};
242
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200243/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200244static const unsigned char dtap_attach_acc2[] = {
245 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
246 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
247 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
248};
249
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200250/* DTAP - Attach Complete */
251static const unsigned char dtap_attach_complete[] = {
252 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200253};
254
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200255/* DTAP - GMM Information */
256static const unsigned char dtap_gmm_information[] = {
257 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200258};
259
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200260/* DTAP - Routing Area Update Request */
261static const unsigned char dtap_ra_upd_req[] = {
262 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
263 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
264 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
265 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
266 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
267 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
268 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200269};
270
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200271/* DTAP - Routing Area Update Accept */
272static const unsigned char dtap_ra_upd_acc[] = {
273 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
274 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
275 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200276};
277
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200278/* DTAP - Routing Area Update Accept, P-TMSI 2 */
279static const unsigned char dtap_ra_upd_acc2[] = {
280 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
281 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
282 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
283};
284
285/* DTAP - Routing Area Update Accept, P-TMSI 3 */
286static const unsigned char dtap_ra_upd_acc3[] = {
287 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
288 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
289 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
290};
291
292/* DTAP - Routing Area Update Complete */
293static const unsigned char dtap_ra_upd_complete[] = {
294 0x08, 0x0a
295};
296
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200297/* DTAP - Routing Area Update Reject */
298/* cause = 10 ("Implicitly detached"), force_standby = 0 */
299static const unsigned char dtap_ra_upd_rej[] = {
300 0x08, 0x0b, 0x0a, 0x00,
301};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200302
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200303/* DTAP - Activate PDP Context Request */
304static const unsigned char dtap_act_pdp_ctx_req[] = {
305 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200306 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
308 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
309 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
310 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200311 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200312};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200313
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200314/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200315/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200316static const unsigned char dtap_detach_po_req[] = {
317 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
318 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200319};
320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200321/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200322/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200323static const unsigned char dtap_detach_req[] = {
324 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
325 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200326};
327
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200328/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200329static const unsigned char dtap_detach_acc[] = {
330 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200331};
332
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200333/* DTAP - Detach Request (MT) */
334/* normal detach, reattach required, implicitly detached */
335static const unsigned char dtap_mt_detach_rea_req[] = {
336 0x08, 0x05, 0x01, 0x25, 0x0a
337};
338
339/* DTAP - Detach Request (MT) */
340/* normal detach, reattach not required, implicitly detached */
341static const unsigned char dtap_mt_detach_req[] = {
342 0x08, 0x05, 0x02, 0x25, 0x0a
343};
344
345/* DTAP - Detach Accept (MT) */
346static const unsigned char dtap_mt_detach_acc[] = {
347 0x08, 0x06
348};
349
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200350/* GPRS-LLC - SAPI: LLGMM, U, XID */
351static const unsigned char llc_u_xid_ul[] = {
352 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
353 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
354};
355
356/* GPRS-LLC - SAPI: LLGMM, U, XID */
357static const unsigned char llc_u_xid_dl[] = {
358 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
359 0xe4, 0xa9, 0x1a, 0x9e
360};
361
362/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
363static const unsigned char llc_ui_ll11_dns_query_ul[] = {
364 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
365 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
366 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
367 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
368 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
369 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
370 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
371 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
372 0x8f, 0x07
373};
374
375/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
376static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
377 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
378 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
379 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
380 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
381 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
382 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
383 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
384 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
385 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
386 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
387 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
388 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
389 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
390 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
391 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
392 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
393 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
394 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
395 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
396 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
397 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
398 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
399 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
400 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
401 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
402 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
403};
404
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200405static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
406 struct sockaddr_in *peer, const unsigned char* data,
407 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200408
409static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
410 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
411{
412 /* GPRS Network Service, PDU type: NS_RESET,
413 */
414 unsigned char msg[12] = {
415 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
416 0x04, 0x82, 0x11, 0x22
417 };
418
419 msg[3] = cause;
420 msg[6] = nsvci / 256;
421 msg[7] = nsvci % 256;
422 msg[10] = nsei / 256;
423 msg[11] = nsei % 256;
424
425 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
426}
427
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200428static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
429 uint16_t nsvci, uint16_t nsei)
430{
431 /* GPRS Network Service, PDU type: NS_RESET_ACK,
432 */
433 unsigned char msg[9] = {
434 0x03, 0x01, 0x82, 0x11, 0x22,
435 0x04, 0x82, 0x11, 0x22
436 };
437
438 msg[3] = nsvci / 256;
439 msg[4] = nsvci % 256;
440 msg[7] = nsei / 256;
441 msg[8] = nsei % 256;
442
443 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
444}
445
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200446static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
447{
448 /* GPRS Network Service, PDU type: NS_ALIVE */
449 unsigned char msg[1] = {
450 0x0a
451 };
452
453 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
454}
455
456static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
457{
458 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
459 unsigned char msg[1] = {
460 0x0b
461 };
462
463 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
464}
465
466static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
467{
468 /* GPRS Network Service, PDU type: NS_UNBLOCK */
469 unsigned char msg[1] = {
470 0x06
471 };
472
473 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
474}
475
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200476static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
477{
478 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
479 unsigned char msg[1] = {
480 0x07
481 };
482
483 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
484}
485
486static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
487 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200488 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
489{
490 /* GPRS Network Service, PDU type: NS_UNITDATA */
491 unsigned char msg[4096] = {
492 0x00, 0x00, 0x00, 0x00
493 };
494
495 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
496
497 msg[2] = nsbvci / 256;
498 msg[3] = nsbvci % 256;
499 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
500
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200501 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200502}
503
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200504static void send_bssgp_ul_unitdata(
505 struct gprs_ns_inst *nsi, const char *text,
506 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
507 struct gprs_ra_id *raid, uint16_t cell_id,
508 const uint8_t *llc_msg, size_t llc_msg_size)
509{
510 /* GPRS Network Service, PDU type: NS_UNITDATA */
511 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
512 unsigned char msg[4096] = {
513 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
514 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
515 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
516 };
517
518 size_t bssgp_msg_size = 23 + llc_msg_size;
519
520 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
521
522 gsm48_construct_ra(msg + 10, raid);
523 msg[1] = (uint8_t)(tlli >> 24);
524 msg[2] = (uint8_t)(tlli >> 16);
525 msg[3] = (uint8_t)(tlli >> 8);
526 msg[4] = (uint8_t)(tlli >> 0);
527 msg[16] = cell_id / 256;
528 msg[17] = cell_id % 256;
529 msg[21] = llc_msg_size / 256;
530 msg[22] = llc_msg_size % 256;
531 memcpy(msg + 23, llc_msg, llc_msg_size);
532
533 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
534 src_addr, nsbvci, msg, bssgp_msg_size);
535}
536
537static void send_bssgp_dl_unitdata(
538 struct gprs_ns_inst *nsi, const char *text,
539 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
540 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
541 const uint8_t *llc_msg, size_t llc_msg_size)
542{
543 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
544 unsigned char msg[4096] = {
545 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
546 0x16, 0x82, 0x02, 0x58,
547 };
548 unsigned char racap_drx[] = {
549 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
550 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
551 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
552 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
553 };
554
555 size_t bssgp_msg_size = 0;
556
557 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
558
559 msg[1] = (uint8_t)(tlli >> 24);
560 msg[2] = (uint8_t)(tlli >> 16);
561 msg[3] = (uint8_t)(tlli >> 8);
562 msg[4] = (uint8_t)(tlli >> 0);
563
564 bssgp_msg_size = 12;
565
566 if (with_racap_drx) {
567 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
568 bssgp_msg_size += sizeof(racap_drx);
569 }
570
571 if (imsi) {
572 OSMO_ASSERT(imsi_size <= 127);
573 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
574 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
575 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
576 bssgp_msg_size += 2 + imsi_size;
577 }
578
579 if ((bssgp_msg_size % 4) != 0) {
580 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
581 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
582 msg[bssgp_msg_size + 1] = 0x80 | abytes;
583 memset(msg + bssgp_msg_size + 2, 0, abytes);
584 bssgp_msg_size += 2 + abytes;
585 }
586
587 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
588 if (llc_msg_size < 128) {
589 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
590 bssgp_msg_size += 2;
591 } else {
592 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
593 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
594 bssgp_msg_size += 3;
595 }
596 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
597 bssgp_msg_size += llc_msg_size;
598
599
600 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
601 src_addr, nsbvci, msg, bssgp_msg_size);
602}
603
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200604static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
605 uint16_t bvci)
606{
607 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
608 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200609 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200610 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200611 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
612 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200613 };
614
615 msg[3] = bvci / 256;
616 msg[4] = bvci % 256;
617
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200618 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
619}
620
621static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
622 struct sockaddr_in *src_addr, uint16_t bvci)
623{
624 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
625 * BSSGP RESET_ACK */
626 static unsigned char msg[5] = {
627 0x23, 0x04, 0x82, 0x00,
628 0x00
629 };
630
631 msg[3] = bvci / 256;
632 msg[4] = bvci % 256;
633
634 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200635}
636
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200637static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
638 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200639 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200640 struct gprs_ra_id *raid)
641{
642 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
643 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200644 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
645 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200646 };
647
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200648 msg[3] = (uint8_t)(tlli >> 24);
649 msg[4] = (uint8_t)(tlli >> 16);
650 msg[5] = (uint8_t)(tlli >> 8);
651 msg[6] = (uint8_t)(tlli >> 0);
652
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200653 gsm48_construct_ra(msg + 9, raid);
654
655 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
656}
657
658static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
659 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200660 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200661 struct gprs_ra_id *raid)
662{
663 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
664 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200665 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
666 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200667 0x81, 0x01
668 };
669
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200670 msg[3] = (uint8_t)(tlli >> 24);
671 msg[4] = (uint8_t)(tlli >> 16);
672 msg[5] = (uint8_t)(tlli >> 8);
673 msg[6] = (uint8_t)(tlli >> 0);
674
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200675 gsm48_construct_ra(msg + 9, raid);
676
677 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
678}
679
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200680static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
681 struct sockaddr_in *src_addr,
682 uint16_t bvci, uint32_t tlli,
683 unsigned n_frames, unsigned n_octets)
684{
685 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
686 unsigned char msg[] = {
687 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
688 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
689 /* n octets */ 0xff, 0xff, 0xff
690 };
691
692 msg[3] = (uint8_t)(tlli >> 24);
693 msg[4] = (uint8_t)(tlli >> 16);
694 msg[5] = (uint8_t)(tlli >> 8);
695 msg[6] = (uint8_t)(tlli >> 0);
696 msg[9] = (uint8_t)(n_frames);
697 msg[12] = (uint8_t)(bvci >> 8);
698 msg[13] = (uint8_t)(bvci >> 0);
699 msg[16] = (uint8_t)(n_octets >> 16);
700 msg[17] = (uint8_t)(n_octets >> 8);
701 msg[18] = (uint8_t)(n_octets >> 0);
702
703 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
704}
705
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200706static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
707 struct sockaddr_in *src_addr,
708 uint16_t bvci, uint8_t tag)
709{
710 /* GPRS Network Service, PDU type: NS_UNITDATA,
711 * BSSGP FLOW_CONTROL_BVC */
712 unsigned char msg[] = {
713 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
714 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
715 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
716 };
717
718 msg[3] = tag;
719
720 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
721 msg, sizeof(msg));
722}
723
724static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
725 struct sockaddr_in *src_addr,
726 uint16_t bvci, uint8_t tag)
727{
728 /* GPRS Network Service, PDU type: NS_UNITDATA,
729 * BSSGP FLOW_CONTROL_BVC_ACK */
730 unsigned char msg[] = {
731 0x27, 0x1e, 0x81, /* Tag */ 0xce
732 };
733
734 msg[3] = tag;
735
736 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
737 msg, sizeof(msg));
738}
739
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200740static void send_llc_ul_ui(
741 struct gprs_ns_inst *nsi, const char *text,
742 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
743 struct gprs_ra_id *raid, uint16_t cell_id,
744 unsigned sapi, unsigned nu,
745 const uint8_t *msg, size_t msg_size)
746{
747 unsigned char llc_msg[4096] = {
748 0x00, 0xc0, 0x01
749 };
750
751 size_t llc_msg_size = 3 + msg_size + 3;
752 uint8_t e_bit = 0;
753 uint8_t pm_bit = 1;
754 unsigned fcs;
755
756 nu &= 0x01ff;
757
758 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
759
760 llc_msg[0] = (sapi & 0x0f);
761 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
762 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
763
764 memcpy(llc_msg + 3, msg, msg_size);
765
766 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
767 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
768 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
769 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
770
771 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
772 src_addr, nsbvci, tlli, raid, cell_id,
773 llc_msg, llc_msg_size);
774}
775
776static void send_llc_dl_ui(
777 struct gprs_ns_inst *nsi, const char *text,
778 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
779 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
780 unsigned sapi, unsigned nu,
781 const uint8_t *msg, size_t msg_size)
782{
783 /* GPRS Network Service, PDU type: NS_UNITDATA */
784 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
785 unsigned char llc_msg[4096] = {
786 0x00, 0x00, 0x01
787 };
788
789 size_t llc_msg_size = 3 + msg_size + 3;
790 uint8_t e_bit = 0;
791 uint8_t pm_bit = 1;
792 unsigned fcs;
793
794 nu &= 0x01ff;
795
796 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
797
798 llc_msg[0] = 0x40 | (sapi & 0x0f);
799 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
800 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
801
802 memcpy(llc_msg + 3, msg, msg_size);
803
804 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
805 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
806 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
807 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
808
809 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
810 src_addr, nsbvci, tlli,
811 with_racap_drx, imsi, imsi_size,
812 llc_msg, llc_msg_size);
813}
814
815
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200816static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
817 uint16_t nsvci, uint16_t nsei)
818{
819 printf("Setup NS-VC: remote 0x%08x:%d, "
820 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
821 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
822 nsvci, nsvci, nsei, nsei);
823
824 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
825 send_ns_alive(nsi, src_addr);
826 send_ns_unblock(nsi, src_addr);
827 send_ns_alive_ack(nsi, src_addr);
828}
829
830static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
831 uint16_t bvci)
832{
833 printf("Setup BSSGP: remote 0x%08x:%d, "
834 "BVCI 0x%04x(%d)\n\n",
835 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
836 bvci, bvci);
837
838 send_bssgp_reset(nsi, src_addr, bvci);
839}
840
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200841static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
842 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200843{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200844 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
845 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200846 send_ns_alive_ack(nsi, sgsn_peer);
847 send_ns_unblock_ack(nsi, sgsn_peer);
848 send_ns_alive(nsi, sgsn_peer);
849}
850
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200851static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
852{
853 sgsn_peer->sin_family = AF_INET;
854 sgsn_peer->sin_port = htons(32000);
855 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
856}
857
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200858static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
859{
860 sgsn_peer->sin_family = AF_INET;
861 sgsn_peer->sin_port = htons(32001);
862 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
863}
864
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200865static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
866{
867 size_t i;
868
869 for (i = 0; i < size; ++i) {
870 bss_peers[i].sin_family = AF_INET;
871 bss_peers[i].sin_port = htons((i + 1) * 1111);
872 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
873 }
874}
875
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200876int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
877 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
878
879/* override */
880int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
881 struct msgb *msg, uint16_t bvci)
882{
883 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
884 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200885 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200886
887 switch (event) {
888 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200889 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200890 default:
891 break;
892 }
893 return 0;
894}
895
896/* override */
897ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
898 const struct sockaddr *dest_addr, socklen_t addrlen)
899{
900 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
901 const struct sockaddr *, socklen_t);
902 static sendto_t real_sendto = NULL;
903 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200904 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200905
906 if (!real_sendto)
907 real_sendto = dlsym(RTLD_NEXT, "sendto");
908
909 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200910 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
911 dest_host, dest_port,
912 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200913 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200914 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
915 dest_host, dest_port,
916 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200917 else if (dest_host == REMOTE_SGSN2_ADDR)
918 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
919 dest_host, dest_port,
920 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200921 else
922 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
923
924 return len;
925}
926
927/* override */
928int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
929{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200930 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
931 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200932 uint16_t bvci = msgb_bvci(msg);
933 uint16_t nsei = msgb_nsei(msg);
934
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200935 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200936
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200937 if (!real_gprs_ns_sendmsg)
938 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
939
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200940 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200941 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
942 "msg length %d (%s)\n",
943 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200944 else if (nsei == SGSN2_NSEI)
945 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
946 "msg length %d (%s)\n",
947 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200948 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200949 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
950 "msg length %d (%s)\n",
951 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200952
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200953 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200954}
955
956static void dump_rate_ctr_group(FILE *stream, const char *prefix,
957 struct rate_ctr_group *ctrg)
958{
959 unsigned int i;
960
961 for (i = 0; i < ctrg->desc->num_ctr; i++) {
962 struct rate_ctr *ctr = &ctrg->ctr[i];
963 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
964 fprintf(stream, " %s%s: %llu%s",
965 prefix, ctrg->desc->ctr_desc[i].description,
966 (long long)ctr->current,
967 "\n");
968 };
969}
970
971/* Signal handler for signals from NS layer */
972static int test_signal(unsigned int subsys, unsigned int signal,
973 void *handler_data, void *signal_data)
974{
975 struct ns_signal_data *nssd = signal_data;
976 int rc;
977
978 if (subsys != SS_L_NS)
979 return 0;
980
981 switch (signal) {
982 case S_NS_RESET:
983 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
984 nssd->nsvc->nsvci,
985 gprs_ns_ll_str(nssd->nsvc));
986 break;
987
988 case S_NS_ALIVE_EXP:
989 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
990 nssd->nsvc->nsvci,
991 gprs_ns_ll_str(nssd->nsvc));
992 break;
993
994 case S_NS_BLOCK:
995 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
996 nssd->nsvc->nsvci,
997 gprs_ns_ll_str(nssd->nsvc));
998 break;
999
1000 case S_NS_UNBLOCK:
1001 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1002 nssd->nsvc->nsvci,
1003 gprs_ns_ll_str(nssd->nsvc));
1004 break;
1005
1006 case S_NS_REPLACED:
1007 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1008 nssd->nsvc->nsvci,
1009 gprs_ns_ll_str(nssd->nsvc));
1010 printf(" -> 0x%04x/%s\n",
1011 nssd->old_nsvc->nsvci,
1012 gprs_ns_ll_str(nssd->old_nsvc));
1013 break;
1014
1015 default:
1016 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1017 nssd->nsvc->nsvci,
1018 gprs_ns_ll_str(nssd->nsvc));
1019 break;
1020 }
1021 printf("\n");
1022 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1023 return rc;
1024}
1025
1026static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1027{
1028 struct msgb *msg;
1029 int ret;
1030 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1031 fprintf(stderr, "message too long: %d\n", data_len);
1032 return -1;
1033 }
1034
1035 msg = gprs_ns_msgb_alloc();
1036 memmove(msg->data, data, data_len);
1037 msg->l2h = msg->data;
1038 msgb_put(msg, data_len);
1039
1040 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1041 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1042 osmo_hexdump(data, data_len));
1043
1044 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1045
1046 printf("result (%s) = %d\n\n", text, ret);
1047
1048 msgb_free(msg);
1049
1050 return ret;
1051}
1052
1053static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1054{
1055 struct gprs_nsvc *nsvc;
1056
1057 printf("Current NS-VCIs:\n");
1058 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1059 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001060 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001061 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001062 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1063 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1064 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001065 );
1066 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1067 }
1068 printf("\n");
1069}
1070
1071static void test_gbproxy()
1072{
1073 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1074 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001075 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001076
1077 bssgp_nsi = nsi;
1078 gbcfg.nsi = bssgp_nsi;
1079 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1080
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001081 configure_sgsn_peer(&sgsn_peer);
1082 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001083
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001084 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001085 printf("--- Initialise SGSN ---\n\n");
1086
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001087 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001088 gprs_dump_nsi(nsi);
1089
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001090 printf("--- Initialise BSS 1 ---\n\n");
1091
1092 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1093 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1094 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001095 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001096
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001097 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1098
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001099 printf("--- Initialise BSS 2 ---\n\n");
1100
1101 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1102 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1103 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001104 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001105
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001106 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1107
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001108 printf("--- Move BSS 1 to new port ---\n\n");
1109
1110 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1111 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001112 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001113
1114 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1115
1116 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1117 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001118 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001119
1120 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1121
1122 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1123 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001124 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001125
1126 printf("--- Move BSS 2 to new port ---\n\n");
1127
1128 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1129 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001130 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001131
1132 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1133
1134 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1135 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001136 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001137
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001138 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1139
1140 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1141 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001142 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001143
1144 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1145
1146 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1147 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001148 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001149
1150 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1151
1152 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1153
1154 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1155 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001156 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001157
1158 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1159
1160 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1161
1162 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1163 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001164 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001165
1166 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1167
1168 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1169
1170 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1171
1172 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1173
1174 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1175
1176 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1177
1178 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1179
1180 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1181
1182 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1183
1184 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1185
1186 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1187
1188 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1189
1190 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1191
1192 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1193
1194 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1195 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001196 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001197
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001198 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001199
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001200 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1201
1202 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1203
1204 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1205
1206 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1207
1208 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1209
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001210 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1211
1212 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1213
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001214 /* Find peer */
1215 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1216 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1217 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1218 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1219 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1220 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1221
1222
1223 /* Cleanup */
1224 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1225 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1226 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1227 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1228 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1229
1230 dump_peers(stdout, 0, 0, &gbcfg);
1231
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001232 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001233
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001234 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001235 gprs_ns_destroy(nsi);
1236 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001237}
1238
1239static void test_gbproxy_ident_changes()
1240{
1241 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1242 struct sockaddr_in bss_peer[1] = {{0},};
1243 struct sockaddr_in sgsn_peer= {0};
1244 uint16_t nsei[2] = {0x1000, 0x2000};
1245 uint16_t nsvci[2] = {0x1001, 0x2001};
1246 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1247
1248 bssgp_nsi = nsi;
1249 gbcfg.nsi = bssgp_nsi;
1250 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1251
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001252 configure_sgsn_peer(&sgsn_peer);
1253 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001254
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001255 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001256 printf("--- Initialise SGSN ---\n\n");
1257
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001258 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001259 gprs_dump_nsi(nsi);
1260
1261 printf("--- Initialise BSS 1 ---\n\n");
1262
1263 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1264 gprs_dump_nsi(nsi);
1265
1266 printf("--- Setup BVCI 1 ---\n\n");
1267
1268 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1269 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001270 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001271
1272 printf("--- Setup BVCI 2 ---\n\n");
1273
1274 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1275 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001276 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001277
1278 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1279
1280 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1281 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1282
1283 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1284
1285 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1286 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1287
1288 printf("--- Change NSEI ---\n\n");
1289
1290 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1291 gprs_dump_nsi(nsi);
1292
1293 printf("--- Setup BVCI 1 ---\n\n");
1294
1295 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1296 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001297 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001298
1299 printf("--- Setup BVCI 3 ---\n\n");
1300
1301 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1302 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001304
1305 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1306
1307 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1308 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1309
1310 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1311 " (should fail) ---\n\n");
1312
1313 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001314 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001315 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001316 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001317
1318 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1319
1320 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1321 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1322
1323 printf("--- Change NSVCI ---\n\n");
1324
1325 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1326 gprs_dump_nsi(nsi);
1327
1328 printf("--- Setup BVCI 1 ---\n\n");
1329
1330 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1331 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001332 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001333
1334 printf("--- Setup BVCI 4 ---\n\n");
1335
1336 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1337 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001338 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001339
1340 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1341
1342 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1343 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1344
1345 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1346 " (should fail) ---\n\n");
1347
1348 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001349 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001350 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001351 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001352
1353 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1354
1355 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1356 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1357
1358 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1359
1360 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1361 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1362
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001363 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001364 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001365
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001366 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001367 gprs_ns_destroy(nsi);
1368 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001369}
1370
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001371static void test_gbproxy_ra_patching()
1372{
1373 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1374 struct sockaddr_in bss_peer[1] = {{0},};
1375 struct sockaddr_in sgsn_peer= {0};
1376 struct gprs_ra_id rai_bss =
1377 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1378 struct gprs_ra_id rai_sgsn =
1379 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1380 struct gprs_ra_id rai_unknown =
1381 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001382 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001383 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001384 const uint32_t ptmsi = 0xefe2b700;
1385 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001386 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001387 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001388 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001389 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001390 struct gbproxy_peer *peer;
1391
1392 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001393
1394 bssgp_nsi = nsi;
1395 gbcfg.nsi = bssgp_nsi;
1396 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001397 gbcfg.core_mcc = 123;
1398 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001399 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001400 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001401 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001402
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001403 configure_sgsn_peer(&sgsn_peer);
1404 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001405
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001406 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001407 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001408 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1409 gbcfg.match_re, err_msg);
1410 exit(1);
1411 }
1412
1413
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001414 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001415 printf("--- Initialise SGSN ---\n\n");
1416
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001417 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001418 gprs_dump_nsi(nsi);
1419
1420 printf("--- Initialise BSS 1 ---\n\n");
1421
1422 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1423 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1424 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001425 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001426
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001427 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001428 OSMO_ASSERT(peer != NULL);
1429
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001430 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1431
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001432 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1433 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001434
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001435 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001436 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001437
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001438 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1439 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1440
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001441 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1442
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001443 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1444 foreign_tlli, &rai_bss, cell_id,
1445 GPRS_SAPI_GMM, 0,
1446 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001447
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001448 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1449
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001450 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1451 foreign_tlli, 0, NULL, 0,
1452 GPRS_SAPI_GMM, 0,
1453 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001454
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001455 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1456 foreign_tlli, &rai_bss, cell_id,
1457 GPRS_SAPI_GMM, 3,
1458 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001459
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001460 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1461 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1462
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001463 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1464 foreign_tlli, 1, imsi, sizeof(imsi),
1465 GPRS_SAPI_GMM, 1,
1466 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001467
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001468 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1469
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001470 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1471 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1472 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1473
1474 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1475 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1476 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1477
1478 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1479 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1480 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1481
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001482 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1483 OSMO_ASSERT(link_info);
1484 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1485 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1486 OSMO_ASSERT(!link_info->tlli.bss_validated);
1487 OSMO_ASSERT(!link_info->tlli.net_validated);
1488 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1489 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1490 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1491 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001492
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001493 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1494 local_tlli, &rai_bss, cell_id,
1495 GPRS_SAPI_GMM, 4,
1496 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001497
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001498 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1499
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001500 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1501 OSMO_ASSERT(link_info);
1502 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1503 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1504 OSMO_ASSERT(link_info->tlli.bss_validated);
1505 OSMO_ASSERT(!link_info->tlli.net_validated);
1506 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1507 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1508 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1509 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001510
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001511 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001512 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1513 local_tlli, &rai_bss, cell_id,
1514 GPRS_SAPI_GMM, 3,
1515 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001516
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001517 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1518
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001519 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1520 OSMO_ASSERT(link_info);
1521 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1522 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1523 OSMO_ASSERT(link_info->tlli.bss_validated);
1524 OSMO_ASSERT(!link_info->tlli.net_validated);
1525 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1526 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1527 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1528 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001529
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001530 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1531 local_tlli, 1, imsi, sizeof(imsi),
1532 GPRS_SAPI_GMM, 2,
1533 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001534
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001535 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1536
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001537 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1538 OSMO_ASSERT(link_info);
1539 OSMO_ASSERT(link_info->tlli.assigned == 0);
1540 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1541 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1542 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001543
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001544 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001545 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1546 local_tlli, &rai_bss, cell_id,
1547 GPRS_SAPI_GMM, 3,
1548 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001549
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001550 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1551
Jacob Erlbeck73685282014-05-23 20:48:07 +02001552 gbcfg.core_apn[0] = 0;
1553 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001554
1555 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001556 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1557 local_tlli, &rai_bss, cell_id,
1558 GPRS_SAPI_GMM, 3,
1559 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001560
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001561 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1562
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001563 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001564
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001565 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001566 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1567 local_tlli, &rai_bss, cell_id,
1568 GPRS_SAPI_GMM, 6,
1569 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001570
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001571 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1572 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1573
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001574 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1575 local_tlli, 1, imsi, sizeof(imsi),
1576 GPRS_SAPI_GMM, 5,
1577 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001578
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001579 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001580
1581 printf("--- RA update ---\n\n");
1582
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001583 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1584 foreign_tlli, &rai_bss, 0x7080,
1585 GPRS_SAPI_GMM, 5,
1586 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001587
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001588 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1589
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001590 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1591 foreign_tlli, 1, imsi, sizeof(imsi),
1592 GPRS_SAPI_GMM, 6,
1593 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001594
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001595 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1596
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001597 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001598 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1599 local_tlli, &rai_bss, cell_id,
1600 GPRS_SAPI_GMM, 3,
1601 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001602
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001603 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1604
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001605 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001606
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001607 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001608 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1609 local_tlli, &rai_bss, cell_id,
1610 GPRS_SAPI_GMM, 6,
1611 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001612
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001613 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1614
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001615 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001616 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001617
1618 printf("--- Bad cases ---\n\n");
1619
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001620 /* The RAI in the Attach Request message differs from the RAI in the
1621 * BSSGP message, only patch the latter */
1622
1623 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1624 foreign_tlli2, &rai_bss, cell_id,
1625 GPRS_SAPI_GMM, 0,
1626 dtap_attach_req2, sizeof(dtap_attach_req2));
1627
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001628 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1629
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001630 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001631 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1632 local_tlli, &rai_bss, cell_id,
1633 GPRS_SAPI_GMM, 3,
1634 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001635
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001636 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001637 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001638
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001639 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001640 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001641
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001642 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001643 gprs_ns_destroy(nsi);
1644 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001645}
1646
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001647static void test_gbproxy_ptmsi_assignment()
1648{
1649 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1650 struct sockaddr_in bss_peer[1] = {{0},};
1651 struct sockaddr_in sgsn_peer= {0};
1652 struct gprs_ra_id rai_bss =
1653 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1654 struct gprs_ra_id rai_unknown =
1655 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1656 uint16_t cell_id = 0x1234;
1657
1658 const uint32_t ptmsi = 0xefe2b700;
1659 const uint32_t local_tlli = 0xefe2b700;
1660
1661 const uint32_t foreign_tlli1 = 0x8000dead;
1662 const uint32_t foreign_tlli2 = 0x8000beef;
1663
1664 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1665 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1666
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001667 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001668 struct gbproxy_peer *peer;
1669 unsigned bss_nu = 0;
1670 unsigned sgsn_nu = 0;
1671
1672 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1673
1674 bssgp_nsi = nsi;
1675 gbcfg.nsi = bssgp_nsi;
1676 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1677 gbcfg.core_mcc = 0;
1678 gbcfg.core_mnc = 0;
1679 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1680 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1681 gbcfg.patch_ptmsi = 0;
1682 gbcfg.bss_ptmsi_state = 0;
1683 gbcfg.sgsn_tlli_state = 1;
1684
1685 configure_sgsn_peer(&sgsn_peer);
1686 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1687
1688 printf("=== %s ===\n", __func__);
1689 printf("--- Initialise SGSN ---\n\n");
1690
1691 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1692
1693 printf("--- Initialise BSS 1 ---\n\n");
1694
1695 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1696 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1697
1698 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1699 OSMO_ASSERT(peer != NULL);
1700
1701 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1702
1703 gprs_dump_nsi(nsi);
1704 dump_global(stdout, 0);
1705 dump_peers(stdout, 0, 0, &gbcfg);
1706
1707 printf("--- Establish first LLC connection ---\n\n");
1708
1709 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1710 foreign_tlli1, &rai_unknown, cell_id,
1711 GPRS_SAPI_GMM, bss_nu++,
1712 dtap_attach_req, sizeof(dtap_attach_req));
1713
1714 dump_peers(stdout, 0, 0, &gbcfg);
1715
1716 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1717 foreign_tlli1, 0, NULL, 0,
1718 GPRS_SAPI_GMM, sgsn_nu++,
1719 dtap_identity_req, sizeof(dtap_identity_req));
1720
1721 dump_peers(stdout, 0, 0, &gbcfg);
1722
1723 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1724 foreign_tlli1, &rai_bss, cell_id,
1725 GPRS_SAPI_GMM, bss_nu++,
1726 dtap_identity_resp, sizeof(dtap_identity_resp));
1727
1728 dump_peers(stdout, 0, 0, &gbcfg);
1729
1730 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1731 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1732 GPRS_SAPI_GMM, sgsn_nu++,
1733 dtap_attach_acc, sizeof(dtap_attach_acc));
1734
1735 dump_peers(stdout, 0, 0, &gbcfg);
1736
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001737 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1738 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1739 OSMO_ASSERT(link_info);
1740 OSMO_ASSERT(link_info == link_info2);
1741 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1742 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1743 OSMO_ASSERT(!link_info->tlli.bss_validated);
1744 OSMO_ASSERT(!link_info->tlli.net_validated);
1745 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001746
1747 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1748 local_tlli, &rai_bss, cell_id,
1749 GPRS_SAPI_GMM, bss_nu++,
1750 dtap_attach_complete, sizeof(dtap_attach_complete));
1751
1752 dump_peers(stdout, 0, 0, &gbcfg);
1753
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001754 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1755 OSMO_ASSERT(link_info);
1756 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1757 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1758 OSMO_ASSERT(link_info->tlli.bss_validated);
1759 OSMO_ASSERT(!link_info->tlli.net_validated);
1760 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001761
1762
1763 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1764 local_tlli, 1, imsi1, sizeof(imsi1),
1765 GPRS_SAPI_GMM, sgsn_nu++,
1766 dtap_gmm_information, sizeof(dtap_gmm_information));
1767
1768 dump_peers(stdout, 0, 0, &gbcfg);
1769
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001770 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1771 OSMO_ASSERT(link_info);
1772 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
1773 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001774
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001775 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1776 OSMO_ASSERT(link_info == link_info2);
1777 OSMO_ASSERT(link_info->tlli.assigned == 0);
1778 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1779 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001780
1781 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
1782
1783 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1784 foreign_tlli2, &rai_unknown, cell_id,
1785 GPRS_SAPI_GMM, bss_nu++,
1786 dtap_attach_req, sizeof(dtap_attach_req));
1787
1788 dump_peers(stdout, 0, 0, &gbcfg);
1789
1790 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1791 foreign_tlli2, 0, NULL, 0,
1792 GPRS_SAPI_GMM, sgsn_nu++,
1793 dtap_identity_req, sizeof(dtap_identity_req));
1794
1795 dump_peers(stdout, 0, 0, &gbcfg);
1796
1797 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1798 foreign_tlli2, &rai_bss, cell_id,
1799 GPRS_SAPI_GMM, bss_nu++,
1800 dtap_identity2_resp, sizeof(dtap_identity2_resp));
1801
1802 dump_peers(stdout, 0, 0, &gbcfg);
1803
1804 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1805 foreign_tlli2, 1, imsi2, sizeof(imsi2),
1806 GPRS_SAPI_GMM, sgsn_nu++,
1807 dtap_attach_acc, sizeof(dtap_attach_acc));
1808
1809 dump_peers(stdout, 0, 0, &gbcfg);
1810
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001811 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
1812 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1813 OSMO_ASSERT(link_info);
1814 OSMO_ASSERT(link_info == link_info2);
1815 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1816 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
1817 OSMO_ASSERT(!link_info->tlli.bss_validated);
1818 OSMO_ASSERT(!link_info->tlli.net_validated);
1819 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001820
1821 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1822 local_tlli, &rai_bss, cell_id,
1823 GPRS_SAPI_GMM, bss_nu++,
1824 dtap_attach_complete, sizeof(dtap_attach_complete));
1825
1826 dump_peers(stdout, 0, 0, &gbcfg);
1827
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001828 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1829 OSMO_ASSERT(link_info);
1830 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1831 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
1832 OSMO_ASSERT(link_info->tlli.bss_validated);
1833 OSMO_ASSERT(!link_info->tlli.net_validated);
1834 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001835
1836 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1837 local_tlli, 1, imsi2, sizeof(imsi2),
1838 GPRS_SAPI_GMM, sgsn_nu++,
1839 dtap_gmm_information, sizeof(dtap_gmm_information));
1840
1841 dump_peers(stdout, 0, 0, &gbcfg);
1842
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001843 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
1844 OSMO_ASSERT(link_info);
1845 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
1846 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001847
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001848 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1849 OSMO_ASSERT(link_info == link_info2);
1850 OSMO_ASSERT(link_info->tlli.assigned == 0);
1851 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1852 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001853
1854 dump_global(stdout, 0);
1855
1856 gbprox_reset(&gbcfg);
1857 gprs_ns_destroy(nsi);
1858 nsi = NULL;
1859}
1860
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001861static void test_gbproxy_ptmsi_patching()
1862{
1863 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1864 struct sockaddr_in bss_peer[1] = {{0},};
1865 struct sockaddr_in sgsn_peer= {0};
1866 struct gprs_ra_id rai_bss =
1867 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1868 struct gprs_ra_id rai_sgsn =
1869 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001870 struct gprs_ra_id rai_wrong_mcc_sgsn =
1871 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001872 struct gprs_ra_id rai_unknown =
1873 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1874 uint16_t cell_id = 0x1234;
1875
1876 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001877 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1878 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001879 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001880 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1881 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001882 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001883 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001884
1885 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001886 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1887 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001888 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001889 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1890 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001891 const uint32_t foreign_bss_tlli = 0x8000dead;
1892
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001893
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001894 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001895 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001896 struct gbproxy_peer *peer;
1897 unsigned bss_nu = 0;
1898 unsigned sgsn_nu = 0;
1899
1900 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001901 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1902 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1903 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1904 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1905 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001906
1907 bssgp_nsi = nsi;
1908 gbcfg.nsi = bssgp_nsi;
1909 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1910 gbcfg.core_mcc = 123;
1911 gbcfg.core_mnc = 456;
1912 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1913 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1914 gbcfg.patch_ptmsi = 1;
1915 gbcfg.bss_ptmsi_state = 0;
1916 gbcfg.sgsn_tlli_state = 1;
1917
1918 configure_sgsn_peer(&sgsn_peer);
1919 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1920
1921 printf("=== %s ===\n", __func__);
1922 printf("--- Initialise SGSN ---\n\n");
1923
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001924 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001925
1926 printf("--- Initialise BSS 1 ---\n\n");
1927
1928 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1929 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1930
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001931 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001932 OSMO_ASSERT(peer != NULL);
1933
1934 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1935
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001936 gprs_dump_nsi(nsi);
1937 dump_global(stdout, 0);
1938 dump_peers(stdout, 0, 0, &gbcfg);
1939
1940 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1941
1942 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1943 foreign_bss_tlli, &rai_unknown, cell_id,
1944 GPRS_SAPI_GMM, bss_nu++,
1945 dtap_attach_req, sizeof(dtap_attach_req));
1946
1947 dump_peers(stdout, 0, 0, &gbcfg);
1948
1949 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1950 random_sgsn_tlli, 0, NULL, 0,
1951 GPRS_SAPI_GMM, sgsn_nu++,
1952 dtap_identity_req, sizeof(dtap_identity_req));
1953
1954 dump_peers(stdout, 0, 0, &gbcfg);
1955
1956 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1957 foreign_bss_tlli, &rai_bss, cell_id,
1958 GPRS_SAPI_GMM, bss_nu++,
1959 dtap_identity_resp, sizeof(dtap_identity_resp));
1960
1961 dump_peers(stdout, 0, 0, &gbcfg);
1962
1963 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1964 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1965 GPRS_SAPI_GMM, sgsn_nu++,
1966 dtap_attach_acc, sizeof(dtap_attach_acc));
1967
1968 dump_peers(stdout, 0, 0, &gbcfg);
1969
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001970 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
1971 OSMO_ASSERT(link_info);
1972 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
1973 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
1974 OSMO_ASSERT(!link_info->tlli.bss_validated);
1975 OSMO_ASSERT(!link_info->tlli.net_validated);
1976 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
1977 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
1978 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
1979 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1980 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
1981 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001982
1983 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1984 local_bss_tlli, &rai_bss, cell_id,
1985 GPRS_SAPI_GMM, bss_nu++,
1986 dtap_attach_complete, sizeof(dtap_attach_complete));
1987
1988 dump_peers(stdout, 0, 0, &gbcfg);
1989
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001990 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
1991 OSMO_ASSERT(link_info);
1992 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
1993 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
1994 OSMO_ASSERT(link_info->tlli.bss_validated);
1995 OSMO_ASSERT(!link_info->tlli.net_validated);
1996 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
1997 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
1998 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1999 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002000
2001 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2002 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2003 GPRS_SAPI_GMM, sgsn_nu++,
2004 dtap_gmm_information, sizeof(dtap_gmm_information));
2005
2006 dump_peers(stdout, 0, 0, &gbcfg);
2007
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002008 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2009 OSMO_ASSERT(link_info);
2010 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2011 OSMO_ASSERT(link_info->tlli.assigned == 0);
2012 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2013 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002014
Jacob Erlbeck82add782014-09-05 18:08:12 +02002015 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2016 local_bss_tlli, &rai_bss, cell_id,
2017 GPRS_SAPI_GMM, bss_nu++,
2018 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2019
2020 dump_peers(stdout, 0, 0, &gbcfg);
2021
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002022 /* Non-DTAP */
2023 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2024 local_bss_tlli, &rai_bss, cell_id,
2025 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2026
2027 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2028 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2029 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2030
2031 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2032 local_bss_tlli, &rai_bss, cell_id,
2033 llc_ui_ll11_dns_query_ul,
2034 sizeof(llc_ui_ll11_dns_query_ul));
2035
2036 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2037 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2038 llc_ui_ll11_dns_resp_dl,
2039 sizeof(llc_ui_ll11_dns_resp_dl));
2040
2041 dump_peers(stdout, 0, 0, &gbcfg);
2042
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002043 /* Repeated RA Update Requests */
2044 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2045 local_bss_tlli, &rai_bss, 0x7080,
2046 GPRS_SAPI_GMM, bss_nu++,
2047 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2048
2049 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2050 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2051 GPRS_SAPI_GMM, sgsn_nu++,
2052 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2053
2054 dump_peers(stdout, 0, 0, &gbcfg);
2055
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002056 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2057 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2058 OSMO_ASSERT(link_info);
2059 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2060 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2061 OSMO_ASSERT(!link_info->tlli.bss_validated);
2062 OSMO_ASSERT(!link_info->tlli.net_validated);
2063 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2064 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2065 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2066 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2067 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2068 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002069
2070 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2071 local_bss_tlli2, &rai_bss, 0x7080,
2072 GPRS_SAPI_GMM, bss_nu++,
2073 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2074
2075 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2076 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2077 GPRS_SAPI_GMM, sgsn_nu++,
2078 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2079
2080 dump_peers(stdout, 0, 0, &gbcfg);
2081
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002082 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2083 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2084 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2085 OSMO_ASSERT(link_info);
2086 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2087 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2088 OSMO_ASSERT(!link_info->tlli.bss_validated);
2089 OSMO_ASSERT(!link_info->tlli.net_validated);
2090 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2091 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2092 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2093 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2094 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2095 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002096
2097 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2098 local_bss_tlli3, &rai_bss, 0x7080,
2099 GPRS_SAPI_GMM, bss_nu++,
2100 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2101
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002102 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002103
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002104 OSMO_ASSERT(link_info);
2105 OSMO_ASSERT(link_info->tlli.bss_validated);
2106 OSMO_ASSERT(!link_info->tlli.net_validated);
2107 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2108 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002109
2110 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2111 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2112 GPRS_SAPI_GMM, sgsn_nu++,
2113 dtap_gmm_information, sizeof(dtap_gmm_information));
2114
2115 dump_peers(stdout, 0, 0, &gbcfg);
2116
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002117 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2118 OSMO_ASSERT(link_info);
2119 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2120 OSMO_ASSERT(link_info->tlli.assigned == 0);
2121 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2122 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002123
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002124 /* Other messages */
2125 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002126 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002130 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002131
2132 dump_peers(stdout, 0, 0, &gbcfg);
2133
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002134 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002135
2136 dump_peers(stdout, 0, 0, &gbcfg);
2137
2138 /* Bad case: Invalid BVCI */
2139 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002140 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002141 dump_global(stdout, 0);
2142
2143 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002144 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002145
2146 dump_global(stdout, 0);
2147
2148 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002149 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002150 &rai_wrong_mcc_sgsn);
2151
2152 dump_global(stdout, 0);
2153
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002154 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2155 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2156 unknown_sgsn_tlli, 1, NULL, 0,
2157 GPRS_SAPI_GMM, 2,
2158 dtap_gmm_information, sizeof(dtap_gmm_information));
2159
2160 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2161 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2162 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2163 GPRS_SAPI_GMM, 3,
2164 dtap_gmm_information, sizeof(dtap_gmm_information));
2165
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002166 /* Detach */
2167 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002168 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002169 GPRS_SAPI_GMM, bss_nu++,
2170 dtap_detach_req, sizeof(dtap_detach_req));
2171
2172 dump_peers(stdout, 0, 0, &gbcfg);
2173
2174 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002175 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002176 GPRS_SAPI_GMM, sgsn_nu++,
2177 dtap_detach_acc, sizeof(dtap_detach_acc));
2178
2179 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002180
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002181 dump_global(stdout, 0);
2182
2183 gbprox_reset(&gbcfg);
2184 gprs_ns_destroy(nsi);
2185 nsi = NULL;
2186}
2187
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002188static void test_gbproxy_imsi_acquisition()
2189{
2190 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2191 struct sockaddr_in bss_peer[1] = {{0},};
2192 struct sockaddr_in sgsn_peer= {0};
2193 struct gprs_ra_id rai_bss =
2194 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2195 struct gprs_ra_id rai_sgsn =
2196 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2197 struct gprs_ra_id rai_wrong_mcc_sgsn =
2198 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2199 struct gprs_ra_id rai_unknown =
2200 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2201 uint16_t cell_id = 0x1234;
2202
2203 const uint32_t sgsn_ptmsi = 0xefe2b700;
2204 const uint32_t local_sgsn_tlli = 0xefe2b700;
2205 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002206 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002207
2208 const uint32_t bss_ptmsi = 0xc00f7304;
2209 const uint32_t local_bss_tlli = 0xc00f7304;
2210 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002211 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002212
2213 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002214 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002215 struct gbproxy_peer *peer;
2216 unsigned bss_nu = 0;
2217 unsigned sgsn_nu = 0;
2218
2219 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2220
2221 bssgp_nsi = nsi;
2222 gbcfg.nsi = bssgp_nsi;
2223 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2224 gbcfg.core_mcc = 123;
2225 gbcfg.core_mnc = 456;
2226 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2227 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2228 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002229 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002230 gbcfg.bss_ptmsi_state = 0;
2231 gbcfg.sgsn_tlli_state = 1;
2232
2233 configure_sgsn_peer(&sgsn_peer);
2234 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2235
2236 printf("=== %s ===\n", __func__);
2237 printf("--- Initialise SGSN ---\n\n");
2238
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002239 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002240
2241 printf("--- Initialise BSS 1 ---\n\n");
2242
2243 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2244 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2245
2246 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2247 OSMO_ASSERT(peer != NULL);
2248
2249 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2250
2251 gprs_dump_nsi(nsi);
2252 dump_global(stdout, 0);
2253 dump_peers(stdout, 0, 0, &gbcfg);
2254
2255 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2256
2257 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002258 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002259 GPRS_SAPI_GMM, bss_nu++,
2260 dtap_attach_req, sizeof(dtap_attach_req));
2261
2262 dump_peers(stdout, 0, 0, &gbcfg);
2263
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002264 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2265 foreign_bss_tlli, &rai_bss, cell_id,
2266 GPRS_SAPI_GMM, bss_nu++,
2267 dtap_identity_resp, sizeof(dtap_identity_resp));
2268
2269 dump_peers(stdout, 0, 0, &gbcfg);
2270
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002271 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2272 random_sgsn_tlli, 0, NULL, 0,
2273 GPRS_SAPI_GMM, sgsn_nu++,
2274 dtap_identity_req, sizeof(dtap_identity_req));
2275
2276 dump_peers(stdout, 0, 0, &gbcfg);
2277
2278 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2279 foreign_bss_tlli, &rai_bss, cell_id,
2280 GPRS_SAPI_GMM, bss_nu++,
2281 dtap_identity_resp, sizeof(dtap_identity_resp));
2282
2283 dump_peers(stdout, 0, 0, &gbcfg);
2284
2285 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2286 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2287 GPRS_SAPI_GMM, sgsn_nu++,
2288 dtap_attach_acc, sizeof(dtap_attach_acc));
2289
2290 dump_peers(stdout, 0, 0, &gbcfg);
2291
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002292 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2293 OSMO_ASSERT(link_info);
2294 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2295 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2296 OSMO_ASSERT(!link_info->tlli.bss_validated);
2297 OSMO_ASSERT(!link_info->tlli.net_validated);
2298 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2299 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2300 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2301 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2302 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2303 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002304
2305 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2306 local_bss_tlli, &rai_bss, cell_id,
2307 GPRS_SAPI_GMM, bss_nu++,
2308 dtap_attach_complete, sizeof(dtap_attach_complete));
2309
2310 dump_peers(stdout, 0, 0, &gbcfg);
2311
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002312 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2313 OSMO_ASSERT(link_info);
2314 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2315 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2316 OSMO_ASSERT(link_info->tlli.bss_validated);
2317 OSMO_ASSERT(!link_info->tlli.net_validated);
2318 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2319 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2320 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2321 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002322
2323 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2324 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2325 GPRS_SAPI_GMM, sgsn_nu++,
2326 dtap_gmm_information, sizeof(dtap_gmm_information));
2327
2328 dump_peers(stdout, 0, 0, &gbcfg);
2329
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002330 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2331 OSMO_ASSERT(link_info);
2332 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2333 OSMO_ASSERT(link_info->tlli.assigned == 0);
2334 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2335 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002336
2337 /* Non-DTAP */
2338 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2339 local_bss_tlli, &rai_bss, cell_id,
2340 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2341
2342 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2343 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2344 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2345
2346 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2347 local_bss_tlli, &rai_bss, cell_id,
2348 llc_ui_ll11_dns_query_ul,
2349 sizeof(llc_ui_ll11_dns_query_ul));
2350
2351 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2352 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2353 llc_ui_ll11_dns_resp_dl,
2354 sizeof(llc_ui_ll11_dns_resp_dl));
2355
2356 dump_peers(stdout, 0, 0, &gbcfg);
2357
2358 /* Other messages */
2359 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2360 local_bss_tlli, 1, 12);
2361
2362 dump_peers(stdout, 0, 0, &gbcfg);
2363
2364 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2365 local_sgsn_tlli, 1, 12);
2366
2367 dump_peers(stdout, 0, 0, &gbcfg);
2368
2369 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2370
2371 dump_peers(stdout, 0, 0, &gbcfg);
2372
2373 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2374
2375 dump_peers(stdout, 0, 0, &gbcfg);
2376
2377 /* Bad case: Invalid BVCI */
2378 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2379 local_bss_tlli, 1, 12);
2380 dump_global(stdout, 0);
2381
2382 /* Bad case: Invalid RAI */
2383 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2384
2385 dump_global(stdout, 0);
2386
2387 /* Bad case: Invalid MCC (LAC ok) */
2388 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2389 &rai_wrong_mcc_sgsn);
2390
2391 dump_global(stdout, 0);
2392
2393 /* Detach */
2394 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2395 local_bss_tlli, &rai_bss, cell_id,
2396 GPRS_SAPI_GMM, bss_nu++,
2397 dtap_detach_req, sizeof(dtap_detach_req));
2398
2399 dump_peers(stdout, 0, 0, &gbcfg);
2400
2401 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2402 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2403 GPRS_SAPI_GMM, sgsn_nu++,
2404 dtap_detach_acc, sizeof(dtap_detach_acc));
2405
2406 dump_peers(stdout, 0, 0, &gbcfg);
2407
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002408 /* RA Update request */
2409
2410 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2411 foreign_bss_tlli, &rai_unknown, 0x7080,
2412 GPRS_SAPI_GMM, bss_nu++,
2413 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2414
2415 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2416 foreign_bss_tlli, &rai_bss, cell_id,
2417 GPRS_SAPI_GMM, bss_nu++,
2418 dtap_identity_resp, sizeof(dtap_identity_resp));
2419
2420 dump_peers(stdout, 0, 0, &gbcfg);
2421
2422 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2423 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2424 GPRS_SAPI_GMM, sgsn_nu++,
2425 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2426
2427 dump_peers(stdout, 0, 0, &gbcfg);
2428
2429 /* Detach */
2430
2431 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2432 local_bss_tlli, &rai_bss, cell_id,
2433 GPRS_SAPI_GMM, bss_nu++,
2434 dtap_detach_req, sizeof(dtap_detach_req));
2435
2436 dump_peers(stdout, 0, 0, &gbcfg);
2437
2438 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2439 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2440 GPRS_SAPI_GMM, sgsn_nu++,
2441 dtap_detach_acc, sizeof(dtap_detach_acc));
2442
2443 dump_peers(stdout, 0, 0, &gbcfg);
2444
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002445 /* Special case: Repeated Attach Requests */
2446
2447 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2448 foreign_bss_tlli, &rai_unknown, cell_id,
2449 GPRS_SAPI_GMM, bss_nu++,
2450 dtap_attach_req, sizeof(dtap_attach_req));
2451
2452 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2453 foreign_bss_tlli, &rai_unknown, cell_id,
2454 GPRS_SAPI_GMM, bss_nu++,
2455 dtap_attach_req, sizeof(dtap_attach_req));
2456
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002457 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2458 foreign_bss_tlli, &rai_bss, cell_id,
2459 GPRS_SAPI_GMM, bss_nu++,
2460 dtap_detach_req, sizeof(dtap_detach_req));
2461
2462 dump_peers(stdout, 0, 0, &gbcfg);
2463
2464 /* Special case: Detach from an unknown TLLI */
2465
2466 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2467 other_bss_tlli, &rai_bss, cell_id,
2468 GPRS_SAPI_GMM, bss_nu++,
2469 dtap_detach_req, sizeof(dtap_detach_req));
2470
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002471 dump_peers(stdout, 0, 0, &gbcfg);
2472
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002473 /* Special case: Repeated RA Update Requests */
2474
2475 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2476 foreign_bss_tlli, &rai_unknown, 0x7080,
2477 GPRS_SAPI_GMM, bss_nu++,
2478 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2479
2480 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2481 foreign_bss_tlli, &rai_unknown, 0x7080,
2482 GPRS_SAPI_GMM, bss_nu++,
2483 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2484
2485 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2486 foreign_bss_tlli, &rai_bss, cell_id,
2487 GPRS_SAPI_GMM, bss_nu++,
2488 dtap_detach_req, sizeof(dtap_detach_req));
2489
2490 dump_peers(stdout, 0, 0, &gbcfg);
2491
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002492 dump_global(stdout, 0);
2493
2494 gbprox_reset(&gbcfg);
2495 gprs_ns_destroy(nsi);
2496 nsi = NULL;
2497}
2498
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002499static void test_gbproxy_secondary_sgsn()
2500{
2501 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2502 struct sockaddr_in bss_peer[1] = {{0},};
2503 struct sockaddr_in sgsn_peer[2]= {{0},};
2504 struct gprs_ra_id rai_bss =
2505 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2506 struct gprs_ra_id rai_sgsn =
2507 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2508 struct gprs_ra_id rai_unknown =
2509 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2510 uint16_t cell_id = 0x1234;
2511
2512 const uint32_t sgsn_ptmsi = 0xefe2b700;
2513 const uint32_t local_sgsn_tlli = 0xefe2b700;
2514 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2515
2516 const uint32_t bss_ptmsi = 0xc00f7304;
2517 const uint32_t local_bss_tlli = 0xc00f7304;
2518 const uint32_t foreign_bss_tlli = 0x8000dead;
2519
2520 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2521 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2522 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2523 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2524 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2525 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2526
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002527 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002528 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002529 const uint32_t local_bss_tlli3 = 0xead4775a;
2530 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2531
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002532 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2533 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002534 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002535 struct gbproxy_link_info *link_info;
2536 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002537 struct gbproxy_peer *peer;
2538 unsigned bss_nu = 0;
2539 unsigned sgsn_nu = 0;
2540
2541 const char *err_msg = NULL;
2542 const char *filter_re = "999999";
2543
2544 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2545 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2546
2547 bssgp_nsi = nsi;
2548 gbcfg.nsi = bssgp_nsi;
2549 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2550 gbcfg.core_mcc = 123;
2551 gbcfg.core_mnc = 456;
2552 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2553 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2554 gbcfg.patch_ptmsi = 1;
2555 gbcfg.acquire_imsi = 1;
2556 gbcfg.bss_ptmsi_state = 0;
2557 gbcfg.sgsn_tlli_state = 1;
2558 gbcfg.route_to_sgsn2 = 1;
2559 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2560
2561 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2562 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2563 err_msg);
2564 OSMO_ASSERT(err_msg == NULL);
2565 }
2566
2567 configure_sgsn_peer(&sgsn_peer[0]);
2568 configure_sgsn2_peer(&sgsn_peer[1]);
2569 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2570
2571 printf("=== %s ===\n", __func__);
2572 printf("--- Initialise SGSN 1 ---\n\n");
2573
2574 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2575
2576 printf("--- Initialise SGSN 2 ---\n\n");
2577
2578 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2579
2580 printf("--- Initialise BSS 1 ---\n\n");
2581
2582 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2583 setup_bssgp(nsi, &bss_peer[0], 0x0);
2584 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2585 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2586 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2587 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2588
2589 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2590 OSMO_ASSERT(peer != NULL);
2591
2592 gprs_dump_nsi(nsi);
2593 dump_global(stdout, 0);
2594 dump_peers(stdout, 0, 0, &gbcfg);
2595
2596 printf("--- Flow control ---\n\n");
2597
2598 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2599 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2600 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2601
2602 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2603
2604 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2605 foreign_bss_tlli, &rai_unknown, cell_id,
2606 GPRS_SAPI_GMM, bss_nu++,
2607 dtap_attach_req, sizeof(dtap_attach_req));
2608
2609 dump_peers(stdout, 0, 0, &gbcfg);
2610
2611 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2612 foreign_bss_tlli, &rai_bss, cell_id,
2613 GPRS_SAPI_GMM, bss_nu++,
2614 dtap_identity_resp, sizeof(dtap_identity_resp));
2615
2616 dump_peers(stdout, 0, 0, &gbcfg);
2617
2618 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2619 random_sgsn_tlli, 0, NULL, 0,
2620 GPRS_SAPI_GMM, sgsn_nu++,
2621 dtap_identity_req, sizeof(dtap_identity_req));
2622
2623 dump_peers(stdout, 0, 0, &gbcfg);
2624
2625 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2626 foreign_bss_tlli, &rai_bss, cell_id,
2627 GPRS_SAPI_GMM, bss_nu++,
2628 dtap_identity_resp, sizeof(dtap_identity_resp));
2629
2630 dump_peers(stdout, 0, 0, &gbcfg);
2631
2632 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2633 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2634 GPRS_SAPI_GMM, sgsn_nu++,
2635 dtap_attach_acc, sizeof(dtap_attach_acc));
2636
2637 dump_peers(stdout, 0, 0, &gbcfg);
2638
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002639 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2640 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2641 OSMO_ASSERT(link_info);
2642 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2643 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2644 OSMO_ASSERT(!link_info->tlli.bss_validated);
2645 OSMO_ASSERT(!link_info->tlli.net_validated);
2646 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2647 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2648 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2649 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2650 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2651 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002652
2653 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2654 local_bss_tlli, &rai_bss, cell_id,
2655 GPRS_SAPI_GMM, bss_nu++,
2656 dtap_attach_complete, sizeof(dtap_attach_complete));
2657
2658 dump_peers(stdout, 0, 0, &gbcfg);
2659
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002660 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2661 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2662 OSMO_ASSERT(link_info);
2663 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2664 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2665 OSMO_ASSERT(link_info->tlli.bss_validated);
2666 OSMO_ASSERT(!link_info->tlli.net_validated);
2667 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2668 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2669 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2670 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002671
2672 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2673 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2674 GPRS_SAPI_GMM, sgsn_nu++,
2675 dtap_gmm_information, sizeof(dtap_gmm_information));
2676
2677 dump_peers(stdout, 0, 0, &gbcfg);
2678
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002679 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2680 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2681 OSMO_ASSERT(link_info);
2682 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2683 OSMO_ASSERT(link_info->tlli.assigned == 0);
2684 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2685 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002686
2687 /* Non-DTAP */
2688 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2689 local_bss_tlli, &rai_bss, cell_id,
2690 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2691
2692 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2693 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2694 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2695
2696 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2697 local_bss_tlli, &rai_bss, cell_id,
2698 llc_ui_ll11_dns_query_ul,
2699 sizeof(llc_ui_ll11_dns_query_ul));
2700
2701 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2702 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2703 llc_ui_ll11_dns_resp_dl,
2704 sizeof(llc_ui_ll11_dns_resp_dl));
2705
2706 dump_peers(stdout, 0, 0, &gbcfg);
2707
2708 /* Other messages */
2709 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2710 local_bss_tlli, 1, 12);
2711
2712 dump_peers(stdout, 0, 0, &gbcfg);
2713
2714 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2715 local_sgsn_tlli, 1, 12);
2716
2717 dump_peers(stdout, 0, 0, &gbcfg);
2718
2719 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2720
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
2723 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2724
2725 dump_peers(stdout, 0, 0, &gbcfg);
2726
2727 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2728
2729 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2730 foreign_bss_tlli2, &rai_unknown, cell_id,
2731 GPRS_SAPI_GMM, bss_nu++,
2732 dtap_attach_req, sizeof(dtap_attach_req));
2733
2734 dump_peers(stdout, 0, 0, &gbcfg);
2735
2736 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2737 foreign_bss_tlli2, &rai_bss, cell_id,
2738 GPRS_SAPI_GMM, bss_nu++,
2739 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2740
2741 dump_peers(stdout, 0, 0, &gbcfg);
2742
2743 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2744 random_sgsn_tlli2, 0, NULL, 0,
2745 GPRS_SAPI_GMM, sgsn_nu++,
2746 dtap_identity_req, sizeof(dtap_identity_req));
2747
2748 dump_peers(stdout, 0, 0, &gbcfg);
2749
2750 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2751 foreign_bss_tlli2, &rai_bss, cell_id,
2752 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002753 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002754
2755 dump_peers(stdout, 0, 0, &gbcfg);
2756
2757 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2758 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2759 GPRS_SAPI_GMM, sgsn_nu++,
2760 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2761
2762 dump_peers(stdout, 0, 0, &gbcfg);
2763
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002764 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2765 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2766 OSMO_ASSERT(link_info);
2767 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2768 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2769 OSMO_ASSERT(!link_info->tlli.bss_validated);
2770 OSMO_ASSERT(!link_info->tlli.net_validated);
2771 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2772 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2773 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
2774 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2775 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2776 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002777
2778 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2779 local_bss_tlli2, &rai_bss, cell_id,
2780 GPRS_SAPI_GMM, bss_nu++,
2781 dtap_attach_complete, sizeof(dtap_attach_complete));
2782
2783 dump_peers(stdout, 0, 0, &gbcfg);
2784
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002785 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2786 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
2787 OSMO_ASSERT(link_info);
2788 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2789 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2790 OSMO_ASSERT(link_info->tlli.bss_validated);
2791 OSMO_ASSERT(!link_info->tlli.net_validated);
2792 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2793 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
2794 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2795 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002796
2797 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2798 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2799 GPRS_SAPI_GMM, sgsn_nu++,
2800 dtap_gmm_information, sizeof(dtap_gmm_information));
2801
2802 dump_peers(stdout, 0, 0, &gbcfg);
2803
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002804 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2805 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
2806 OSMO_ASSERT(link_info);
2807 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
2808 OSMO_ASSERT(link_info->tlli.assigned == 0);
2809 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
2810 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002811
2812 /* Non-DTAP */
2813 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2814 local_bss_tlli2, &rai_bss, cell_id,
2815 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2816
2817 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2818 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2819 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2820
2821 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2822 local_bss_tlli2, &rai_bss, cell_id,
2823 llc_ui_ll11_dns_query_ul,
2824 sizeof(llc_ui_ll11_dns_query_ul));
2825
2826 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2827 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2828 llc_ui_ll11_dns_resp_dl,
2829 sizeof(llc_ui_ll11_dns_resp_dl));
2830
2831 dump_peers(stdout, 0, 0, &gbcfg);
2832
2833 /* Other messages */
2834 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2835 local_bss_tlli2, 1, 12);
2836
2837 dump_peers(stdout, 0, 0, &gbcfg);
2838
2839 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2840 local_sgsn_tlli2, 1, 12);
2841
2842 dump_peers(stdout, 0, 0, &gbcfg);
2843
2844 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2845
2846 dump_peers(stdout, 0, 0, &gbcfg);
2847
2848 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2849
2850 dump_peers(stdout, 0, 0, &gbcfg);
2851
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002852 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
2853
2854 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2855 foreign_bss_tlli3, &rai_unknown, cell_id,
2856 GPRS_SAPI_GMM, bss_nu++,
2857 dtap_attach_req, sizeof(dtap_attach_req));
2858
2859 dump_peers(stdout, 0, 0, &gbcfg);
2860
2861 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2862 foreign_bss_tlli3, &rai_bss, cell_id,
2863 GPRS_SAPI_GMM, bss_nu++,
2864 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2865
2866 dump_peers(stdout, 0, 0, &gbcfg);
2867
2868 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2869 random_sgsn_tlli3, 0, NULL, 0,
2870 GPRS_SAPI_GMM, sgsn_nu++,
2871 dtap_identity_req, sizeof(dtap_identity_req));
2872
2873 dump_peers(stdout, 0, 0, &gbcfg);
2874
2875 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2876 foreign_bss_tlli3, &rai_bss, cell_id,
2877 GPRS_SAPI_GMM, bss_nu++,
2878 dtap_identity3_resp, sizeof(dtap_identity3_resp));
2879
2880 dump_peers(stdout, 0, 0, &gbcfg);
2881
2882 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
2883 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
2884 GPRS_SAPI_GMM, sgsn_nu++,
2885 dtap_attach_acc, sizeof(dtap_attach_acc));
2886
2887 dump_peers(stdout, 0, 0, &gbcfg);
2888
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002889 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
2890 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
2891 OSMO_ASSERT(link_info);
2892 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2893 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
2894 OSMO_ASSERT(!link_info->tlli.bss_validated);
2895 OSMO_ASSERT(!link_info->tlli.net_validated);
2896 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2897 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2898 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
2899 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2900 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2901 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002902
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002903 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2904 local_bss_tlli3, &rai_bss, cell_id,
2905 GPRS_SAPI_GMM, bss_nu++,
2906 dtap_attach_complete, sizeof(dtap_attach_complete));
2907
2908 dump_peers(stdout, 0, 0, &gbcfg);
2909
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002910 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002911 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002912 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
2913 OSMO_ASSERT(link_info);
2914 OSMO_ASSERT(link_info != other_info);
2915 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2916 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
2917 OSMO_ASSERT(link_info->tlli.bss_validated);
2918 OSMO_ASSERT(!link_info->tlli.net_validated);
2919 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2920 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
2921 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2922 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002923
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002924 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2925 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2926 GPRS_SAPI_GMM, sgsn_nu++,
2927 dtap_gmm_information, sizeof(dtap_gmm_information));
2928
2929 dump_peers(stdout, 0, 0, &gbcfg);
2930
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002931 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002932 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002933 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
2934 OSMO_ASSERT(link_info);
2935 OSMO_ASSERT(link_info != other_info);
2936 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2937 OSMO_ASSERT(link_info->tlli.assigned == 0);
2938 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2939 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002940
2941
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002942 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2943
2944 /* Detach */
2945 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2946 local_bss_tlli, &rai_bss, cell_id,
2947 GPRS_SAPI_GMM, bss_nu++,
2948 dtap_detach_req, sizeof(dtap_detach_req));
2949
2950 dump_peers(stdout, 0, 0, &gbcfg);
2951
2952 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2953 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2954 GPRS_SAPI_GMM, sgsn_nu++,
2955 dtap_detach_acc, sizeof(dtap_detach_acc));
2956
2957 dump_peers(stdout, 0, 0, &gbcfg);
2958
2959 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2960
2961 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2962 local_bss_tlli2, &rai_bss, cell_id,
2963 GPRS_SAPI_GMM, bss_nu++,
2964 dtap_detach_req, sizeof(dtap_detach_req));
2965
2966 dump_peers(stdout, 0, 0, &gbcfg);
2967
2968 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2969 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2970 GPRS_SAPI_GMM, sgsn_nu++,
2971 dtap_detach_acc, sizeof(dtap_detach_acc));
2972
2973 dump_peers(stdout, 0, 0, &gbcfg);
2974
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002975 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
2976
2977 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2978 local_bss_tlli3, &rai_bss, cell_id,
2979 GPRS_SAPI_GMM, bss_nu++,
2980 dtap_detach_req, sizeof(dtap_detach_req));
2981
2982 dump_peers(stdout, 0, 0, &gbcfg);
2983
2984 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2985 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
2986 GPRS_SAPI_GMM, sgsn_nu++,
2987 dtap_detach_acc, sizeof(dtap_detach_acc));
2988
2989 dump_peers(stdout, 0, 0, &gbcfg);
2990
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002991 dump_global(stdout, 0);
2992
2993 gbprox_reset(&gbcfg);
2994 gprs_ns_destroy(nsi);
2995 nsi = NULL;
2996}
2997
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02002998static void test_gbproxy_keep_info()
2999{
3000 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3001 struct sockaddr_in bss_peer[1] = {{0},};
3002 struct sockaddr_in sgsn_peer= {0};
3003 struct gprs_ra_id rai_bss =
3004 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3005 uint16_t cell_id = 0x1234;
3006
3007 const uint32_t ptmsi = 0xefe2b700;
3008 const uint32_t local_tlli = 0xefe2b700;
3009 const uint32_t foreign_tlli = 0xafe2b700;
3010
3011 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003012 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003013 struct gbproxy_peer *peer;
3014 unsigned bss_nu = 0;
3015 unsigned sgsn_nu = 0;
3016
3017 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3018
3019 bssgp_nsi = nsi;
3020 gbcfg.nsi = bssgp_nsi;
3021 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3022 gbcfg.patch_ptmsi = 0;
3023 gbcfg.acquire_imsi = 1;
3024 gbcfg.bss_ptmsi_state = 0;
3025 gbcfg.sgsn_tlli_state = 1;
3026 gbcfg.core_mcc = 0;
3027 gbcfg.core_mnc = 0;
3028 gbcfg.core_apn = NULL;
3029 gbcfg.core_apn_size = 0;
3030 gbcfg.route_to_sgsn2 = 0;
3031 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003032 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003033
3034 configure_sgsn_peer(&sgsn_peer);
3035 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3036
3037 printf("=== %s ===\n", __func__);
3038 printf("--- Initialise SGSN ---\n\n");
3039
3040 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3041
3042 printf("--- Initialise BSS 1 ---\n\n");
3043
3044 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3045 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3046
3047 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3048 OSMO_ASSERT(peer != NULL);
3049
3050 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3051
3052 gprs_dump_nsi(nsi);
3053 dump_global(stdout, 0);
3054 dump_peers(stdout, 0, 0, &gbcfg);
3055
3056 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3057
3058 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3059 foreign_tlli, &rai_bss, cell_id,
3060 GPRS_SAPI_GMM, bss_nu++,
3061 dtap_attach_req, sizeof(dtap_attach_req));
3062
3063 dump_peers(stdout, 0, 0, &gbcfg);
3064
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003065 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3066 OSMO_ASSERT(link_info);
3067 OSMO_ASSERT(link_info->imsi_len == 0);
3068 OSMO_ASSERT(!link_info->is_deregistered);
3069 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003070
3071 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3072 foreign_tlli, &rai_bss, cell_id,
3073 GPRS_SAPI_GMM, bss_nu++,
3074 dtap_identity_resp, sizeof(dtap_identity_resp));
3075
3076 dump_peers(stdout, 0, 0, &gbcfg);
3077
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003078 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3079 OSMO_ASSERT(link_info);
3080 OSMO_ASSERT(link_info->imsi_len > 0);
3081 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003082
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003083 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3084 foreign_tlli, 0, NULL, 0,
3085 GPRS_SAPI_GMM, sgsn_nu++,
3086 dtap_identity_req, sizeof(dtap_identity_req));
3087
3088 dump_peers(stdout, 0, 0, &gbcfg);
3089
3090 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3091 foreign_tlli, &rai_bss, cell_id,
3092 GPRS_SAPI_GMM, bss_nu++,
3093 dtap_identity_resp, sizeof(dtap_identity_resp));
3094
3095 dump_peers(stdout, 0, 0, &gbcfg);
3096
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003097 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3098 OSMO_ASSERT(link_info);
3099 OSMO_ASSERT(link_info->imsi_len > 0);
3100 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003101
3102 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3103 foreign_tlli, 1, imsi, sizeof(imsi),
3104 GPRS_SAPI_GMM, sgsn_nu++,
3105 dtap_attach_acc, sizeof(dtap_attach_acc));
3106
3107 dump_peers(stdout, 0, 0, &gbcfg);
3108
3109 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3110 local_tlli, &rai_bss, cell_id,
3111 GPRS_SAPI_GMM, bss_nu++,
3112 dtap_attach_complete, sizeof(dtap_attach_complete));
3113
3114 dump_peers(stdout, 0, 0, &gbcfg);
3115
3116 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3117 local_tlli, 1, imsi, sizeof(imsi),
3118 GPRS_SAPI_GMM, sgsn_nu++,
3119 dtap_gmm_information, sizeof(dtap_gmm_information));
3120
3121 dump_peers(stdout, 0, 0, &gbcfg);
3122
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003123 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3124 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003125
3126 /* Detach (MO) */
3127 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3128 local_tlli, &rai_bss, cell_id,
3129 GPRS_SAPI_GMM, bss_nu++,
3130 dtap_detach_req, sizeof(dtap_detach_req));
3131
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003132 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3133 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003134
3135 dump_peers(stdout, 0, 0, &gbcfg);
3136
3137 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3138 local_tlli, 1, imsi, sizeof(imsi),
3139 GPRS_SAPI_GMM, sgsn_nu++,
3140 dtap_detach_acc, sizeof(dtap_detach_acc));
3141
3142 dump_peers(stdout, 0, 0, &gbcfg);
3143
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003144 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3145 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3146 OSMO_ASSERT(link_info);
3147 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003148
3149 /* Re-Attach */
3150 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3151 foreign_tlli, &rai_bss, cell_id,
3152 GPRS_SAPI_GMM, bss_nu++,
3153 dtap_attach_req3, sizeof(dtap_attach_req3));
3154
3155 dump_peers(stdout, 0, 0, &gbcfg);
3156
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003157 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3158 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3159 OSMO_ASSERT(link_info);
3160 OSMO_ASSERT(link_info == link_info2);
3161 OSMO_ASSERT(link_info->imsi_len != 0);
3162 OSMO_ASSERT(!link_info->is_deregistered);
3163 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003164
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003165 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3166 foreign_tlli, 1, imsi, sizeof(imsi),
3167 GPRS_SAPI_GMM, sgsn_nu++,
3168 dtap_attach_acc, sizeof(dtap_attach_acc));
3169
3170 dump_peers(stdout, 0, 0, &gbcfg);
3171
3172 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3173 local_tlli, &rai_bss, cell_id,
3174 GPRS_SAPI_GMM, bss_nu++,
3175 dtap_attach_complete, sizeof(dtap_attach_complete));
3176
3177 dump_peers(stdout, 0, 0, &gbcfg);
3178
3179 /* Detach (MT) */
3180 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3181 local_tlli, 1, imsi, sizeof(imsi),
3182 GPRS_SAPI_GMM, sgsn_nu++,
3183 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3184
3185 dump_peers(stdout, 0, 0, &gbcfg);
3186
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003187 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3188 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003189
3190 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3191 local_tlli, &rai_bss, cell_id,
3192 GPRS_SAPI_GMM, bss_nu++,
3193 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3194
3195 dump_peers(stdout, 0, 0, &gbcfg);
3196
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003197 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3198 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3199 OSMO_ASSERT(link_info);
3200 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003201
3202 /* Re-Attach */
3203 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3204 foreign_tlli, &rai_bss, cell_id,
3205 GPRS_SAPI_GMM, bss_nu++,
3206 dtap_attach_req3, sizeof(dtap_attach_req3));
3207
3208 dump_peers(stdout, 0, 0, &gbcfg);
3209
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003210 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3211 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3212 OSMO_ASSERT(link_info);
3213 OSMO_ASSERT(link_info == link_info2);
3214 OSMO_ASSERT(link_info->imsi_len != 0);
3215 OSMO_ASSERT(!link_info->is_deregistered);
3216 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003217
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003218 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3219 foreign_tlli, 1, imsi, sizeof(imsi),
3220 GPRS_SAPI_GMM, sgsn_nu++,
3221 dtap_attach_acc, sizeof(dtap_attach_acc));
3222
3223 dump_peers(stdout, 0, 0, &gbcfg);
3224
3225 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3226 local_tlli, &rai_bss, cell_id,
3227 GPRS_SAPI_GMM, bss_nu++,
3228 dtap_attach_complete, sizeof(dtap_attach_complete));
3229
3230 dump_peers(stdout, 0, 0, &gbcfg);
3231
3232 /* Detach (MT) */
3233 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3234 local_tlli, 1, imsi, sizeof(imsi),
3235 GPRS_SAPI_GMM, sgsn_nu++,
3236 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3237
3238 dump_peers(stdout, 0, 0, &gbcfg);
3239
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003240 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3241 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003242
3243 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3244 local_tlli, &rai_bss, cell_id,
3245 GPRS_SAPI_GMM, bss_nu++,
3246 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3247
3248 dump_peers(stdout, 0, 0, &gbcfg);
3249
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003250 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3251 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3252 OSMO_ASSERT(link_info);
3253 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003254
3255 /* Re-Attach */
3256 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3257 foreign_tlli, &rai_bss, cell_id,
3258 GPRS_SAPI_GMM, bss_nu++,
3259 dtap_attach_req3, sizeof(dtap_attach_req3));
3260
3261 dump_peers(stdout, 0, 0, &gbcfg);
3262
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003263 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3264 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3265 OSMO_ASSERT(link_info);
3266 OSMO_ASSERT(link_info == link_info2);
3267 OSMO_ASSERT(link_info->imsi_len != 0);
3268 OSMO_ASSERT(!link_info->is_deregistered);
3269 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003270
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003271 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3272 foreign_tlli, 1, imsi, sizeof(imsi),
3273 GPRS_SAPI_GMM, sgsn_nu++,
3274 dtap_attach_acc, sizeof(dtap_attach_acc));
3275
3276 dump_peers(stdout, 0, 0, &gbcfg);
3277
3278 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3279 local_tlli, &rai_bss, cell_id,
3280 GPRS_SAPI_GMM, bss_nu++,
3281 dtap_attach_complete, sizeof(dtap_attach_complete));
3282
3283 dump_peers(stdout, 0, 0, &gbcfg);
3284
3285 /* RA update procedure (reject -> Detach) */
3286 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3287 local_tlli, &rai_bss, 0x7080,
3288 GPRS_SAPI_GMM, bss_nu++,
3289 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3290
3291 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3292 local_tlli, 1, imsi, sizeof(imsi),
3293 GPRS_SAPI_GMM, sgsn_nu++,
3294 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3295
3296 dump_peers(stdout, 0, 0, &gbcfg);
3297
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003298 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3299 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3300 OSMO_ASSERT(link_info);
3301 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003302
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003303 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3304 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3305 foreign_tlli, &rai_bss, cell_id,
3306 GPRS_SAPI_GMM, bss_nu++,
3307 dtap_attach_req, sizeof(dtap_attach_req));
3308
3309 dump_peers(stdout, 0, 0, &gbcfg);
3310
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003311 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3312 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3313 OSMO_ASSERT(link_info);
3314 OSMO_ASSERT(link_info != link_info2);
3315 OSMO_ASSERT(link_info->imsi_len == 0);
3316 OSMO_ASSERT(!link_info->is_deregistered);
3317 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003318
3319 /* This wouldn't happen in reality, since the Attach Request hadn't
3320 * been forwarded to the SGSN.
3321 * TODO: Add the missing messages.
3322 */
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003323 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3324 foreign_tlli, 1, imsi, sizeof(imsi),
3325 GPRS_SAPI_GMM, sgsn_nu++,
3326 dtap_attach_acc, sizeof(dtap_attach_acc));
3327
3328 dump_peers(stdout, 0, 0, &gbcfg);
3329
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003330 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3331 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3332 OSMO_ASSERT(link_info);
3333 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003334 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003335 OSMO_ASSERT(!link_info->is_deregistered);
3336 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003337
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003338 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3339 local_tlli, &rai_bss, cell_id,
3340 GPRS_SAPI_GMM, bss_nu++,
3341 dtap_attach_complete, sizeof(dtap_attach_complete));
3342
3343 dump_peers(stdout, 0, 0, &gbcfg);
3344
3345 /* Detach (MT) */
3346 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3347 local_tlli, 1, imsi, sizeof(imsi),
3348 GPRS_SAPI_GMM, sgsn_nu++,
3349 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3350
3351 dump_peers(stdout, 0, 0, &gbcfg);
3352
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003353 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3354 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003355
3356 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3357 local_tlli, &rai_bss, cell_id,
3358 GPRS_SAPI_GMM, bss_nu++,
3359 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3360
3361 dump_peers(stdout, 0, 0, &gbcfg);
3362
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003363 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3364 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3365 OSMO_ASSERT(link_info);
3366 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003367
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003368 dump_global(stdout, 0);
3369
3370 gbprox_reset(&gbcfg);
3371 gprs_ns_destroy(nsi);
3372 nsi = NULL;
3373}
3374
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003375/* TODO: Move tlv testing to libosmocore */
3376int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3377int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3378 uint8_t **value);
3379int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3380 size_t *value_len);
3381int lv_shift(uint8_t **data, size_t *data_len,
3382 uint8_t **value, size_t *value_len);
3383
3384static void check_tlv_match(uint8_t **data, size_t *data_len,
3385 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3386{
3387 uint8_t *value;
3388 size_t value_len;
3389 int rc;
3390
3391 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3392 OSMO_ASSERT(rc == 0);
3393
3394 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003395 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003396 OSMO_ASSERT(value_len == exp_len);
3397 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3398}
3399
3400static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3401 uint8_t tag, size_t len, const uint8_t *exp_val)
3402{
3403 uint8_t *value;
3404 int rc;
3405
3406 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3407 OSMO_ASSERT(rc == 0);
3408
3409 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003410 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003411 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3412}
3413
3414static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3415 size_t len, const uint8_t *exp_val)
3416{
3417 uint8_t *value;
3418 int rc;
3419
3420 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003421 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003422 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3423}
3424
3425static void check_lv_shift(uint8_t **data, size_t *data_len,
3426 size_t exp_len, const uint8_t *exp_val)
3427{
3428 uint8_t *value;
3429 size_t value_len;
3430 int rc;
3431
3432 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003433 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003434 OSMO_ASSERT(value_len == exp_len);
3435 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3436}
3437
3438static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3439 const uint8_t *test_data)
3440{
3441 uint8_t buf[300] = {0};
3442
3443 uint8_t *unchanged_ptr = buf - 1;
3444 size_t unchanged_len = 0xdead;
3445 size_t tmp_data_len = data_len;
3446 uint8_t *value = unchanged_ptr;
3447 size_t value_len = unchanged_len;
3448 uint8_t *data = buf;
3449
3450 OSMO_ASSERT(data_len <= sizeof(buf));
3451
3452 tlv_put(data, tag, len, test_data);
3453 if (data_len < len + 2) {
3454 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3455 tag, &value, &value_len));
3456 OSMO_ASSERT(tmp_data_len == 0);
3457 OSMO_ASSERT(data == buf + data_len);
3458 OSMO_ASSERT(value == unchanged_ptr);
3459 OSMO_ASSERT(value_len == unchanged_len);
3460 } else {
3461 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3462 tag, &value, &value_len));
3463 OSMO_ASSERT(value != unchanged_ptr);
3464 OSMO_ASSERT(value_len != unchanged_len);
3465 }
3466}
3467
3468static void check_tv_fixed_match_data_len(size_t data_len,
3469 uint8_t tag, size_t len,
3470 const uint8_t *test_data)
3471{
3472 uint8_t buf[300] = {0};
3473
3474 uint8_t *unchanged_ptr = buf - 1;
3475 size_t tmp_data_len = data_len;
3476 uint8_t *value = unchanged_ptr;
3477 uint8_t *data = buf;
3478
3479 OSMO_ASSERT(data_len <= sizeof(buf));
3480
3481 tv_fixed_put(data, tag, len, test_data);
3482
3483 if (data_len < len + 1) {
3484 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3485 tag, len, &value));
3486 OSMO_ASSERT(tmp_data_len == 0);
3487 OSMO_ASSERT(data == buf + data_len);
3488 OSMO_ASSERT(value == unchanged_ptr);
3489 } else {
3490 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3491 tag, len, &value));
3492 OSMO_ASSERT(value != unchanged_ptr);
3493 }
3494}
3495
3496static void check_v_fixed_shift_data_len(size_t data_len,
3497 size_t len, const uint8_t *test_data)
3498{
3499 uint8_t buf[300] = {0};
3500
3501 uint8_t *unchanged_ptr = buf - 1;
3502 size_t tmp_data_len = data_len;
3503 uint8_t *value = unchanged_ptr;
3504 uint8_t *data = buf;
3505
3506 OSMO_ASSERT(data_len <= sizeof(buf));
3507
3508 memcpy(data, test_data, len);
3509
3510 if (data_len < len) {
3511 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3512 len, &value));
3513 OSMO_ASSERT(tmp_data_len == 0);
3514 OSMO_ASSERT(data == buf + data_len);
3515 OSMO_ASSERT(value == unchanged_ptr);
3516 } else {
3517 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3518 len, &value));
3519 OSMO_ASSERT(value != unchanged_ptr);
3520 }
3521}
3522
3523static void check_lv_shift_data_len(size_t data_len,
3524 size_t len, const uint8_t *test_data)
3525{
3526 uint8_t buf[300] = {0};
3527
3528 uint8_t *unchanged_ptr = buf - 1;
3529 size_t unchanged_len = 0xdead;
3530 size_t tmp_data_len = data_len;
3531 uint8_t *value = unchanged_ptr;
3532 size_t value_len = unchanged_len;
3533 uint8_t *data = buf;
3534
3535 lv_put(data, len, test_data);
3536 if (data_len < len + 1) {
3537 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3538 &value, &value_len));
3539 OSMO_ASSERT(tmp_data_len == 0);
3540 OSMO_ASSERT(data == buf + data_len);
3541 OSMO_ASSERT(value == unchanged_ptr);
3542 OSMO_ASSERT(value_len == unchanged_len);
3543 } else {
3544 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3545 &value, &value_len));
3546 OSMO_ASSERT(value != unchanged_ptr);
3547 OSMO_ASSERT(value_len != unchanged_len);
3548 }
3549}
3550
3551static void test_tlv_shift_functions()
3552{
3553 uint8_t test_data[1024];
3554 uint8_t buf[1024];
3555 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003556 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003557 uint8_t *data;
3558 size_t data_len;
3559 const uint8_t tag = 0x1a;
3560
3561 printf("Test shift functions\n");
3562
3563 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3564 test_data[i] = (uint8_t)i;
3565
3566 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003567 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003568
3569 memset(buf, 0xee, sizeof(buf));
3570 data_end = data = buf;
3571
3572 for (i = 0; i < iterations; i++) {
3573 data_end = tlv_put(data_end, tag, len, test_data);
3574 data_end = tv_fixed_put(data_end, tag, len, test_data);
3575 /* v_fixed_put */
3576 memcpy(data_end, test_data, len);
3577 data_end += len;
3578 data_end = lv_put(data_end, len, test_data);
3579 }
3580
3581 data_len = data_end - data;
3582 OSMO_ASSERT(data_len <= sizeof(buf));
3583
3584 for (i = 0; i < iterations; i++) {
3585 check_tlv_match(&data, &data_len, tag, len, test_data);
3586 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3587 check_v_fixed_shift(&data, &data_len, len, test_data);
3588 check_lv_shift(&data, &data_len, len, test_data);
3589 }
3590
3591 OSMO_ASSERT(data == data_end);
3592
3593 /* Test at end of data */
3594
3595 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3596 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3597 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3598 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3599
3600 /* Test invalid data_len */
3601 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3602 check_tlv_match_data_len(data_len, tag, len, test_data);
3603 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3604 check_v_fixed_shift_data_len(data_len, len, test_data);
3605 check_lv_shift_data_len(data_len, len, test_data);
3606 }
3607 }
3608}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003609
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003610struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003611 struct gbproxy_peer *peer, uint32_t tlli,
3612 const uint8_t *imsi, size_t imsi_len, time_t now)
3613{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003614 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003615 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003616 int tlli_already_known = 0;
3617
3618 /* Check, whether the IMSI matches */
3619 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003620 imsi_matches = gbproxy_check_imsi(peer, imsi, imsi_len);
3621 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003622 return NULL;
3623 }
3624
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003625 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003626
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003627 if (!link_info) {
3628 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003629
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003630 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003631 /* TLLI has changed somehow, adjust it */
3632 LOGP(DGPRS, LOGL_INFO,
3633 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003634 link_info->tlli.current, tlli);
3635 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003636 }
3637 }
3638
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003639 if (!link_info) {
3640 link_info = gbproxy_link_info_alloc(peer);
3641 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003642 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003643 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003644 tlli_already_known = 1;
3645 }
3646
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003647 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003648
3649 if (!tlli_already_known)
3650 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3651
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003652 gbproxy_attach_link_info(peer, now, link_info);
3653 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003654
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003655 if (imsi_matches >= 0)
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003656 link_info->imsi_matches = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003657
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003658 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003659}
3660
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003661static void test_gbproxy_tlli_expire(void)
3662{
3663 struct gbproxy_config cfg = {0};
3664 struct gbproxy_peer *peer;
3665 const char *err_msg = NULL;
3666 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3667 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003668 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003669 const uint32_t tlli1 = 1234 | 0xc0000000;
3670 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003671 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003672 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003673 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003674
3675 printf("Test TLLI info expiry\n\n");
3676
3677 gbproxy_init_config(&cfg);
3678
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003679 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003680 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3681 err_msg);
3682 OSMO_ASSERT(err_msg == NULL);
3683 }
3684
3685 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003686 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003687
3688 printf("Test TLLI replacement:\n");
3689
3690 cfg.tlli_max_len = 0;
3691 cfg.tlli_max_age = 0;
3692 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003693 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003694
3695 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003696 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003697 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003698 OSMO_ASSERT(link_info);
3699 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003700 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003701
3702 /* replace the old entry */
3703 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003704 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003705 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003706 OSMO_ASSERT(link_info);
3707 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003708 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003709
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003710 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003711
3712 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003713 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3714 OSMO_ASSERT(link_info);
3715 OSMO_ASSERT(link_info->tlli.current == tlli2);
3716 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3717 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003718
3719 printf("\n");
3720
3721 gbproxy_peer_free(peer);
3722 }
3723
3724 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003725 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003726
3727 printf("Test IMSI replacement:\n");
3728
3729 cfg.tlli_max_len = 0;
3730 cfg.tlli_max_age = 0;
3731 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003732 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003733
3734 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003735 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003736 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003737 OSMO_ASSERT(link_info);
3738 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003739 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003740
3741 /* try to replace the old entry */
3742 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003743 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003744 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003745 OSMO_ASSERT(link_info);
3746 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003747 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003748
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003749 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003750
3751 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003752 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3753 OSMO_ASSERT(!link_info);
3754 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3755 OSMO_ASSERT(link_info);
3756 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003757
3758 printf("\n");
3759
3760 gbproxy_peer_free(peer);
3761 }
3762
3763 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003764 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003765 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003766
3767 printf("Test TLLI expiry, max_len == 1:\n");
3768
3769 cfg.tlli_max_len = 1;
3770 cfg.tlli_max_age = 0;
3771 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003772 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003773
3774 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003775 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003776 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003777
3778 /* replace the old entry */
3779 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003780 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003781 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003782
Jacob Erlbeck51fde082014-09-19 16:40:21 +02003783 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003784 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003785 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003786
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003787 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003788
3789 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003790 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3791 OSMO_ASSERT(!link_info);
3792 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3793 OSMO_ASSERT(link_info);
3794 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003795
3796 printf("\n");
3797
3798 gbproxy_peer_free(peer);
3799 }
3800
3801 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003802 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02003803 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003804
3805 printf("Test TLLI expiry, max_age == 1:\n");
3806
3807 cfg.tlli_max_len = 0;
3808 cfg.tlli_max_age = 1;
3809 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003810 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003811
3812 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003813 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003814 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003815
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003816 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003817 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003818 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003819 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003820
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003821 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003822 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003823 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003824
3825 dump_peers(stdout, 2, now + 2, &cfg);
3826
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003827 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003828 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3829 OSMO_ASSERT(!link_info);
3830 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3831 OSMO_ASSERT(link_info);
3832 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003833
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003834 printf("\n");
3835
3836 gbproxy_peer_free(peer);
3837 }
3838
3839 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003840 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003841 int num_removed;
3842
3843 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
3844
3845 cfg.tlli_max_len = 0;
3846 cfg.tlli_max_age = 1;
3847 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003848 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003849
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003850 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003851 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003852 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003853
3854 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003855 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003856 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003857 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003858
3859 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003860 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003861 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003862 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003863
3864 dump_peers(stdout, 2, now + 2, &cfg);
3865
3866 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003867 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003868 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003869 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003870
3871 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003872
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003873 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003874 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3875 OSMO_ASSERT(!link_info);
3876 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3877 OSMO_ASSERT(!link_info);
3878 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
3879 OSMO_ASSERT(link_info);
3880 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02003881
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003882 printf("\n");
3883
3884 gbproxy_peer_free(peer);
3885 }
3886}
3887
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003888static void test_gbproxy_imsi_matching(void)
3889{
3890 struct gbproxy_config cfg = {0};
3891 struct gbproxy_peer *peer;
3892 const char *err_msg = NULL;
3893 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
3894 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3895 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
3896 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
3897 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
3898 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
3899 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
3900 const char *filter_re1 = ".*";
3901 const char *filter_re2 = "^1234";
3902 const char *filter_re3 = "^4321";
3903 const char *filter_re4_bad = "^12[";
3904
3905 printf("=== Test IMSI/TMSI matching ===\n\n");
3906
3907 gbproxy_init_config(&cfg);
3908 OSMO_ASSERT(cfg.check_imsi == 0);
3909
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003910 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003911 OSMO_ASSERT(cfg.check_imsi == 1);
3912
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003913 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003914 OSMO_ASSERT(cfg.check_imsi == 1);
3915
3916 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003917 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003918 OSMO_ASSERT(err_msg != NULL);
3919 OSMO_ASSERT(cfg.check_imsi == 0);
3920
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003921 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003922 OSMO_ASSERT(cfg.check_imsi == 1);
3923
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003924 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003925 OSMO_ASSERT(cfg.check_imsi == 0);
3926
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003927 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003928 OSMO_ASSERT(cfg.check_imsi == 1);
3929
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003930 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003931 OSMO_ASSERT(cfg.check_imsi == 0);
3932
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003933 peer = gbproxy_peer_alloc(&cfg, 20);
3934
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003935 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003936 OSMO_ASSERT(cfg.check_imsi == 1);
3937
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003938 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3939 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003940 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003941 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003942 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003943 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3944 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3945 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3946 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3947 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003948
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003949 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003950 OSMO_ASSERT(cfg.check_imsi == 1);
3951
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003952 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3953 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3954 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3955 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3956 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3957 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3958 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003959
3960 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3961
3962 gbproxy_peer_free(peer);
3963}
3964
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003965static struct log_info_cat gprs_categories[] = {
3966 [DGPRS] = {
3967 .name = "DGPRS",
3968 .description = "GPRS Packet Service",
3969 .enabled = 1, .loglevel = LOGL_DEBUG,
3970 },
3971 [DNS] = {
3972 .name = "DNS",
3973 .description = "GPRS Network Service (NS)",
3974 .enabled = 1, .loglevel = LOGL_INFO,
3975 },
3976 [DBSSGP] = {
3977 .name = "DBSSGP",
3978 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3979 .enabled = 1, .loglevel = LOGL_DEBUG,
3980 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003981};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003982
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003983static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003984 .cat = gprs_categories,
3985 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003986};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003987
3988int main(int argc, char **argv)
3989{
3990 osmo_init_logging(&info);
3991 log_set_use_color(osmo_stderr_target, 0);
3992 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003993 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003994
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003995 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003996 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3997 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003998
3999 rate_ctr_init(NULL);
4000
4001 setlinebuf(stdout);
4002
4003 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004004 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004005 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004006 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004007 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004008 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004009 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004010 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004011 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004012 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004013 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004014 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004015 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004016 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004017
4018 exit(EXIT_SUCCESS);
4019}