blob: 5aa301b6aa97389193a66ba8ca3ebacd76f21b52 [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 Erlbeckacfaff32014-09-22 18:54:34 +020036#include <openbsc/gprs_gb_parse.h>
37#include <openbsc/gsm_04_08_gprs.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020038#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020039
40#define REMOTE_BSS_ADDR 0x01020304
41#define REMOTE_SGSN_ADDR 0x05060708
42
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020043#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020044
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020045#define REMOTE_SGSN2_ADDR 0x15161718
46#define SGSN2_NSEI 0x0102
47
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020048#define MATCH_ANY (-1)
49
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020050struct gbproxy_config gbcfg = {0};
51
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020052struct llist_head *received_messages = NULL;
53
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020054static int dump_global(FILE *stream, int indent)
55{
56 unsigned int i;
57 const struct rate_ctr_group_desc *desc;
58 int rc;
59
60 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
61 if (rc < 0)
62 return rc;
63
64 desc = gbcfg.ctrg->desc;
65
66 for (i = 0; i < desc->num_ctr; i++) {
67 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
68 if (ctr->current) {
69 rc = fprintf(stream, "%*s %s: %llu\n",
70 indent, "",
71 desc->ctr_desc[i].description,
72 (long long)ctr->current);
73
74 if (rc < 0)
75 return rc;
76 }
77 }
78
79 return 0;
80}
81
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020082static int dump_peers(FILE *stream, int indent, time_t now,
83 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020085 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020086 struct gprs_ra_id raid;
87 unsigned int i;
88 const struct rate_ctr_group_desc *desc;
89 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020090
91 rc = fprintf(stream, "%*sPeers:\n", indent, "");
92 if (rc < 0)
93 return rc;
94
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020095 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +020096 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020097 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020098 gsm48_parse_ra(&raid, peer->ra);
99
100 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
101 "RAI %u-%u-%u-%u\n",
102 indent, "",
103 peer->nsei, peer->bvci,
104 peer->blocked ? "" : "not ",
105 raid.mcc, raid.mnc, raid.lac, raid.rac);
106
107 if (rc < 0)
108 return rc;
109
110 desc = peer->ctrg->desc;
111
112 for (i = 0; i < desc->num_ctr; i++) {
113 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
114 if (ctr->current) {
115 rc = fprintf(stream, "%*s %s: %llu\n",
116 indent, "",
117 desc->ctr_desc[i].description,
118 (long long)ctr->current);
119
120 if (rc < 0)
121 return rc;
122 }
123 }
124
125 fprintf(stream, "%*s TLLI-Cache: %d\n",
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200126 indent, "", state->logical_link_count);
127 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200128 char mi_buf[200];
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200129 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200130 int stored_msgs = 0;
131 struct llist_head *iter;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200132 enum gbproxy_match_id match_id;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200133 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200134 stored_msgs++;
135
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200136 if (link_info->imsi_len > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200137 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
138 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200139 link_info->imsi,
140 link_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200141 } else {
142 snprintf(mi_buf, sizeof(mi_buf), "(none)");
143 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200144 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200145 indent, "", link_info->tlli.current);
146 if (link_info->tlli.assigned)
147 fprintf(stream, "/%08x", link_info->tlli.assigned);
148 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200149 fprintf(stream, " -> %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200150 link_info->sgsn_tlli.current);
151 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200152 fprintf(stream, "/%08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200153 link_info->sgsn_tlli.assigned);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200154 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200155 fprintf(stream, ", IMSI %s, AGE %d",
156 mi_buf, (int)age);
157
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200158 if (stored_msgs)
159 fprintf(stream, ", STORED %d", stored_msgs);
160
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200161 for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches);
162 ++match_id) {
163 if (cfg->matches[match_id].enable &&
164 link_info->is_matching[match_id]) {
165 fprintf(stream, ", IMSI matches");
166 break;
167 }
168 }
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200169
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200170 if (link_info->imsi_acq_pending)
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200171 fprintf(stream, ", IMSI acquisition in progress");
172
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200173 if (cfg->route_to_sgsn2)
174 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200175 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200176
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200177 if (link_info->is_deregistered)
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200178 fprintf(stream, ", DE-REGISTERED");
179
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200180 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200181 if (rc < 0)
182 return rc;
183 }
184 }
185
186 return 0;
187}
188
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200189const uint8_t *convert_ra(struct gprs_ra_id *raid)
190{
191 static uint8_t buf[6];
192 gsm48_construct_ra(buf, raid);
193 return buf;
194}
195
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200196/* DTAP - Attach Request */
197static const unsigned char dtap_attach_req[] = {
198 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
199 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
200 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
201 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
202 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
203 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200204};
205
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200206/* DTAP - Attach Request (invalid RAI) */
207static const unsigned char dtap_attach_req2[] = {
208 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
209 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
210 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
211 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
212 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
213 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
214};
215
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200216/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
217static const unsigned char dtap_attach_req3[] = {
218 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
219 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
220 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
221 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
222 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
223 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
224};
225
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200226/* DTAP - Identity Request */
227static const unsigned char dtap_identity_req[] = {
228 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200229};
230
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200231/* DTAP - Identity Response */
232static const unsigned char dtap_identity_resp[] = {
233 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
234 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200235};
236
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200237/* DTAP - Identity Response, IMSI 2 */
238static const unsigned char dtap_identity2_resp[] = {
239 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
240 0x16, 0x17, 0x18
241};
242
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200243/* DTAP - Identity Response, IMSI 3 */
244static const unsigned char dtap_identity3_resp[] = {
245 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
246 0x26, 0x27, 0x28
247};
248
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200249/* DTAP - Attach Accept */
250static const unsigned char dtap_attach_acc[] = {
251 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
252 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
253 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200254};
255
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200256/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200257static const unsigned char dtap_attach_acc2[] = {
258 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
259 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
260 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
261};
262
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200263/* DTAP - Attach Complete */
264static const unsigned char dtap_attach_complete[] = {
265 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200266};
267
Jacob Erlbeck2bf32612014-09-22 11:26:58 +0200268/* DTAP - Attach Reject (GPRS services not allowed) */
269static const unsigned char dtap_attach_rej7[] = {
270 0x08, 0x04, 0x07
271};
272
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200273/* DTAP - GMM Information */
274static const unsigned char dtap_gmm_information[] = {
275 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200276};
277
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200278/* DTAP - Routing Area Update Request */
279static const unsigned char dtap_ra_upd_req[] = {
280 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
281 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
282 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
283 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
284 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
285 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
286 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200287};
288
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200289/* DTAP - Routing Area Update Accept */
290static const unsigned char dtap_ra_upd_acc[] = {
291 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
292 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
293 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200294};
295
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200296/* DTAP - Routing Area Update Accept, P-TMSI 2 */
297static const unsigned char dtap_ra_upd_acc2[] = {
298 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
299 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
300 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
301};
302
303/* DTAP - Routing Area Update Accept, P-TMSI 3 */
304static const unsigned char dtap_ra_upd_acc3[] = {
305 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
306 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
307 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
308};
309
310/* DTAP - Routing Area Update Complete */
311static const unsigned char dtap_ra_upd_complete[] = {
312 0x08, 0x0a
313};
314
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200315/* DTAP - Routing Area Update Reject */
316/* cause = 10 ("Implicitly detached"), force_standby = 0 */
317static const unsigned char dtap_ra_upd_rej[] = {
318 0x08, 0x0b, 0x0a, 0x00,
319};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200321/* DTAP - Activate PDP Context Request */
322static const unsigned char dtap_act_pdp_ctx_req[] = {
323 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200324 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
326 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
327 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
328 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200329 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200330};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200331
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200332/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200333/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200334static const unsigned char dtap_detach_po_req[] = {
335 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
336 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200337};
338
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200339/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200340/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200341static const unsigned char dtap_detach_req[] = {
342 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
343 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200344};
345
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200346/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200347static const unsigned char dtap_detach_acc[] = {
348 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200349};
350
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200351/* DTAP - Detach Request (MT) */
352/* normal detach, reattach required, implicitly detached */
353static const unsigned char dtap_mt_detach_rea_req[] = {
354 0x08, 0x05, 0x01, 0x25, 0x0a
355};
356
357/* DTAP - Detach Request (MT) */
358/* normal detach, reattach not required, implicitly detached */
359static const unsigned char dtap_mt_detach_req[] = {
360 0x08, 0x05, 0x02, 0x25, 0x0a
361};
362
363/* DTAP - Detach Accept (MT) */
364static const unsigned char dtap_mt_detach_acc[] = {
365 0x08, 0x06
366};
367
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200368/* GPRS-LLC - SAPI: LLGMM, U, XID */
369static const unsigned char llc_u_xid_ul[] = {
370 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
371 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
372};
373
374/* GPRS-LLC - SAPI: LLGMM, U, XID */
375static const unsigned char llc_u_xid_dl[] = {
376 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
377 0xe4, 0xa9, 0x1a, 0x9e
378};
379
380/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
381static const unsigned char llc_ui_ll11_dns_query_ul[] = {
382 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
383 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
384 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
385 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
386 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
387 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
388 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
389 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
390 0x8f, 0x07
391};
392
393/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
394static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
395 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
396 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
397 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
398 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
399 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
400 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
401 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
402 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
403 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
404 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
405 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
406 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
407 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
408 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
409 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
410 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
411 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
412 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
413 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
414 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
415 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
416 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
417 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
418 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
419 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
420 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
421};
422
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200423static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
424 struct sockaddr_in *peer, const unsigned char* data,
425 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200426
427static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
428 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
429{
430 /* GPRS Network Service, PDU type: NS_RESET,
431 */
432 unsigned char msg[12] = {
433 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
434 0x04, 0x82, 0x11, 0x22
435 };
436
437 msg[3] = cause;
438 msg[6] = nsvci / 256;
439 msg[7] = nsvci % 256;
440 msg[10] = nsei / 256;
441 msg[11] = nsei % 256;
442
443 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
444}
445
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200446static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
447 uint16_t nsvci, uint16_t nsei)
448{
449 /* GPRS Network Service, PDU type: NS_RESET_ACK,
450 */
451 unsigned char msg[9] = {
452 0x03, 0x01, 0x82, 0x11, 0x22,
453 0x04, 0x82, 0x11, 0x22
454 };
455
456 msg[3] = nsvci / 256;
457 msg[4] = nsvci % 256;
458 msg[7] = nsei / 256;
459 msg[8] = nsei % 256;
460
461 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
462}
463
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200464static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
465{
466 /* GPRS Network Service, PDU type: NS_ALIVE */
467 unsigned char msg[1] = {
468 0x0a
469 };
470
471 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
472}
473
474static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
475{
476 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
477 unsigned char msg[1] = {
478 0x0b
479 };
480
481 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
482}
483
484static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
485{
486 /* GPRS Network Service, PDU type: NS_UNBLOCK */
487 unsigned char msg[1] = {
488 0x06
489 };
490
491 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
492}
493
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200494static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
495{
496 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
497 unsigned char msg[1] = {
498 0x07
499 };
500
501 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
502}
503
504static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
505 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200506 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
507{
508 /* GPRS Network Service, PDU type: NS_UNITDATA */
509 unsigned char msg[4096] = {
510 0x00, 0x00, 0x00, 0x00
511 };
512
513 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
514
515 msg[2] = nsbvci / 256;
516 msg[3] = nsbvci % 256;
517 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
518
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200519 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200520}
521
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200522static void send_bssgp_ul_unitdata(
523 struct gprs_ns_inst *nsi, const char *text,
524 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
525 struct gprs_ra_id *raid, uint16_t cell_id,
526 const uint8_t *llc_msg, size_t llc_msg_size)
527{
528 /* GPRS Network Service, PDU type: NS_UNITDATA */
529 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
530 unsigned char msg[4096] = {
531 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
532 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
533 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
534 };
535
536 size_t bssgp_msg_size = 23 + llc_msg_size;
537
538 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
539
540 gsm48_construct_ra(msg + 10, raid);
541 msg[1] = (uint8_t)(tlli >> 24);
542 msg[2] = (uint8_t)(tlli >> 16);
543 msg[3] = (uint8_t)(tlli >> 8);
544 msg[4] = (uint8_t)(tlli >> 0);
545 msg[16] = cell_id / 256;
546 msg[17] = cell_id % 256;
547 msg[21] = llc_msg_size / 256;
548 msg[22] = llc_msg_size % 256;
549 memcpy(msg + 23, llc_msg, llc_msg_size);
550
551 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
552 src_addr, nsbvci, msg, bssgp_msg_size);
553}
554
555static void send_bssgp_dl_unitdata(
556 struct gprs_ns_inst *nsi, const char *text,
557 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
558 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
559 const uint8_t *llc_msg, size_t llc_msg_size)
560{
561 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
562 unsigned char msg[4096] = {
563 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
564 0x16, 0x82, 0x02, 0x58,
565 };
566 unsigned char racap_drx[] = {
567 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
568 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
569 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
570 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
571 };
572
573 size_t bssgp_msg_size = 0;
574
575 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
576
577 msg[1] = (uint8_t)(tlli >> 24);
578 msg[2] = (uint8_t)(tlli >> 16);
579 msg[3] = (uint8_t)(tlli >> 8);
580 msg[4] = (uint8_t)(tlli >> 0);
581
582 bssgp_msg_size = 12;
583
584 if (with_racap_drx) {
585 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
586 bssgp_msg_size += sizeof(racap_drx);
587 }
588
589 if (imsi) {
590 OSMO_ASSERT(imsi_size <= 127);
591 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
592 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
593 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
594 bssgp_msg_size += 2 + imsi_size;
595 }
596
597 if ((bssgp_msg_size % 4) != 0) {
598 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
599 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
600 msg[bssgp_msg_size + 1] = 0x80 | abytes;
601 memset(msg + bssgp_msg_size + 2, 0, abytes);
602 bssgp_msg_size += 2 + abytes;
603 }
604
605 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
606 if (llc_msg_size < 128) {
607 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
608 bssgp_msg_size += 2;
609 } else {
610 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
611 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
612 bssgp_msg_size += 3;
613 }
614 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
615 bssgp_msg_size += llc_msg_size;
616
617
618 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
619 src_addr, nsbvci, msg, bssgp_msg_size);
620}
621
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200622static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
623 uint16_t bvci)
624{
625 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
626 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200627 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200628 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200629 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
630 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200631 };
632
633 msg[3] = bvci / 256;
634 msg[4] = bvci % 256;
635
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200636 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
637}
638
639static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
640 struct sockaddr_in *src_addr, uint16_t bvci)
641{
642 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
643 * BSSGP RESET_ACK */
644 static unsigned char msg[5] = {
645 0x23, 0x04, 0x82, 0x00,
646 0x00
647 };
648
649 msg[3] = bvci / 256;
650 msg[4] = bvci % 256;
651
652 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200653}
654
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200655static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
656 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200657 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200658 struct gprs_ra_id *raid)
659{
660 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
661 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200662 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
663 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200664 };
665
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200666 msg[3] = (uint8_t)(tlli >> 24);
667 msg[4] = (uint8_t)(tlli >> 16);
668 msg[5] = (uint8_t)(tlli >> 8);
669 msg[6] = (uint8_t)(tlli >> 0);
670
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200671 gsm48_construct_ra(msg + 9, raid);
672
673 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
674}
675
676static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
677 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200678 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200679 struct gprs_ra_id *raid)
680{
681 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
682 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200683 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
684 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200685 0x81, 0x01
686 };
687
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200688 msg[3] = (uint8_t)(tlli >> 24);
689 msg[4] = (uint8_t)(tlli >> 16);
690 msg[5] = (uint8_t)(tlli >> 8);
691 msg[6] = (uint8_t)(tlli >> 0);
692
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200693 gsm48_construct_ra(msg + 9, raid);
694
695 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
696}
697
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200698static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
699 struct sockaddr_in *src_addr,
700 uint16_t bvci, uint32_t tlli,
701 unsigned n_frames, unsigned n_octets)
702{
703 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
704 unsigned char msg[] = {
705 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
706 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
707 /* n octets */ 0xff, 0xff, 0xff
708 };
709
710 msg[3] = (uint8_t)(tlli >> 24);
711 msg[4] = (uint8_t)(tlli >> 16);
712 msg[5] = (uint8_t)(tlli >> 8);
713 msg[6] = (uint8_t)(tlli >> 0);
714 msg[9] = (uint8_t)(n_frames);
715 msg[12] = (uint8_t)(bvci >> 8);
716 msg[13] = (uint8_t)(bvci >> 0);
717 msg[16] = (uint8_t)(n_octets >> 16);
718 msg[17] = (uint8_t)(n_octets >> 8);
719 msg[18] = (uint8_t)(n_octets >> 0);
720
721 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
722}
723
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200724static void send_bssgp_flow_control_bvc(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 */
730 unsigned char msg[] = {
731 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
732 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
733 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
734 };
735
736 msg[3] = tag;
737
738 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
739 msg, sizeof(msg));
740}
741
742static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
743 struct sockaddr_in *src_addr,
744 uint16_t bvci, uint8_t tag)
745{
746 /* GPRS Network Service, PDU type: NS_UNITDATA,
747 * BSSGP FLOW_CONTROL_BVC_ACK */
748 unsigned char msg[] = {
749 0x27, 0x1e, 0x81, /* Tag */ 0xce
750 };
751
752 msg[3] = tag;
753
754 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
755 msg, sizeof(msg));
756}
757
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200758static void send_llc_ul_ui(
759 struct gprs_ns_inst *nsi, const char *text,
760 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
761 struct gprs_ra_id *raid, uint16_t cell_id,
762 unsigned sapi, unsigned nu,
763 const uint8_t *msg, size_t msg_size)
764{
765 unsigned char llc_msg[4096] = {
766 0x00, 0xc0, 0x01
767 };
768
769 size_t llc_msg_size = 3 + msg_size + 3;
770 uint8_t e_bit = 0;
771 uint8_t pm_bit = 1;
772 unsigned fcs;
773
774 nu &= 0x01ff;
775
776 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
777
778 llc_msg[0] = (sapi & 0x0f);
779 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
780 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
781
782 memcpy(llc_msg + 3, msg, msg_size);
783
784 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
785 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
786 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
787 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
788
789 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
790 src_addr, nsbvci, tlli, raid, cell_id,
791 llc_msg, llc_msg_size);
792}
793
794static void send_llc_dl_ui(
795 struct gprs_ns_inst *nsi, const char *text,
796 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
797 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
798 unsigned sapi, unsigned nu,
799 const uint8_t *msg, size_t msg_size)
800{
801 /* GPRS Network Service, PDU type: NS_UNITDATA */
802 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
803 unsigned char llc_msg[4096] = {
804 0x00, 0x00, 0x01
805 };
806
807 size_t llc_msg_size = 3 + msg_size + 3;
808 uint8_t e_bit = 0;
809 uint8_t pm_bit = 1;
810 unsigned fcs;
811
812 nu &= 0x01ff;
813
814 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
815
816 llc_msg[0] = 0x40 | (sapi & 0x0f);
817 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
818 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
819
820 memcpy(llc_msg + 3, msg, msg_size);
821
822 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
823 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
824 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
825 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
826
827 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
828 src_addr, nsbvci, tlli,
829 with_racap_drx, imsi, imsi_size,
830 llc_msg, llc_msg_size);
831}
832
833
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200834static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
835 uint16_t nsvci, uint16_t nsei)
836{
837 printf("Setup NS-VC: remote 0x%08x:%d, "
838 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
839 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
840 nsvci, nsvci, nsei, nsei);
841
842 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
843 send_ns_alive(nsi, src_addr);
844 send_ns_unblock(nsi, src_addr);
845 send_ns_alive_ack(nsi, src_addr);
846}
847
848static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
849 uint16_t bvci)
850{
851 printf("Setup BSSGP: remote 0x%08x:%d, "
852 "BVCI 0x%04x(%d)\n\n",
853 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
854 bvci, bvci);
855
856 send_bssgp_reset(nsi, src_addr, bvci);
857}
858
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200859static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
860 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200861{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200862 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
863 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200864 send_ns_alive_ack(nsi, sgsn_peer);
865 send_ns_unblock_ack(nsi, sgsn_peer);
866 send_ns_alive(nsi, sgsn_peer);
867}
868
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200869static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
870{
871 sgsn_peer->sin_family = AF_INET;
872 sgsn_peer->sin_port = htons(32000);
873 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
874}
875
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200876static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
877{
878 sgsn_peer->sin_family = AF_INET;
879 sgsn_peer->sin_port = htons(32001);
880 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
881}
882
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200883static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
884{
885 size_t i;
886
887 for (i = 0; i < size; ++i) {
888 bss_peers[i].sin_family = AF_INET;
889 bss_peers[i].sin_port = htons((i + 1) * 1111);
890 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
891 }
892}
893
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200894int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
895 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
896
897/* override */
898int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
899 struct msgb *msg, uint16_t bvci)
900{
901 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
902 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200903 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200904
905 switch (event) {
906 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +0200907 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200908 default:
909 break;
910 }
911 return 0;
912}
913
914/* override */
915ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
916 const struct sockaddr *dest_addr, socklen_t addrlen)
917{
918 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
919 const struct sockaddr *, socklen_t);
920 static sendto_t real_sendto = NULL;
921 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200922 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200923
924 if (!real_sendto)
925 real_sendto = dlsym(RTLD_NEXT, "sendto");
926
927 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200928 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
929 dest_host, dest_port,
930 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200931 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200932 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
933 dest_host, dest_port,
934 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200935 else if (dest_host == REMOTE_SGSN2_ADDR)
936 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
937 dest_host, dest_port,
938 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200939 else
940 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
941
942 return len;
943}
944
945/* override */
946int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
947{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200948 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
949 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200950 uint16_t bvci = msgb_bvci(msg);
951 uint16_t nsei = msgb_nsei(msg);
952
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200953 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200954
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200955 if (!real_gprs_ns_sendmsg)
956 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
957
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200958 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200959 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
960 "msg length %d (%s)\n",
961 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200962 else if (nsei == SGSN2_NSEI)
963 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
964 "msg length %d (%s)\n",
965 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200966 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200967 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
968 "msg length %d (%s)\n",
969 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200970
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200971 if (received_messages) {
972 struct msgb *msg_copy;
973 msg_copy = gprs_msgb_copy(msg, "received_messages");
974 llist_add_tail(&msg_copy->list, received_messages);
975 }
976
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200977 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978}
979
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200980/* Get the next message from the receive FIFO
981 *
982 * \returns a pointer to the message which will be invalidated at the next call
983 * to expect_msg. Returns NULL, if there is no message left.
984 */
985static struct msgb *expect_msg(void)
986{
987 static struct msgb *msg = NULL;
988
989 msgb_free(msg);
990 msg = NULL;
991
992 if (!received_messages)
993 return NULL;
994
995 if (llist_empty(received_messages))
996 return NULL;
997
998 msg = llist_entry(received_messages->next, struct msgb, list);
999 llist_del(&msg->list);
1000
1001 return msg;
1002}
1003
1004struct expect_result {
1005 struct msgb *msg;
1006 struct gprs_gb_parse_context parse_ctx;
1007};
1008
1009static struct expect_result *expect_bssgp_msg(
1010 int match_nsei, int match_bvci, int match_pdu_type)
1011{
1012 static struct expect_result result;
1013 static const struct expect_result empty_result = {0,};
1014 static struct msgb *msg;
1015 uint16_t nsei;
1016 int rc;
1017
1018 memcpy(&result, &empty_result, sizeof(result));
1019
1020 msg = expect_msg();
1021 if (!msg)
1022 return NULL;
1023
1024 nsei = msgb_nsei(msg);
1025
1026 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1027 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1028 __func__, match_nsei, nsei);
1029 return NULL;
1030 }
1031
1032 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1033 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1034 __func__, match_bvci, msgb_bvci(msg));
1035 return NULL;
1036 }
1037
1038 result.msg = msg;
1039
1040 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1041 result.parse_ctx.peer_nsei = nsei;
1042
1043 if (!msgb_bssgph(msg)) {
1044 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1045 return NULL;
1046 }
1047
1048 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1049 &result.parse_ctx);
1050
1051 if (!rc) {
1052 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1053 return NULL;
1054 }
1055
1056 if (match_pdu_type != MATCH_ANY &&
1057 match_pdu_type != result.parse_ctx.pdu_type) {
1058 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1059 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1060 return NULL;
1061 }
1062
1063 return &result;
1064}
1065
1066static struct expect_result *expect_llc_msg(
1067 int match_nsei, int match_bvci, int match_sapi, int match_type)
1068{
1069 static struct expect_result *result;
1070
1071 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1072 if (!result)
1073 return NULL;
1074
1075 if (!result->parse_ctx.llc) {
1076 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1077 return NULL;
1078 }
1079
1080 if (match_sapi != MATCH_ANY &&
1081 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1082 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1083 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1084 return NULL;
1085 }
1086
1087 if (match_type != MATCH_ANY &&
1088 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1089 fprintf(stderr,
1090 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1091 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1092 return NULL;
1093 }
1094
1095 return result;
1096}
1097
1098static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1099 int match_type)
1100{
1101 static struct expect_result *result;
1102
1103 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1104 if (!result)
1105 return NULL;
1106
1107 if (!result->parse_ctx.g48_hdr) {
1108 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1109 return NULL;
1110 }
1111
1112 if (match_type != MATCH_ANY &&
1113 match_type != result->parse_ctx.g48_hdr->msg_type) {
1114 fprintf(stderr,
1115 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1116 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1117 return NULL;
1118 }
1119
1120 return result;
1121}
1122
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001123static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1124 struct rate_ctr_group *ctrg)
1125{
1126 unsigned int i;
1127
1128 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1129 struct rate_ctr *ctr = &ctrg->ctr[i];
1130 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1131 fprintf(stream, " %s%s: %llu%s",
1132 prefix, ctrg->desc->ctr_desc[i].description,
1133 (long long)ctr->current,
1134 "\n");
1135 };
1136}
1137
1138/* Signal handler for signals from NS layer */
1139static int test_signal(unsigned int subsys, unsigned int signal,
1140 void *handler_data, void *signal_data)
1141{
1142 struct ns_signal_data *nssd = signal_data;
1143 int rc;
1144
1145 if (subsys != SS_L_NS)
1146 return 0;
1147
1148 switch (signal) {
1149 case S_NS_RESET:
1150 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1151 nssd->nsvc->nsvci,
1152 gprs_ns_ll_str(nssd->nsvc));
1153 break;
1154
1155 case S_NS_ALIVE_EXP:
1156 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1157 nssd->nsvc->nsvci,
1158 gprs_ns_ll_str(nssd->nsvc));
1159 break;
1160
1161 case S_NS_BLOCK:
1162 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1163 nssd->nsvc->nsvci,
1164 gprs_ns_ll_str(nssd->nsvc));
1165 break;
1166
1167 case S_NS_UNBLOCK:
1168 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1169 nssd->nsvc->nsvci,
1170 gprs_ns_ll_str(nssd->nsvc));
1171 break;
1172
1173 case S_NS_REPLACED:
1174 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1175 nssd->nsvc->nsvci,
1176 gprs_ns_ll_str(nssd->nsvc));
1177 printf(" -> 0x%04x/%s\n",
1178 nssd->old_nsvc->nsvci,
1179 gprs_ns_ll_str(nssd->old_nsvc));
1180 break;
1181
1182 default:
1183 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1184 nssd->nsvc->nsvci,
1185 gprs_ns_ll_str(nssd->nsvc));
1186 break;
1187 }
1188 printf("\n");
1189 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1190 return rc;
1191}
1192
1193static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1194{
1195 struct msgb *msg;
1196 int ret;
1197 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1198 fprintf(stderr, "message too long: %d\n", data_len);
1199 return -1;
1200 }
1201
1202 msg = gprs_ns_msgb_alloc();
1203 memmove(msg->data, data, data_len);
1204 msg->l2h = msg->data;
1205 msgb_put(msg, data_len);
1206
1207 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1208 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1209 osmo_hexdump(data, data_len));
1210
1211 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1212
1213 printf("result (%s) = %d\n\n", text, ret);
1214
1215 msgb_free(msg);
1216
1217 return ret;
1218}
1219
1220static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1221{
1222 struct gprs_nsvc *nsvc;
1223
1224 printf("Current NS-VCIs:\n");
1225 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1226 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001227 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001228 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001229 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1230 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1231 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001232 );
1233 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1234 }
1235 printf("\n");
1236}
1237
1238static void test_gbproxy()
1239{
1240 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1241 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001242 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001243
1244 bssgp_nsi = nsi;
1245 gbcfg.nsi = bssgp_nsi;
1246 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1247
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001248 configure_sgsn_peer(&sgsn_peer);
1249 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001250
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001251 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001252 printf("--- Initialise SGSN ---\n\n");
1253
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001254 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001255 gprs_dump_nsi(nsi);
1256
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001257 printf("--- Initialise BSS 1 ---\n\n");
1258
1259 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1260 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1261 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001262 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001263
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001264 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1265
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001266 printf("--- Initialise BSS 2 ---\n\n");
1267
1268 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1269 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1270 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001271 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001272
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001273 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1274
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001275 printf("--- Move BSS 1 to new port ---\n\n");
1276
1277 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1278 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001279 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001280
1281 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1282
1283 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1284 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001285 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001286
1287 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1288
1289 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1290 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001291 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001292
1293 printf("--- Move BSS 2 to new port ---\n\n");
1294
1295 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1296 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001297 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001298
1299 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1300
1301 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1302 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001304
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001305 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1306
1307 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1308 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001309 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001310
1311 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1312
1313 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1314 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001315 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001316
1317 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1318
1319 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1320
1321 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1322 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001323 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001324
1325 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1326
1327 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1328
1329 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1330 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001331 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001332
1333 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1334
1335 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1336
1337 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1338
1339 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1340
1341 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1342
1343 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1344
1345 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1346
1347 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1348
1349 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1350
1351 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1352
1353 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1354
1355 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1356
1357 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1358
1359 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1360
1361 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1362 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001363 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001364
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001365 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001366
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001367 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1368
1369 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1370
1371 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1372
1373 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1374
1375 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1376
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001377 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1378
1379 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1380
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001381 /* Find peer */
1382 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1383 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1384 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1385 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1386 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1387 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1388
1389
1390 /* Cleanup */
1391 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1392 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1393 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1394 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1395 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1396
1397 dump_peers(stdout, 0, 0, &gbcfg);
1398
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001399 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001400
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001401 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001402 gprs_ns_destroy(nsi);
1403 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001404}
1405
1406static void test_gbproxy_ident_changes()
1407{
1408 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1409 struct sockaddr_in bss_peer[1] = {{0},};
1410 struct sockaddr_in sgsn_peer= {0};
1411 uint16_t nsei[2] = {0x1000, 0x2000};
1412 uint16_t nsvci[2] = {0x1001, 0x2001};
1413 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1414
1415 bssgp_nsi = nsi;
1416 gbcfg.nsi = bssgp_nsi;
1417 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1418
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001419 configure_sgsn_peer(&sgsn_peer);
1420 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001421
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001422 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001423 printf("--- Initialise SGSN ---\n\n");
1424
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001425 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001426 gprs_dump_nsi(nsi);
1427
1428 printf("--- Initialise BSS 1 ---\n\n");
1429
1430 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1431 gprs_dump_nsi(nsi);
1432
1433 printf("--- Setup BVCI 1 ---\n\n");
1434
1435 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1436 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001437 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001438
1439 printf("--- Setup BVCI 2 ---\n\n");
1440
1441 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1442 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001443 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001444
1445 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1446
1447 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1448 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1449
1450 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1451
1452 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1453 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1454
1455 printf("--- Change NSEI ---\n\n");
1456
1457 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1458 gprs_dump_nsi(nsi);
1459
1460 printf("--- Setup BVCI 1 ---\n\n");
1461
1462 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1463 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001464 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001465
1466 printf("--- Setup BVCI 3 ---\n\n");
1467
1468 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1469 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001470 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001471
1472 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1473
1474 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1475 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1476
1477 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1478 " (should fail) ---\n\n");
1479
1480 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001481 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001482 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001483 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001484
1485 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1486
1487 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1488 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1489
1490 printf("--- Change NSVCI ---\n\n");
1491
1492 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1493 gprs_dump_nsi(nsi);
1494
1495 printf("--- Setup BVCI 1 ---\n\n");
1496
1497 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1498 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001499 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001500
1501 printf("--- Setup BVCI 4 ---\n\n");
1502
1503 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1504 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001505 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001506
1507 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1508
1509 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1510 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1511
1512 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1513 " (should fail) ---\n\n");
1514
1515 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001516 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001517 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001518 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001519
1520 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1521
1522 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1523 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1524
1525 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1526
1527 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1528 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1529
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001530 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001531 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001532
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001533 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001534 gprs_ns_destroy(nsi);
1535 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001536}
1537
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001538static void test_gbproxy_ra_patching()
1539{
1540 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1541 struct sockaddr_in bss_peer[1] = {{0},};
1542 struct sockaddr_in sgsn_peer= {0};
1543 struct gprs_ra_id rai_bss =
1544 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1545 struct gprs_ra_id rai_sgsn =
1546 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1547 struct gprs_ra_id rai_unknown =
1548 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001549 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001550 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001551 const uint32_t ptmsi = 0xefe2b700;
1552 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001554 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001555 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001556 const char *patch_re = "^9898|^121314";
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001557 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001558 struct gbproxy_peer *peer;
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001559 LLIST_HEAD(rcv_list);
1560 struct expect_result *er;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001561
1562 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001563
1564 bssgp_nsi = nsi;
1565 gbcfg.nsi = bssgp_nsi;
1566 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001567 gbcfg.core_mcc = 123;
1568 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001569 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001570 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001571 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001572
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001573 configure_sgsn_peer(&sgsn_peer);
1574 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001575
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001576 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
1577 patch_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001578 fprintf(stderr, "Failed to compile RE '%s': %s\n",
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001579 patch_re, err_msg);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001580 exit(1);
1581 }
1582
1583
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001584 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001585 printf("--- Initialise SGSN ---\n\n");
1586
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001587 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001588 gprs_dump_nsi(nsi);
1589
1590 printf("--- Initialise BSS 1 ---\n\n");
1591
1592 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001593
1594 received_messages = &rcv_list;
1595
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001596 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1597 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001598 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001599
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001600 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001601 OSMO_ASSERT(peer != NULL);
1602
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001603 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1604
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001605 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1606
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001607 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1608
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001609 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001610
1611 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1612
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001613 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001614
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001615 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1616
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001617 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001618 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001619
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001620 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1621 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1622
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001623 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1624
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001625 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1626 foreign_tlli, &rai_bss, cell_id,
1627 GPRS_SAPI_GMM, 0,
1628 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001629
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001630 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001631 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001632
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001633 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1634 foreign_tlli, 0, NULL, 0,
1635 GPRS_SAPI_GMM, 0,
1636 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001637
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001638 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1639
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001640 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1641 foreign_tlli, &rai_bss, cell_id,
1642 GPRS_SAPI_GMM, 3,
1643 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001644
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001645 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1646
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001647 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1648 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1649
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001650 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1651 foreign_tlli, 1, imsi, sizeof(imsi),
1652 GPRS_SAPI_GMM, 1,
1653 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001654
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001655 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1656
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001657 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1658
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001659 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1660 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1661 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1662
1663 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1664 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1665 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1666
1667 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1668 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1669 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1670
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001671 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1672 OSMO_ASSERT(link_info);
1673 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1674 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1675 OSMO_ASSERT(!link_info->tlli.bss_validated);
1676 OSMO_ASSERT(!link_info->tlli.net_validated);
1677 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1678 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1679 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1680 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001681
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001682 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1683 local_tlli, &rai_bss, cell_id,
1684 GPRS_SAPI_GMM, 4,
1685 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001686
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001687 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1688
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001689 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1690
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001691 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1692 OSMO_ASSERT(link_info);
1693 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1694 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1695 OSMO_ASSERT(link_info->tlli.bss_validated);
1696 OSMO_ASSERT(!link_info->tlli.net_validated);
1697 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1698 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1699 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1700 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001701
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001702 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001703 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1704 local_tlli, &rai_bss, cell_id,
1705 GPRS_SAPI_GMM, 3,
1706 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001707
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001708 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1709
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001710 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1711
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001712 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1713 OSMO_ASSERT(link_info);
1714 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1715 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1716 OSMO_ASSERT(link_info->tlli.bss_validated);
1717 OSMO_ASSERT(!link_info->tlli.net_validated);
1718 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1719 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1720 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1721 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001722
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001723 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1724 local_tlli, 1, imsi, sizeof(imsi),
1725 GPRS_SAPI_GMM, 2,
1726 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001727
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001728 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1729
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001730 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1731
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001732 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1733 OSMO_ASSERT(link_info);
1734 OSMO_ASSERT(link_info->tlli.assigned == 0);
1735 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1736 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1737 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001738
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001739 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001740 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1741 local_tlli, &rai_bss, cell_id,
1742 GPRS_SAPI_GMM, 3,
1743 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001744
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001745 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1746 OSMO_ASSERT(er->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
1747
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001748 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1749
Jacob Erlbeck73685282014-05-23 20:48:07 +02001750 gbcfg.core_apn[0] = 0;
1751 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001752
1753 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001754 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1755 local_tlli, &rai_bss, cell_id,
1756 GPRS_SAPI_GMM, 3,
1757 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001758
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001759 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1760 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1761
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001762 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1763
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001764 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001765
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001766 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001767 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1768 local_tlli, &rai_bss, cell_id,
1769 GPRS_SAPI_GMM, 6,
1770 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001771
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001772 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1773
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001774 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1775 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1776
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001777 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1778 local_tlli, 1, imsi, sizeof(imsi),
1779 GPRS_SAPI_GMM, 5,
1780 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001781
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001782 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1783
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001784 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001785
1786 printf("--- RA update ---\n\n");
1787
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001788 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1789 foreign_tlli, &rai_bss, 0x7080,
1790 GPRS_SAPI_GMM, 5,
1791 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001792
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001793 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1794
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001795 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1796
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001797 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1798 foreign_tlli, 1, imsi, sizeof(imsi),
1799 GPRS_SAPI_GMM, 6,
1800 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001801
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001802 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1803
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001804 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1805
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001806 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001807 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1808 local_tlli, &rai_bss, cell_id,
1809 GPRS_SAPI_GMM, 3,
1810 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001811
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001812 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1813 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1814
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001815 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1816
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001817 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001818
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001819 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001820 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1821 local_tlli, &rai_bss, cell_id,
1822 GPRS_SAPI_GMM, 6,
1823 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001824
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001825 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1826
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001827 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1828
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001829 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001830 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001831
1832 printf("--- Bad cases ---\n\n");
1833
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001834 /* The RAI in the Attach Request message differs from the RAI in the
1835 * BSSGP message, only patch the latter */
1836
1837 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1838 foreign_tlli2, &rai_bss, cell_id,
1839 GPRS_SAPI_GMM, 0,
1840 dtap_attach_req2, sizeof(dtap_attach_req2));
1841
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001842 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1843
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001844 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1845
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001846 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001847 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1848 local_tlli, &rai_bss, cell_id,
1849 GPRS_SAPI_GMM, 3,
1850 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001851
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001852 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1853
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001854 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001855 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001856
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001857 /* TODO: The following breaks with the current libosmocore, enable it
1858 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1859 * is integrated */
1860 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1861 OSMO_ASSERT(expect_msg());
1862
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001863 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001864 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001865
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001866 OSMO_ASSERT(!expect_msg());
1867 received_messages = NULL;
1868
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02001869 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001870 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001871 gprs_ns_destroy(nsi);
1872 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001873}
1874
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001875static void test_gbproxy_ptmsi_assignment()
1876{
1877 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1878 struct sockaddr_in bss_peer[1] = {{0},};
1879 struct sockaddr_in sgsn_peer= {0};
1880 struct gprs_ra_id rai_bss =
1881 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1882 struct gprs_ra_id rai_unknown =
1883 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1884 uint16_t cell_id = 0x1234;
1885
1886 const uint32_t ptmsi = 0xefe2b700;
1887 const uint32_t local_tlli = 0xefe2b700;
1888
1889 const uint32_t foreign_tlli1 = 0x8000dead;
1890 const uint32_t foreign_tlli2 = 0x8000beef;
1891
1892 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1893 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1894
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001895 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001896 struct gbproxy_peer *peer;
1897 unsigned bss_nu = 0;
1898 unsigned sgsn_nu = 0;
1899
1900 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1901
1902 bssgp_nsi = nsi;
1903 gbcfg.nsi = bssgp_nsi;
1904 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1905 gbcfg.core_mcc = 0;
1906 gbcfg.core_mnc = 0;
1907 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1908 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1909 gbcfg.patch_ptmsi = 0;
1910 gbcfg.bss_ptmsi_state = 0;
1911 gbcfg.sgsn_tlli_state = 1;
1912
1913 configure_sgsn_peer(&sgsn_peer);
1914 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1915
1916 printf("=== %s ===\n", __func__);
1917 printf("--- Initialise SGSN ---\n\n");
1918
1919 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1920
1921 printf("--- Initialise BSS 1 ---\n\n");
1922
1923 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1924 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1925
1926 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1927 OSMO_ASSERT(peer != NULL);
1928
1929 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1930
1931 gprs_dump_nsi(nsi);
1932 dump_global(stdout, 0);
1933 dump_peers(stdout, 0, 0, &gbcfg);
1934
1935 printf("--- Establish first LLC connection ---\n\n");
1936
1937 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1938 foreign_tlli1, &rai_unknown, cell_id,
1939 GPRS_SAPI_GMM, bss_nu++,
1940 dtap_attach_req, sizeof(dtap_attach_req));
1941
1942 dump_peers(stdout, 0, 0, &gbcfg);
1943
1944 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1945 foreign_tlli1, 0, NULL, 0,
1946 GPRS_SAPI_GMM, sgsn_nu++,
1947 dtap_identity_req, sizeof(dtap_identity_req));
1948
1949 dump_peers(stdout, 0, 0, &gbcfg);
1950
1951 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1952 foreign_tlli1, &rai_bss, cell_id,
1953 GPRS_SAPI_GMM, bss_nu++,
1954 dtap_identity_resp, sizeof(dtap_identity_resp));
1955
1956 dump_peers(stdout, 0, 0, &gbcfg);
1957
1958 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1959 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1960 GPRS_SAPI_GMM, sgsn_nu++,
1961 dtap_attach_acc, sizeof(dtap_attach_acc));
1962
1963 dump_peers(stdout, 0, 0, &gbcfg);
1964
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001965 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1966 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1967 OSMO_ASSERT(link_info);
1968 OSMO_ASSERT(link_info == link_info2);
1969 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1970 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1971 OSMO_ASSERT(!link_info->tlli.bss_validated);
1972 OSMO_ASSERT(!link_info->tlli.net_validated);
1973 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001974
1975 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1976 local_tlli, &rai_bss, cell_id,
1977 GPRS_SAPI_GMM, bss_nu++,
1978 dtap_attach_complete, sizeof(dtap_attach_complete));
1979
1980 dump_peers(stdout, 0, 0, &gbcfg);
1981
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001982 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1983 OSMO_ASSERT(link_info);
1984 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1985 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1986 OSMO_ASSERT(link_info->tlli.bss_validated);
1987 OSMO_ASSERT(!link_info->tlli.net_validated);
1988 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001989
1990
1991 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1992 local_tlli, 1, imsi1, sizeof(imsi1),
1993 GPRS_SAPI_GMM, sgsn_nu++,
1994 dtap_gmm_information, sizeof(dtap_gmm_information));
1995
1996 dump_peers(stdout, 0, 0, &gbcfg);
1997
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001998 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1999 OSMO_ASSERT(link_info);
2000 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2001 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002002
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002003 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2004 OSMO_ASSERT(link_info == link_info2);
2005 OSMO_ASSERT(link_info->tlli.assigned == 0);
2006 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2007 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002008
2009 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2010
2011 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2012 foreign_tlli2, &rai_unknown, cell_id,
2013 GPRS_SAPI_GMM, bss_nu++,
2014 dtap_attach_req, sizeof(dtap_attach_req));
2015
2016 dump_peers(stdout, 0, 0, &gbcfg);
2017
2018 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2019 foreign_tlli2, 0, NULL, 0,
2020 GPRS_SAPI_GMM, sgsn_nu++,
2021 dtap_identity_req, sizeof(dtap_identity_req));
2022
2023 dump_peers(stdout, 0, 0, &gbcfg);
2024
2025 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2026 foreign_tlli2, &rai_bss, cell_id,
2027 GPRS_SAPI_GMM, bss_nu++,
2028 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2029
2030 dump_peers(stdout, 0, 0, &gbcfg);
2031
2032 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2033 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2034 GPRS_SAPI_GMM, sgsn_nu++,
2035 dtap_attach_acc, sizeof(dtap_attach_acc));
2036
2037 dump_peers(stdout, 0, 0, &gbcfg);
2038
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002039 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2040 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2041 OSMO_ASSERT(link_info);
2042 OSMO_ASSERT(link_info == link_info2);
2043 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2044 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2045 OSMO_ASSERT(!link_info->tlli.bss_validated);
2046 OSMO_ASSERT(!link_info->tlli.net_validated);
2047 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002048
2049 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2050 local_tlli, &rai_bss, cell_id,
2051 GPRS_SAPI_GMM, bss_nu++,
2052 dtap_attach_complete, sizeof(dtap_attach_complete));
2053
2054 dump_peers(stdout, 0, 0, &gbcfg);
2055
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002056 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2057 OSMO_ASSERT(link_info);
2058 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2059 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2060 OSMO_ASSERT(link_info->tlli.bss_validated);
2061 OSMO_ASSERT(!link_info->tlli.net_validated);
2062 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002063
2064 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2065 local_tlli, 1, imsi2, sizeof(imsi2),
2066 GPRS_SAPI_GMM, sgsn_nu++,
2067 dtap_gmm_information, sizeof(dtap_gmm_information));
2068
2069 dump_peers(stdout, 0, 0, &gbcfg);
2070
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002071 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2072 OSMO_ASSERT(link_info);
2073 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2074 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002075
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002076 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2077 OSMO_ASSERT(link_info == link_info2);
2078 OSMO_ASSERT(link_info->tlli.assigned == 0);
2079 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2080 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002081
2082 dump_global(stdout, 0);
2083
2084 gbprox_reset(&gbcfg);
2085 gprs_ns_destroy(nsi);
2086 nsi = NULL;
2087}
2088
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002089static void test_gbproxy_ptmsi_patching()
2090{
2091 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2092 struct sockaddr_in bss_peer[1] = {{0},};
2093 struct sockaddr_in sgsn_peer= {0};
2094 struct gprs_ra_id rai_bss =
2095 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2096 struct gprs_ra_id rai_sgsn =
2097 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002098 struct gprs_ra_id rai_wrong_mcc_sgsn =
2099 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002100 struct gprs_ra_id rai_unknown =
2101 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2102 uint16_t cell_id = 0x1234;
2103
2104 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002105 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2106 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002107 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002108 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2109 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002110 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002111 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002112
2113 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002114 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2115 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002116 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002117 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2118 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002119 const uint32_t foreign_bss_tlli = 0x8000dead;
2120
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002121
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002122 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002123 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002124 struct gbproxy_peer *peer;
2125 unsigned bss_nu = 0;
2126 unsigned sgsn_nu = 0;
2127
2128 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002129 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2130 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2131 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2132 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2133 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002134
2135 bssgp_nsi = nsi;
2136 gbcfg.nsi = bssgp_nsi;
2137 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2138 gbcfg.core_mcc = 123;
2139 gbcfg.core_mnc = 456;
2140 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2141 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2142 gbcfg.patch_ptmsi = 1;
2143 gbcfg.bss_ptmsi_state = 0;
2144 gbcfg.sgsn_tlli_state = 1;
2145
2146 configure_sgsn_peer(&sgsn_peer);
2147 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2148
2149 printf("=== %s ===\n", __func__);
2150 printf("--- Initialise SGSN ---\n\n");
2151
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002152 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002153
2154 printf("--- Initialise BSS 1 ---\n\n");
2155
2156 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2157 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2158
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002159 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002160 OSMO_ASSERT(peer != NULL);
2161
2162 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2163
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002164 gprs_dump_nsi(nsi);
2165 dump_global(stdout, 0);
2166 dump_peers(stdout, 0, 0, &gbcfg);
2167
2168 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2169
2170 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2171 foreign_bss_tlli, &rai_unknown, cell_id,
2172 GPRS_SAPI_GMM, bss_nu++,
2173 dtap_attach_req, sizeof(dtap_attach_req));
2174
2175 dump_peers(stdout, 0, 0, &gbcfg);
2176
2177 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2178 random_sgsn_tlli, 0, NULL, 0,
2179 GPRS_SAPI_GMM, sgsn_nu++,
2180 dtap_identity_req, sizeof(dtap_identity_req));
2181
2182 dump_peers(stdout, 0, 0, &gbcfg);
2183
2184 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2185 foreign_bss_tlli, &rai_bss, cell_id,
2186 GPRS_SAPI_GMM, bss_nu++,
2187 dtap_identity_resp, sizeof(dtap_identity_resp));
2188
2189 dump_peers(stdout, 0, 0, &gbcfg);
2190
2191 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2192 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2193 GPRS_SAPI_GMM, sgsn_nu++,
2194 dtap_attach_acc, sizeof(dtap_attach_acc));
2195
2196 dump_peers(stdout, 0, 0, &gbcfg);
2197
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002198 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2199 OSMO_ASSERT(link_info);
2200 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2201 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2202 OSMO_ASSERT(!link_info->tlli.bss_validated);
2203 OSMO_ASSERT(!link_info->tlli.net_validated);
2204 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2205 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2206 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2207 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2208 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2209 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002210
2211 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2212 local_bss_tlli, &rai_bss, cell_id,
2213 GPRS_SAPI_GMM, bss_nu++,
2214 dtap_attach_complete, sizeof(dtap_attach_complete));
2215
2216 dump_peers(stdout, 0, 0, &gbcfg);
2217
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002218 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2219 OSMO_ASSERT(link_info);
2220 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2221 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2222 OSMO_ASSERT(link_info->tlli.bss_validated);
2223 OSMO_ASSERT(!link_info->tlli.net_validated);
2224 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2225 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2226 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2227 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002228
2229 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2230 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2231 GPRS_SAPI_GMM, sgsn_nu++,
2232 dtap_gmm_information, sizeof(dtap_gmm_information));
2233
2234 dump_peers(stdout, 0, 0, &gbcfg);
2235
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002236 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2237 OSMO_ASSERT(link_info);
2238 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2239 OSMO_ASSERT(link_info->tlli.assigned == 0);
2240 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2241 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002242
Jacob Erlbeck82add782014-09-05 18:08:12 +02002243 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2244 local_bss_tlli, &rai_bss, cell_id,
2245 GPRS_SAPI_GMM, bss_nu++,
2246 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2247
2248 dump_peers(stdout, 0, 0, &gbcfg);
2249
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002250 /* Non-DTAP */
2251 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2252 local_bss_tlli, &rai_bss, cell_id,
2253 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2254
2255 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2256 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2257 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2258
2259 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2260 local_bss_tlli, &rai_bss, cell_id,
2261 llc_ui_ll11_dns_query_ul,
2262 sizeof(llc_ui_ll11_dns_query_ul));
2263
2264 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2265 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2266 llc_ui_ll11_dns_resp_dl,
2267 sizeof(llc_ui_ll11_dns_resp_dl));
2268
2269 dump_peers(stdout, 0, 0, &gbcfg);
2270
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002271 /* Repeated RA Update Requests */
2272 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2273 local_bss_tlli, &rai_bss, 0x7080,
2274 GPRS_SAPI_GMM, bss_nu++,
2275 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2276
2277 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2278 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2279 GPRS_SAPI_GMM, sgsn_nu++,
2280 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2281
2282 dump_peers(stdout, 0, 0, &gbcfg);
2283
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002284 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2285 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2286 OSMO_ASSERT(link_info);
2287 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2288 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2289 OSMO_ASSERT(!link_info->tlli.bss_validated);
2290 OSMO_ASSERT(!link_info->tlli.net_validated);
2291 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2292 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2293 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2294 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2295 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2296 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002297
2298 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2299 local_bss_tlli2, &rai_bss, 0x7080,
2300 GPRS_SAPI_GMM, bss_nu++,
2301 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2302
2303 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2304 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2305 GPRS_SAPI_GMM, sgsn_nu++,
2306 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2307
2308 dump_peers(stdout, 0, 0, &gbcfg);
2309
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002310 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2311 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2312 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_tlli3);
2315 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2316 OSMO_ASSERT(!link_info->tlli.bss_validated);
2317 OSMO_ASSERT(!link_info->tlli.net_validated);
2318 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2319 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2320 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2321 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2322 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2323 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002324
2325 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2326 local_bss_tlli3, &rai_bss, 0x7080,
2327 GPRS_SAPI_GMM, bss_nu++,
2328 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2329
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002330 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002331
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002332 OSMO_ASSERT(link_info);
2333 OSMO_ASSERT(link_info->tlli.bss_validated);
2334 OSMO_ASSERT(!link_info->tlli.net_validated);
2335 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2336 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002337
2338 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2339 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2340 GPRS_SAPI_GMM, sgsn_nu++,
2341 dtap_gmm_information, sizeof(dtap_gmm_information));
2342
2343 dump_peers(stdout, 0, 0, &gbcfg);
2344
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002345 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2346 OSMO_ASSERT(link_info);
2347 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2348 OSMO_ASSERT(link_info->tlli.assigned == 0);
2349 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2350 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002351
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002352 /* Other messages */
2353 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002354 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002355
2356 dump_peers(stdout, 0, 0, &gbcfg);
2357
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002358 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002359
2360 dump_peers(stdout, 0, 0, &gbcfg);
2361
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002362 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002363
2364 dump_peers(stdout, 0, 0, &gbcfg);
2365
2366 /* Bad case: Invalid BVCI */
2367 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002368 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002369 dump_global(stdout, 0);
2370
2371 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002372 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002373
2374 dump_global(stdout, 0);
2375
2376 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002377 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002378 &rai_wrong_mcc_sgsn);
2379
2380 dump_global(stdout, 0);
2381
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002382 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2383 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2384 unknown_sgsn_tlli, 1, NULL, 0,
2385 GPRS_SAPI_GMM, 2,
2386 dtap_gmm_information, sizeof(dtap_gmm_information));
2387
2388 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2389 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2390 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2391 GPRS_SAPI_GMM, 3,
2392 dtap_gmm_information, sizeof(dtap_gmm_information));
2393
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002394 /* Detach */
2395 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002396 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002397 GPRS_SAPI_GMM, bss_nu++,
2398 dtap_detach_req, sizeof(dtap_detach_req));
2399
2400 dump_peers(stdout, 0, 0, &gbcfg);
2401
2402 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002403 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002404 GPRS_SAPI_GMM, sgsn_nu++,
2405 dtap_detach_acc, sizeof(dtap_detach_acc));
2406
2407 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002408
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002409 dump_global(stdout, 0);
2410
2411 gbprox_reset(&gbcfg);
2412 gprs_ns_destroy(nsi);
2413 nsi = NULL;
2414}
2415
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002416static void test_gbproxy_imsi_acquisition()
2417{
2418 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2419 struct sockaddr_in bss_peer[1] = {{0},};
2420 struct sockaddr_in sgsn_peer= {0};
2421 struct gprs_ra_id rai_bss =
2422 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2423 struct gprs_ra_id rai_sgsn =
2424 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2425 struct gprs_ra_id rai_wrong_mcc_sgsn =
2426 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2427 struct gprs_ra_id rai_unknown =
2428 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2429 uint16_t cell_id = 0x1234;
2430
2431 const uint32_t sgsn_ptmsi = 0xefe2b700;
2432 const uint32_t local_sgsn_tlli = 0xefe2b700;
2433 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002434 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002435
2436 const uint32_t bss_ptmsi = 0xc00f7304;
2437 const uint32_t local_bss_tlli = 0xc00f7304;
2438 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002439 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002440
2441 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002442 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002443 struct gbproxy_peer *peer;
2444 unsigned bss_nu = 0;
2445 unsigned sgsn_nu = 0;
2446
2447 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2448
2449 bssgp_nsi = nsi;
2450 gbcfg.nsi = bssgp_nsi;
2451 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2452 gbcfg.core_mcc = 123;
2453 gbcfg.core_mnc = 456;
2454 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2455 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2456 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002457 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002458 gbcfg.bss_ptmsi_state = 0;
2459 gbcfg.sgsn_tlli_state = 1;
2460
2461 configure_sgsn_peer(&sgsn_peer);
2462 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2463
2464 printf("=== %s ===\n", __func__);
2465 printf("--- Initialise SGSN ---\n\n");
2466
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002467 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002468
2469 printf("--- Initialise BSS 1 ---\n\n");
2470
2471 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2472 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2473
2474 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2475 OSMO_ASSERT(peer != NULL);
2476
2477 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2478
2479 gprs_dump_nsi(nsi);
2480 dump_global(stdout, 0);
2481 dump_peers(stdout, 0, 0, &gbcfg);
2482
2483 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2484
2485 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002486 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002487 GPRS_SAPI_GMM, bss_nu++,
2488 dtap_attach_req, sizeof(dtap_attach_req));
2489
2490 dump_peers(stdout, 0, 0, &gbcfg);
2491
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002492 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2493 foreign_bss_tlli, &rai_bss, cell_id,
2494 GPRS_SAPI_GMM, bss_nu++,
2495 dtap_identity_resp, sizeof(dtap_identity_resp));
2496
2497 dump_peers(stdout, 0, 0, &gbcfg);
2498
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002499 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2500 random_sgsn_tlli, 0, NULL, 0,
2501 GPRS_SAPI_GMM, sgsn_nu++,
2502 dtap_identity_req, sizeof(dtap_identity_req));
2503
2504 dump_peers(stdout, 0, 0, &gbcfg);
2505
2506 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2507 foreign_bss_tlli, &rai_bss, cell_id,
2508 GPRS_SAPI_GMM, bss_nu++,
2509 dtap_identity_resp, sizeof(dtap_identity_resp));
2510
2511 dump_peers(stdout, 0, 0, &gbcfg);
2512
2513 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2514 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2515 GPRS_SAPI_GMM, sgsn_nu++,
2516 dtap_attach_acc, sizeof(dtap_attach_acc));
2517
2518 dump_peers(stdout, 0, 0, &gbcfg);
2519
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002520 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2521 OSMO_ASSERT(link_info);
2522 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2523 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2524 OSMO_ASSERT(!link_info->tlli.bss_validated);
2525 OSMO_ASSERT(!link_info->tlli.net_validated);
2526 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2527 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2528 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2529 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2530 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2531 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002532
2533 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2534 local_bss_tlli, &rai_bss, cell_id,
2535 GPRS_SAPI_GMM, bss_nu++,
2536 dtap_attach_complete, sizeof(dtap_attach_complete));
2537
2538 dump_peers(stdout, 0, 0, &gbcfg);
2539
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002540 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2541 OSMO_ASSERT(link_info);
2542 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2543 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2544 OSMO_ASSERT(link_info->tlli.bss_validated);
2545 OSMO_ASSERT(!link_info->tlli.net_validated);
2546 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2547 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2548 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2549 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002550
2551 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2552 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2553 GPRS_SAPI_GMM, sgsn_nu++,
2554 dtap_gmm_information, sizeof(dtap_gmm_information));
2555
2556 dump_peers(stdout, 0, 0, &gbcfg);
2557
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002558 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2559 OSMO_ASSERT(link_info);
2560 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2561 OSMO_ASSERT(link_info->tlli.assigned == 0);
2562 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2563 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002564
2565 /* Non-DTAP */
2566 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2567 local_bss_tlli, &rai_bss, cell_id,
2568 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2569
2570 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2571 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2572 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2573
2574 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2575 local_bss_tlli, &rai_bss, cell_id,
2576 llc_ui_ll11_dns_query_ul,
2577 sizeof(llc_ui_ll11_dns_query_ul));
2578
2579 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2580 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2581 llc_ui_ll11_dns_resp_dl,
2582 sizeof(llc_ui_ll11_dns_resp_dl));
2583
2584 dump_peers(stdout, 0, 0, &gbcfg);
2585
2586 /* Other messages */
2587 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2588 local_bss_tlli, 1, 12);
2589
2590 dump_peers(stdout, 0, 0, &gbcfg);
2591
2592 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2593 local_sgsn_tlli, 1, 12);
2594
2595 dump_peers(stdout, 0, 0, &gbcfg);
2596
2597 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2598
2599 dump_peers(stdout, 0, 0, &gbcfg);
2600
2601 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2602
2603 dump_peers(stdout, 0, 0, &gbcfg);
2604
2605 /* Bad case: Invalid BVCI */
2606 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2607 local_bss_tlli, 1, 12);
2608 dump_global(stdout, 0);
2609
2610 /* Bad case: Invalid RAI */
2611 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2612
2613 dump_global(stdout, 0);
2614
2615 /* Bad case: Invalid MCC (LAC ok) */
2616 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2617 &rai_wrong_mcc_sgsn);
2618
2619 dump_global(stdout, 0);
2620
2621 /* Detach */
2622 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2623 local_bss_tlli, &rai_bss, cell_id,
2624 GPRS_SAPI_GMM, bss_nu++,
2625 dtap_detach_req, sizeof(dtap_detach_req));
2626
2627 dump_peers(stdout, 0, 0, &gbcfg);
2628
2629 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2630 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2631 GPRS_SAPI_GMM, sgsn_nu++,
2632 dtap_detach_acc, sizeof(dtap_detach_acc));
2633
2634 dump_peers(stdout, 0, 0, &gbcfg);
2635
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002636 /* RA Update request */
2637
2638 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2639 foreign_bss_tlli, &rai_unknown, 0x7080,
2640 GPRS_SAPI_GMM, bss_nu++,
2641 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2642
2643 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2644 foreign_bss_tlli, &rai_bss, cell_id,
2645 GPRS_SAPI_GMM, bss_nu++,
2646 dtap_identity_resp, sizeof(dtap_identity_resp));
2647
2648 dump_peers(stdout, 0, 0, &gbcfg);
2649
2650 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2651 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2652 GPRS_SAPI_GMM, sgsn_nu++,
2653 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2654
2655 dump_peers(stdout, 0, 0, &gbcfg);
2656
2657 /* Detach */
2658
2659 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2660 local_bss_tlli, &rai_bss, cell_id,
2661 GPRS_SAPI_GMM, bss_nu++,
2662 dtap_detach_req, sizeof(dtap_detach_req));
2663
2664 dump_peers(stdout, 0, 0, &gbcfg);
2665
2666 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2667 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2668 GPRS_SAPI_GMM, sgsn_nu++,
2669 dtap_detach_acc, sizeof(dtap_detach_acc));
2670
2671 dump_peers(stdout, 0, 0, &gbcfg);
2672
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002673 /* Special case: Repeated Attach Requests */
2674
2675 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2676 foreign_bss_tlli, &rai_unknown, cell_id,
2677 GPRS_SAPI_GMM, bss_nu++,
2678 dtap_attach_req, sizeof(dtap_attach_req));
2679
2680 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2681 foreign_bss_tlli, &rai_unknown, cell_id,
2682 GPRS_SAPI_GMM, bss_nu++,
2683 dtap_attach_req, sizeof(dtap_attach_req));
2684
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002685 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2686 foreign_bss_tlli, &rai_bss, cell_id,
2687 GPRS_SAPI_GMM, bss_nu++,
2688 dtap_detach_req, sizeof(dtap_detach_req));
2689
2690 dump_peers(stdout, 0, 0, &gbcfg);
2691
2692 /* Special case: Detach from an unknown TLLI */
2693
2694 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2695 other_bss_tlli, &rai_bss, cell_id,
2696 GPRS_SAPI_GMM, bss_nu++,
2697 dtap_detach_req, sizeof(dtap_detach_req));
2698
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002699 dump_peers(stdout, 0, 0, &gbcfg);
2700
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002701 /* Special case: Repeated RA Update Requests */
2702
2703 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2704 foreign_bss_tlli, &rai_unknown, 0x7080,
2705 GPRS_SAPI_GMM, bss_nu++,
2706 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2707
2708 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2709 foreign_bss_tlli, &rai_unknown, 0x7080,
2710 GPRS_SAPI_GMM, bss_nu++,
2711 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2712
2713 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2714 foreign_bss_tlli, &rai_bss, cell_id,
2715 GPRS_SAPI_GMM, bss_nu++,
2716 dtap_detach_req, sizeof(dtap_detach_req));
2717
2718 dump_peers(stdout, 0, 0, &gbcfg);
2719
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002720 dump_global(stdout, 0);
2721
2722 gbprox_reset(&gbcfg);
2723 gprs_ns_destroy(nsi);
2724 nsi = NULL;
2725}
2726
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002727static void test_gbproxy_secondary_sgsn()
2728{
2729 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2730 struct sockaddr_in bss_peer[1] = {{0},};
2731 struct sockaddr_in sgsn_peer[2]= {{0},};
2732 struct gprs_ra_id rai_bss =
2733 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2734 struct gprs_ra_id rai_sgsn =
2735 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2736 struct gprs_ra_id rai_unknown =
2737 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2738 uint16_t cell_id = 0x1234;
2739
2740 const uint32_t sgsn_ptmsi = 0xefe2b700;
2741 const uint32_t local_sgsn_tlli = 0xefe2b700;
2742 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2743
2744 const uint32_t bss_ptmsi = 0xc00f7304;
2745 const uint32_t local_bss_tlli = 0xc00f7304;
2746 const uint32_t foreign_bss_tlli = 0x8000dead;
2747
2748 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2749 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2750 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2751 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2752 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2753 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2754
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002755 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002756 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002757 const uint32_t local_bss_tlli3 = 0xead4775a;
2758 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2759
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002760 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2761 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002762 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002763 struct gbproxy_link_info *link_info;
2764 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002765 struct gbproxy_peer *peer;
2766 unsigned bss_nu = 0;
2767 unsigned sgsn_nu = 0;
2768
2769 const char *err_msg = NULL;
2770 const char *filter_re = "999999";
2771
2772 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2773 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2774
2775 bssgp_nsi = nsi;
2776 gbcfg.nsi = bssgp_nsi;
2777 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2778 gbcfg.core_mcc = 123;
2779 gbcfg.core_mnc = 456;
2780 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2781 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2782 gbcfg.patch_ptmsi = 1;
2783 gbcfg.acquire_imsi = 1;
2784 gbcfg.bss_ptmsi_state = 0;
2785 gbcfg.sgsn_tlli_state = 1;
2786 gbcfg.route_to_sgsn2 = 1;
2787 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2788
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02002789 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02002790 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002791 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2792 err_msg);
2793 OSMO_ASSERT(err_msg == NULL);
2794 }
2795
2796 configure_sgsn_peer(&sgsn_peer[0]);
2797 configure_sgsn2_peer(&sgsn_peer[1]);
2798 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2799
2800 printf("=== %s ===\n", __func__);
2801 printf("--- Initialise SGSN 1 ---\n\n");
2802
2803 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2804
2805 printf("--- Initialise SGSN 2 ---\n\n");
2806
2807 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2808
2809 printf("--- Initialise BSS 1 ---\n\n");
2810
2811 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2812 setup_bssgp(nsi, &bss_peer[0], 0x0);
2813 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2814 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2815 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2816 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2817
2818 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2819 OSMO_ASSERT(peer != NULL);
2820
2821 gprs_dump_nsi(nsi);
2822 dump_global(stdout, 0);
2823 dump_peers(stdout, 0, 0, &gbcfg);
2824
2825 printf("--- Flow control ---\n\n");
2826
2827 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2828 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2829 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2830
2831 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2832
2833 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2834 foreign_bss_tlli, &rai_unknown, cell_id,
2835 GPRS_SAPI_GMM, bss_nu++,
2836 dtap_attach_req, sizeof(dtap_attach_req));
2837
2838 dump_peers(stdout, 0, 0, &gbcfg);
2839
2840 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2841 foreign_bss_tlli, &rai_bss, cell_id,
2842 GPRS_SAPI_GMM, bss_nu++,
2843 dtap_identity_resp, sizeof(dtap_identity_resp));
2844
2845 dump_peers(stdout, 0, 0, &gbcfg);
2846
2847 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2848 random_sgsn_tlli, 0, NULL, 0,
2849 GPRS_SAPI_GMM, sgsn_nu++,
2850 dtap_identity_req, sizeof(dtap_identity_req));
2851
2852 dump_peers(stdout, 0, 0, &gbcfg);
2853
2854 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2855 foreign_bss_tlli, &rai_bss, cell_id,
2856 GPRS_SAPI_GMM, bss_nu++,
2857 dtap_identity_resp, sizeof(dtap_identity_resp));
2858
2859 dump_peers(stdout, 0, 0, &gbcfg);
2860
2861 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2862 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2863 GPRS_SAPI_GMM, sgsn_nu++,
2864 dtap_attach_acc, sizeof(dtap_attach_acc));
2865
2866 dump_peers(stdout, 0, 0, &gbcfg);
2867
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002868 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2869 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2870 OSMO_ASSERT(link_info);
2871 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2872 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2873 OSMO_ASSERT(!link_info->tlli.bss_validated);
2874 OSMO_ASSERT(!link_info->tlli.net_validated);
2875 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2876 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2877 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2878 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2879 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2880 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002881
2882 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2883 local_bss_tlli, &rai_bss, cell_id,
2884 GPRS_SAPI_GMM, bss_nu++,
2885 dtap_attach_complete, sizeof(dtap_attach_complete));
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, local_sgsn_tlli, SGSN2_NSEI));
2890 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2891 OSMO_ASSERT(link_info);
2892 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2893 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2894 OSMO_ASSERT(link_info->tlli.bss_validated);
2895 OSMO_ASSERT(!link_info->tlli.net_validated);
2896 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2897 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2898 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2899 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002900
2901 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2902 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2903 GPRS_SAPI_GMM, sgsn_nu++,
2904 dtap_gmm_information, sizeof(dtap_gmm_information));
2905
2906 dump_peers(stdout, 0, 0, &gbcfg);
2907
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002908 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2909 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2910 OSMO_ASSERT(link_info);
2911 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2912 OSMO_ASSERT(link_info->tlli.assigned == 0);
2913 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2914 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002915
2916 /* Non-DTAP */
2917 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2918 local_bss_tlli, &rai_bss, cell_id,
2919 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2920
2921 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2922 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2923 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2924
2925 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2926 local_bss_tlli, &rai_bss, cell_id,
2927 llc_ui_ll11_dns_query_ul,
2928 sizeof(llc_ui_ll11_dns_query_ul));
2929
2930 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2931 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2932 llc_ui_ll11_dns_resp_dl,
2933 sizeof(llc_ui_ll11_dns_resp_dl));
2934
2935 dump_peers(stdout, 0, 0, &gbcfg);
2936
2937 /* Other messages */
2938 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2939 local_bss_tlli, 1, 12);
2940
2941 dump_peers(stdout, 0, 0, &gbcfg);
2942
2943 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2944 local_sgsn_tlli, 1, 12);
2945
2946 dump_peers(stdout, 0, 0, &gbcfg);
2947
2948 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2949
2950 dump_peers(stdout, 0, 0, &gbcfg);
2951
2952 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2953
2954 dump_peers(stdout, 0, 0, &gbcfg);
2955
2956 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2957
2958 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2959 foreign_bss_tlli2, &rai_unknown, cell_id,
2960 GPRS_SAPI_GMM, bss_nu++,
2961 dtap_attach_req, sizeof(dtap_attach_req));
2962
2963 dump_peers(stdout, 0, 0, &gbcfg);
2964
2965 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2966 foreign_bss_tlli2, &rai_bss, cell_id,
2967 GPRS_SAPI_GMM, bss_nu++,
2968 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2969
2970 dump_peers(stdout, 0, 0, &gbcfg);
2971
2972 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2973 random_sgsn_tlli2, 0, NULL, 0,
2974 GPRS_SAPI_GMM, sgsn_nu++,
2975 dtap_identity_req, sizeof(dtap_identity_req));
2976
2977 dump_peers(stdout, 0, 0, &gbcfg);
2978
2979 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2980 foreign_bss_tlli2, &rai_bss, cell_id,
2981 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002982 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002983
2984 dump_peers(stdout, 0, 0, &gbcfg);
2985
2986 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2987 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2988 GPRS_SAPI_GMM, sgsn_nu++,
2989 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2990
2991 dump_peers(stdout, 0, 0, &gbcfg);
2992
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002993 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2994 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2995 OSMO_ASSERT(link_info);
2996 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2997 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2998 OSMO_ASSERT(!link_info->tlli.bss_validated);
2999 OSMO_ASSERT(!link_info->tlli.net_validated);
3000 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3001 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3002 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3003 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3004 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3005 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003006
3007 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3008 local_bss_tlli2, &rai_bss, cell_id,
3009 GPRS_SAPI_GMM, bss_nu++,
3010 dtap_attach_complete, sizeof(dtap_attach_complete));
3011
3012 dump_peers(stdout, 0, 0, &gbcfg);
3013
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003014 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3015 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3016 OSMO_ASSERT(link_info);
3017 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3018 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3019 OSMO_ASSERT(link_info->tlli.bss_validated);
3020 OSMO_ASSERT(!link_info->tlli.net_validated);
3021 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3022 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3023 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3024 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003025
3026 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3027 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3028 GPRS_SAPI_GMM, sgsn_nu++,
3029 dtap_gmm_information, sizeof(dtap_gmm_information));
3030
3031 dump_peers(stdout, 0, 0, &gbcfg);
3032
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003033 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3034 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3035 OSMO_ASSERT(link_info);
3036 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3037 OSMO_ASSERT(link_info->tlli.assigned == 0);
3038 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3039 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003040
3041 /* Non-DTAP */
3042 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3043 local_bss_tlli2, &rai_bss, cell_id,
3044 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3045
3046 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3047 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3048 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3049
3050 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3051 local_bss_tlli2, &rai_bss, cell_id,
3052 llc_ui_ll11_dns_query_ul,
3053 sizeof(llc_ui_ll11_dns_query_ul));
3054
3055 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3056 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3057 llc_ui_ll11_dns_resp_dl,
3058 sizeof(llc_ui_ll11_dns_resp_dl));
3059
3060 dump_peers(stdout, 0, 0, &gbcfg);
3061
3062 /* Other messages */
3063 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3064 local_bss_tlli2, 1, 12);
3065
3066 dump_peers(stdout, 0, 0, &gbcfg);
3067
3068 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3069 local_sgsn_tlli2, 1, 12);
3070
3071 dump_peers(stdout, 0, 0, &gbcfg);
3072
3073 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3074
3075 dump_peers(stdout, 0, 0, &gbcfg);
3076
3077 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3078
3079 dump_peers(stdout, 0, 0, &gbcfg);
3080
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003081 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3082
3083 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3084 foreign_bss_tlli3, &rai_unknown, cell_id,
3085 GPRS_SAPI_GMM, bss_nu++,
3086 dtap_attach_req, sizeof(dtap_attach_req));
3087
3088 dump_peers(stdout, 0, 0, &gbcfg);
3089
3090 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3091 foreign_bss_tlli3, &rai_bss, cell_id,
3092 GPRS_SAPI_GMM, bss_nu++,
3093 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3094
3095 dump_peers(stdout, 0, 0, &gbcfg);
3096
3097 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3098 random_sgsn_tlli3, 0, NULL, 0,
3099 GPRS_SAPI_GMM, sgsn_nu++,
3100 dtap_identity_req, sizeof(dtap_identity_req));
3101
3102 dump_peers(stdout, 0, 0, &gbcfg);
3103
3104 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3105 foreign_bss_tlli3, &rai_bss, cell_id,
3106 GPRS_SAPI_GMM, bss_nu++,
3107 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3108
3109 dump_peers(stdout, 0, 0, &gbcfg);
3110
3111 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3112 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3113 GPRS_SAPI_GMM, sgsn_nu++,
3114 dtap_attach_acc, sizeof(dtap_attach_acc));
3115
3116 dump_peers(stdout, 0, 0, &gbcfg);
3117
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003118 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3119 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3120 OSMO_ASSERT(link_info);
3121 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3122 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3123 OSMO_ASSERT(!link_info->tlli.bss_validated);
3124 OSMO_ASSERT(!link_info->tlli.net_validated);
3125 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3126 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3127 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3128 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3129 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3130 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003131
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003132 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3133 local_bss_tlli3, &rai_bss, cell_id,
3134 GPRS_SAPI_GMM, bss_nu++,
3135 dtap_attach_complete, sizeof(dtap_attach_complete));
3136
3137 dump_peers(stdout, 0, 0, &gbcfg);
3138
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003139 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003140 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003141 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3142 OSMO_ASSERT(link_info);
3143 OSMO_ASSERT(link_info != other_info);
3144 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3145 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3146 OSMO_ASSERT(link_info->tlli.bss_validated);
3147 OSMO_ASSERT(!link_info->tlli.net_validated);
3148 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3149 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3150 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3151 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003152
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003153 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3154 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3155 GPRS_SAPI_GMM, sgsn_nu++,
3156 dtap_gmm_information, sizeof(dtap_gmm_information));
3157
3158 dump_peers(stdout, 0, 0, &gbcfg);
3159
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003160 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003161 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003162 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3163 OSMO_ASSERT(link_info);
3164 OSMO_ASSERT(link_info != other_info);
3165 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3166 OSMO_ASSERT(link_info->tlli.assigned == 0);
3167 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3168 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003169
3170
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003171 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3172
3173 /* Detach */
3174 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3175 local_bss_tlli, &rai_bss, cell_id,
3176 GPRS_SAPI_GMM, bss_nu++,
3177 dtap_detach_req, sizeof(dtap_detach_req));
3178
3179 dump_peers(stdout, 0, 0, &gbcfg);
3180
3181 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3182 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3183 GPRS_SAPI_GMM, sgsn_nu++,
3184 dtap_detach_acc, sizeof(dtap_detach_acc));
3185
3186 dump_peers(stdout, 0, 0, &gbcfg);
3187
3188 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3189
3190 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3191 local_bss_tlli2, &rai_bss, cell_id,
3192 GPRS_SAPI_GMM, bss_nu++,
3193 dtap_detach_req, sizeof(dtap_detach_req));
3194
3195 dump_peers(stdout, 0, 0, &gbcfg);
3196
3197 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3198 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3199 GPRS_SAPI_GMM, sgsn_nu++,
3200 dtap_detach_acc, sizeof(dtap_detach_acc));
3201
3202 dump_peers(stdout, 0, 0, &gbcfg);
3203
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003204 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3205
3206 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3207 local_bss_tlli3, &rai_bss, cell_id,
3208 GPRS_SAPI_GMM, bss_nu++,
3209 dtap_detach_req, sizeof(dtap_detach_req));
3210
3211 dump_peers(stdout, 0, 0, &gbcfg);
3212
3213 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3214 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3215 GPRS_SAPI_GMM, sgsn_nu++,
3216 dtap_detach_acc, sizeof(dtap_detach_acc));
3217
3218 dump_peers(stdout, 0, 0, &gbcfg);
3219
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003220 dump_global(stdout, 0);
3221
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003222 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003223 gbprox_reset(&gbcfg);
3224 gprs_ns_destroy(nsi);
3225 nsi = NULL;
3226}
3227
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003228static void test_gbproxy_keep_info()
3229{
3230 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3231 struct sockaddr_in bss_peer[1] = {{0},};
3232 struct sockaddr_in sgsn_peer= {0};
3233 struct gprs_ra_id rai_bss =
3234 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3235 uint16_t cell_id = 0x1234;
3236
3237 const uint32_t ptmsi = 0xefe2b700;
3238 const uint32_t local_tlli = 0xefe2b700;
3239 const uint32_t foreign_tlli = 0xafe2b700;
3240
3241 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003242 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003243 struct gbproxy_peer *peer;
3244 unsigned bss_nu = 0;
3245 unsigned sgsn_nu = 0;
3246
3247 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3248
3249 bssgp_nsi = nsi;
3250 gbcfg.nsi = bssgp_nsi;
3251 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3252 gbcfg.patch_ptmsi = 0;
3253 gbcfg.acquire_imsi = 1;
3254 gbcfg.bss_ptmsi_state = 0;
3255 gbcfg.sgsn_tlli_state = 1;
3256 gbcfg.core_mcc = 0;
3257 gbcfg.core_mnc = 0;
3258 gbcfg.core_apn = NULL;
3259 gbcfg.core_apn_size = 0;
3260 gbcfg.route_to_sgsn2 = 0;
3261 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003262 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003263
3264 configure_sgsn_peer(&sgsn_peer);
3265 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3266
3267 printf("=== %s ===\n", __func__);
3268 printf("--- Initialise SGSN ---\n\n");
3269
3270 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3271
3272 printf("--- Initialise BSS 1 ---\n\n");
3273
3274 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3275 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3276
3277 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3278 OSMO_ASSERT(peer != NULL);
3279
3280 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3281
3282 gprs_dump_nsi(nsi);
3283 dump_global(stdout, 0);
3284 dump_peers(stdout, 0, 0, &gbcfg);
3285
3286 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3287
3288 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3289 foreign_tlli, &rai_bss, cell_id,
3290 GPRS_SAPI_GMM, bss_nu++,
3291 dtap_attach_req, sizeof(dtap_attach_req));
3292
3293 dump_peers(stdout, 0, 0, &gbcfg);
3294
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003295 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3296 OSMO_ASSERT(link_info);
3297 OSMO_ASSERT(link_info->imsi_len == 0);
3298 OSMO_ASSERT(!link_info->is_deregistered);
3299 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003300
3301 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3302 foreign_tlli, &rai_bss, cell_id,
3303 GPRS_SAPI_GMM, bss_nu++,
3304 dtap_identity_resp, sizeof(dtap_identity_resp));
3305
3306 dump_peers(stdout, 0, 0, &gbcfg);
3307
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003308 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3309 OSMO_ASSERT(link_info);
3310 OSMO_ASSERT(link_info->imsi_len > 0);
3311 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003312
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003313 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3314 foreign_tlli, 0, NULL, 0,
3315 GPRS_SAPI_GMM, sgsn_nu++,
3316 dtap_identity_req, sizeof(dtap_identity_req));
3317
3318 dump_peers(stdout, 0, 0, &gbcfg);
3319
3320 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3321 foreign_tlli, &rai_bss, cell_id,
3322 GPRS_SAPI_GMM, bss_nu++,
3323 dtap_identity_resp, sizeof(dtap_identity_resp));
3324
3325 dump_peers(stdout, 0, 0, &gbcfg);
3326
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003327 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3328 OSMO_ASSERT(link_info);
3329 OSMO_ASSERT(link_info->imsi_len > 0);
3330 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003331
3332 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3333 foreign_tlli, 1, imsi, sizeof(imsi),
3334 GPRS_SAPI_GMM, sgsn_nu++,
3335 dtap_attach_acc, sizeof(dtap_attach_acc));
3336
3337 dump_peers(stdout, 0, 0, &gbcfg);
3338
3339 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3340 local_tlli, &rai_bss, cell_id,
3341 GPRS_SAPI_GMM, bss_nu++,
3342 dtap_attach_complete, sizeof(dtap_attach_complete));
3343
3344 dump_peers(stdout, 0, 0, &gbcfg);
3345
3346 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3347 local_tlli, 1, imsi, sizeof(imsi),
3348 GPRS_SAPI_GMM, sgsn_nu++,
3349 dtap_gmm_information, sizeof(dtap_gmm_information));
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 /* Detach (MO) */
3357 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3358 local_tlli, &rai_bss, cell_id,
3359 GPRS_SAPI_GMM, bss_nu++,
3360 dtap_detach_req, sizeof(dtap_detach_req));
3361
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003362 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3363 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003364
3365 dump_peers(stdout, 0, 0, &gbcfg);
3366
3367 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3368 local_tlli, 1, imsi, sizeof(imsi),
3369 GPRS_SAPI_GMM, sgsn_nu++,
3370 dtap_detach_acc, sizeof(dtap_detach_acc));
3371
3372 dump_peers(stdout, 0, 0, &gbcfg);
3373
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003374 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3375 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3376 OSMO_ASSERT(link_info);
3377 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003378
3379 /* Re-Attach */
3380 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3381 foreign_tlli, &rai_bss, cell_id,
3382 GPRS_SAPI_GMM, bss_nu++,
3383 dtap_attach_req3, sizeof(dtap_attach_req3));
3384
3385 dump_peers(stdout, 0, 0, &gbcfg);
3386
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003387 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3388 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3389 OSMO_ASSERT(link_info);
3390 OSMO_ASSERT(link_info == link_info2);
3391 OSMO_ASSERT(link_info->imsi_len != 0);
3392 OSMO_ASSERT(!link_info->is_deregistered);
3393 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003394
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003395 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3396 foreign_tlli, 1, imsi, sizeof(imsi),
3397 GPRS_SAPI_GMM, sgsn_nu++,
3398 dtap_attach_acc, sizeof(dtap_attach_acc));
3399
3400 dump_peers(stdout, 0, 0, &gbcfg);
3401
3402 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3403 local_tlli, &rai_bss, cell_id,
3404 GPRS_SAPI_GMM, bss_nu++,
3405 dtap_attach_complete, sizeof(dtap_attach_complete));
3406
3407 dump_peers(stdout, 0, 0, &gbcfg);
3408
3409 /* Detach (MT) */
3410 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3411 local_tlli, 1, imsi, sizeof(imsi),
3412 GPRS_SAPI_GMM, sgsn_nu++,
3413 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3414
3415 dump_peers(stdout, 0, 0, &gbcfg);
3416
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003417 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3418 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003419
3420 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3421 local_tlli, &rai_bss, cell_id,
3422 GPRS_SAPI_GMM, bss_nu++,
3423 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3424
3425 dump_peers(stdout, 0, 0, &gbcfg);
3426
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003427 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3428 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3429 OSMO_ASSERT(link_info);
3430 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003431
3432 /* Re-Attach */
3433 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3434 foreign_tlli, &rai_bss, cell_id,
3435 GPRS_SAPI_GMM, bss_nu++,
3436 dtap_attach_req3, sizeof(dtap_attach_req3));
3437
3438 dump_peers(stdout, 0, 0, &gbcfg);
3439
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003440 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3441 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3442 OSMO_ASSERT(link_info);
3443 OSMO_ASSERT(link_info == link_info2);
3444 OSMO_ASSERT(link_info->imsi_len != 0);
3445 OSMO_ASSERT(!link_info->is_deregistered);
3446 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003447
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003448 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3449 foreign_tlli, 1, imsi, sizeof(imsi),
3450 GPRS_SAPI_GMM, sgsn_nu++,
3451 dtap_attach_acc, sizeof(dtap_attach_acc));
3452
3453 dump_peers(stdout, 0, 0, &gbcfg);
3454
3455 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3456 local_tlli, &rai_bss, cell_id,
3457 GPRS_SAPI_GMM, bss_nu++,
3458 dtap_attach_complete, sizeof(dtap_attach_complete));
3459
3460 dump_peers(stdout, 0, 0, &gbcfg);
3461
3462 /* Detach (MT) */
3463 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3464 local_tlli, 1, imsi, sizeof(imsi),
3465 GPRS_SAPI_GMM, sgsn_nu++,
3466 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3467
3468 dump_peers(stdout, 0, 0, &gbcfg);
3469
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003470 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3471 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003472
3473 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3474 local_tlli, &rai_bss, cell_id,
3475 GPRS_SAPI_GMM, bss_nu++,
3476 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3477
3478 dump_peers(stdout, 0, 0, &gbcfg);
3479
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003480 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3481 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3482 OSMO_ASSERT(link_info);
3483 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003484
3485 /* Re-Attach */
3486 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3487 foreign_tlli, &rai_bss, cell_id,
3488 GPRS_SAPI_GMM, bss_nu++,
3489 dtap_attach_req3, sizeof(dtap_attach_req3));
3490
3491 dump_peers(stdout, 0, 0, &gbcfg);
3492
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003493 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3494 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3495 OSMO_ASSERT(link_info);
3496 OSMO_ASSERT(link_info == link_info2);
3497 OSMO_ASSERT(link_info->imsi_len != 0);
3498 OSMO_ASSERT(!link_info->is_deregistered);
3499 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003500
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003501 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3502 foreign_tlli, 1, imsi, sizeof(imsi),
3503 GPRS_SAPI_GMM, sgsn_nu++,
3504 dtap_attach_acc, sizeof(dtap_attach_acc));
3505
3506 dump_peers(stdout, 0, 0, &gbcfg);
3507
3508 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3509 local_tlli, &rai_bss, cell_id,
3510 GPRS_SAPI_GMM, bss_nu++,
3511 dtap_attach_complete, sizeof(dtap_attach_complete));
3512
3513 dump_peers(stdout, 0, 0, &gbcfg);
3514
3515 /* RA update procedure (reject -> Detach) */
3516 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3517 local_tlli, &rai_bss, 0x7080,
3518 GPRS_SAPI_GMM, bss_nu++,
3519 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3520
3521 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3522 local_tlli, 1, imsi, sizeof(imsi),
3523 GPRS_SAPI_GMM, sgsn_nu++,
3524 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3525
3526 dump_peers(stdout, 0, 0, &gbcfg);
3527
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003528 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3529 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3530 OSMO_ASSERT(link_info);
3531 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003532
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003533 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3534 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3535 foreign_tlli, &rai_bss, cell_id,
3536 GPRS_SAPI_GMM, bss_nu++,
3537 dtap_attach_req, sizeof(dtap_attach_req));
3538
3539 dump_peers(stdout, 0, 0, &gbcfg);
3540
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003541 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3542 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3543 OSMO_ASSERT(link_info);
3544 OSMO_ASSERT(link_info != link_info2);
3545 OSMO_ASSERT(link_info->imsi_len == 0);
3546 OSMO_ASSERT(!link_info->is_deregistered);
3547 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003548
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003549 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3550 foreign_tlli, &rai_bss, cell_id,
3551 GPRS_SAPI_GMM, bss_nu++,
3552 dtap_identity_resp, sizeof(dtap_identity_resp));
3553
3554 dump_peers(stdout, 0, 0, &gbcfg);
3555
3556 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3557 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3558 OSMO_ASSERT(link_info);
3559 OSMO_ASSERT(link_info == link_info2);
3560 OSMO_ASSERT(link_info->imsi_len != 0);
3561 OSMO_ASSERT(!link_info->is_deregistered);
3562 OSMO_ASSERT(!link_info->imsi_acq_pending);
3563
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003564 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3565 foreign_tlli, 1, imsi, sizeof(imsi),
3566 GPRS_SAPI_GMM, sgsn_nu++,
3567 dtap_attach_acc, sizeof(dtap_attach_acc));
3568
3569 dump_peers(stdout, 0, 0, &gbcfg);
3570
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003571 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3572 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3573 OSMO_ASSERT(link_info);
3574 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003575 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003576
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003577 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3578 local_tlli, &rai_bss, cell_id,
3579 GPRS_SAPI_GMM, bss_nu++,
3580 dtap_attach_complete, sizeof(dtap_attach_complete));
3581
3582 dump_peers(stdout, 0, 0, &gbcfg);
3583
3584 /* Detach (MT) */
3585 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3586 local_tlli, 1, imsi, sizeof(imsi),
3587 GPRS_SAPI_GMM, sgsn_nu++,
3588 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3589
3590 dump_peers(stdout, 0, 0, &gbcfg);
3591
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003592 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3593 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003594
3595 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3596 local_tlli, &rai_bss, cell_id,
3597 GPRS_SAPI_GMM, bss_nu++,
3598 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3599
3600 dump_peers(stdout, 0, 0, &gbcfg);
3601
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003602 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3603 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3604 OSMO_ASSERT(link_info);
3605 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003606
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003607 /* Attach rejected */
3608
3609 gbproxy_delete_link_infos(peer);
3610
3611 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3612 foreign_tlli, &rai_bss, cell_id,
3613 GPRS_SAPI_GMM, bss_nu++,
3614 dtap_attach_req, sizeof(dtap_attach_req));
3615
3616 dump_peers(stdout, 0, 0, &gbcfg);
3617
3618 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3619 OSMO_ASSERT(link_info);
3620 OSMO_ASSERT(link_info->imsi_len == 0);
3621 OSMO_ASSERT(!link_info->is_deregistered);
3622 OSMO_ASSERT(link_info->imsi_acq_pending);
3623
3624 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3625 foreign_tlli, &rai_bss, cell_id,
3626 GPRS_SAPI_GMM, bss_nu++,
3627 dtap_identity_resp, sizeof(dtap_identity_resp));
3628
3629 dump_peers(stdout, 0, 0, &gbcfg);
3630
3631 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3632 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3633 OSMO_ASSERT(link_info);
3634 OSMO_ASSERT(link_info == link_info2);
3635 OSMO_ASSERT(link_info->imsi_len != 0);
3636 OSMO_ASSERT(!link_info->is_deregistered);
3637 OSMO_ASSERT(!link_info->imsi_acq_pending);
3638
3639 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3640 foreign_tlli, 1, imsi, sizeof(imsi),
3641 GPRS_SAPI_GMM, sgsn_nu++,
3642 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3643
3644 dump_peers(stdout, 0, 0, &gbcfg);
3645
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003646 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3647
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003648 /* Attach (incomplete) and Detach (MO) */
3649
3650 gbproxy_delete_link_infos(peer);
3651
3652 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3653 foreign_tlli, &rai_bss, cell_id,
3654 GPRS_SAPI_GMM, bss_nu++,
3655 dtap_attach_req, sizeof(dtap_attach_req));
3656
3657 dump_peers(stdout, 0, 0, &gbcfg);
3658
3659 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3660 OSMO_ASSERT(link_info);
3661 OSMO_ASSERT(link_info->imsi_len == 0);
3662 OSMO_ASSERT(!link_info->is_deregistered);
3663 OSMO_ASSERT(link_info->imsi_acq_pending);
3664
3665 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3666 foreign_tlli, &rai_bss, cell_id,
3667 GPRS_SAPI_GMM, bss_nu++,
3668 dtap_detach_req, sizeof(dtap_detach_req));
3669
3670 dump_peers(stdout, 0, 0, &gbcfg);
3671
3672 /* Attach (incomplete) and Detach (MT) */
3673
3674 gbproxy_delete_link_infos(peer);
3675
3676 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3677 foreign_tlli, &rai_bss, cell_id,
3678 GPRS_SAPI_GMM, bss_nu++,
3679 dtap_attach_req, sizeof(dtap_attach_req));
3680
3681 dump_peers(stdout, 0, 0, &gbcfg);
3682
3683 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3684 OSMO_ASSERT(link_info);
3685 OSMO_ASSERT(link_info->imsi_len == 0);
3686 OSMO_ASSERT(!link_info->is_deregistered);
3687 OSMO_ASSERT(link_info->imsi_acq_pending);
3688
3689 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3690 foreign_tlli, 1, imsi, sizeof(imsi),
3691 GPRS_SAPI_GMM, sgsn_nu++,
3692 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3693
3694 dump_peers(stdout, 0, 0, &gbcfg);
3695
3696 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3697 OSMO_ASSERT(link_info);
3698
3699 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3700 foreign_tlli, &rai_bss, cell_id,
3701 GPRS_SAPI_GMM, bss_nu++,
3702 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3703
3704 dump_peers(stdout, 0, 0, &gbcfg);
3705
3706 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3707 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3708 OSMO_ASSERT(link_info);
3709 OSMO_ASSERT(link_info->is_deregistered);
3710
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003711 dump_global(stdout, 0);
3712
3713 gbprox_reset(&gbcfg);
3714 gprs_ns_destroy(nsi);
3715 nsi = NULL;
3716}
3717
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003718/* TODO: Move tlv testing to libosmocore */
3719int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3720int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3721 uint8_t **value);
3722int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3723 size_t *value_len);
3724int lv_shift(uint8_t **data, size_t *data_len,
3725 uint8_t **value, size_t *value_len);
3726
3727static void check_tlv_match(uint8_t **data, size_t *data_len,
3728 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3729{
3730 uint8_t *value;
3731 size_t value_len;
3732 int rc;
3733
3734 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3735 OSMO_ASSERT(rc == 0);
3736
3737 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003738 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003739 OSMO_ASSERT(value_len == exp_len);
3740 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3741}
3742
3743static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3744 uint8_t tag, size_t len, const uint8_t *exp_val)
3745{
3746 uint8_t *value;
3747 int rc;
3748
3749 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3750 OSMO_ASSERT(rc == 0);
3751
3752 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003753 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003754 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3755}
3756
3757static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3758 size_t len, const uint8_t *exp_val)
3759{
3760 uint8_t *value;
3761 int rc;
3762
3763 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003764 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003765 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3766}
3767
3768static void check_lv_shift(uint8_t **data, size_t *data_len,
3769 size_t exp_len, const uint8_t *exp_val)
3770{
3771 uint8_t *value;
3772 size_t value_len;
3773 int rc;
3774
3775 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003776 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003777 OSMO_ASSERT(value_len == exp_len);
3778 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3779}
3780
3781static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3782 const uint8_t *test_data)
3783{
3784 uint8_t buf[300] = {0};
3785
3786 uint8_t *unchanged_ptr = buf - 1;
3787 size_t unchanged_len = 0xdead;
3788 size_t tmp_data_len = data_len;
3789 uint8_t *value = unchanged_ptr;
3790 size_t value_len = unchanged_len;
3791 uint8_t *data = buf;
3792
3793 OSMO_ASSERT(data_len <= sizeof(buf));
3794
3795 tlv_put(data, tag, len, test_data);
3796 if (data_len < len + 2) {
3797 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3798 tag, &value, &value_len));
3799 OSMO_ASSERT(tmp_data_len == 0);
3800 OSMO_ASSERT(data == buf + data_len);
3801 OSMO_ASSERT(value == unchanged_ptr);
3802 OSMO_ASSERT(value_len == unchanged_len);
3803 } else {
3804 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3805 tag, &value, &value_len));
3806 OSMO_ASSERT(value != unchanged_ptr);
3807 OSMO_ASSERT(value_len != unchanged_len);
3808 }
3809}
3810
3811static void check_tv_fixed_match_data_len(size_t data_len,
3812 uint8_t tag, size_t len,
3813 const uint8_t *test_data)
3814{
3815 uint8_t buf[300] = {0};
3816
3817 uint8_t *unchanged_ptr = buf - 1;
3818 size_t tmp_data_len = data_len;
3819 uint8_t *value = unchanged_ptr;
3820 uint8_t *data = buf;
3821
3822 OSMO_ASSERT(data_len <= sizeof(buf));
3823
3824 tv_fixed_put(data, tag, len, test_data);
3825
3826 if (data_len < len + 1) {
3827 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3828 tag, len, &value));
3829 OSMO_ASSERT(tmp_data_len == 0);
3830 OSMO_ASSERT(data == buf + data_len);
3831 OSMO_ASSERT(value == unchanged_ptr);
3832 } else {
3833 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3834 tag, len, &value));
3835 OSMO_ASSERT(value != unchanged_ptr);
3836 }
3837}
3838
3839static void check_v_fixed_shift_data_len(size_t data_len,
3840 size_t len, const uint8_t *test_data)
3841{
3842 uint8_t buf[300] = {0};
3843
3844 uint8_t *unchanged_ptr = buf - 1;
3845 size_t tmp_data_len = data_len;
3846 uint8_t *value = unchanged_ptr;
3847 uint8_t *data = buf;
3848
3849 OSMO_ASSERT(data_len <= sizeof(buf));
3850
3851 memcpy(data, test_data, len);
3852
3853 if (data_len < len) {
3854 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3855 len, &value));
3856 OSMO_ASSERT(tmp_data_len == 0);
3857 OSMO_ASSERT(data == buf + data_len);
3858 OSMO_ASSERT(value == unchanged_ptr);
3859 } else {
3860 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3861 len, &value));
3862 OSMO_ASSERT(value != unchanged_ptr);
3863 }
3864}
3865
3866static void check_lv_shift_data_len(size_t data_len,
3867 size_t len, const uint8_t *test_data)
3868{
3869 uint8_t buf[300] = {0};
3870
3871 uint8_t *unchanged_ptr = buf - 1;
3872 size_t unchanged_len = 0xdead;
3873 size_t tmp_data_len = data_len;
3874 uint8_t *value = unchanged_ptr;
3875 size_t value_len = unchanged_len;
3876 uint8_t *data = buf;
3877
3878 lv_put(data, len, test_data);
3879 if (data_len < len + 1) {
3880 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3881 &value, &value_len));
3882 OSMO_ASSERT(tmp_data_len == 0);
3883 OSMO_ASSERT(data == buf + data_len);
3884 OSMO_ASSERT(value == unchanged_ptr);
3885 OSMO_ASSERT(value_len == unchanged_len);
3886 } else {
3887 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3888 &value, &value_len));
3889 OSMO_ASSERT(value != unchanged_ptr);
3890 OSMO_ASSERT(value_len != unchanged_len);
3891 }
3892}
3893
3894static void test_tlv_shift_functions()
3895{
3896 uint8_t test_data[1024];
3897 uint8_t buf[1024];
3898 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003899 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003900 uint8_t *data;
3901 size_t data_len;
3902 const uint8_t tag = 0x1a;
3903
3904 printf("Test shift functions\n");
3905
3906 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3907 test_data[i] = (uint8_t)i;
3908
3909 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003910 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003911
3912 memset(buf, 0xee, sizeof(buf));
3913 data_end = data = buf;
3914
3915 for (i = 0; i < iterations; i++) {
3916 data_end = tlv_put(data_end, tag, len, test_data);
3917 data_end = tv_fixed_put(data_end, tag, len, test_data);
3918 /* v_fixed_put */
3919 memcpy(data_end, test_data, len);
3920 data_end += len;
3921 data_end = lv_put(data_end, len, test_data);
3922 }
3923
3924 data_len = data_end - data;
3925 OSMO_ASSERT(data_len <= sizeof(buf));
3926
3927 for (i = 0; i < iterations; i++) {
3928 check_tlv_match(&data, &data_len, tag, len, test_data);
3929 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3930 check_v_fixed_shift(&data, &data_len, len, test_data);
3931 check_lv_shift(&data, &data_len, len, test_data);
3932 }
3933
3934 OSMO_ASSERT(data == data_end);
3935
3936 /* Test at end of data */
3937
3938 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3939 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3940 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3941 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3942
3943 /* Test invalid data_len */
3944 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3945 check_tlv_match_data_len(data_len, tag, len, test_data);
3946 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3947 check_v_fixed_shift_data_len(data_len, len, test_data);
3948 check_lv_shift_data_len(data_len, len, test_data);
3949 }
3950 }
3951}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003952
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003953struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003954 struct gbproxy_peer *peer, uint32_t tlli,
3955 const uint8_t *imsi, size_t imsi_len, time_t now)
3956{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003957 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003958 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003959 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003960 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003961
3962 /* Check, whether the IMSI matches */
3963 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003964 imsi_matches = gbproxy_check_imsi(
3965 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003966 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003967 return NULL;
3968 }
3969
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003970 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003971
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003972 if (!link_info) {
3973 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003974
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003975 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003976 /* TLLI has changed somehow, adjust it */
3977 LOGP(DGPRS, LOGL_INFO,
3978 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003979 link_info->tlli.current, tlli);
3980 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003981 }
3982 }
3983
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003984 if (!link_info) {
3985 link_info = gbproxy_link_info_alloc(peer);
3986 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003987 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003988 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003989 tlli_already_known = 1;
3990 }
3991
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003992 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003993
3994 if (!tlli_already_known)
3995 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3996
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003997 gbproxy_attach_link_info(peer, now, link_info);
3998 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003999
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004000 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004001 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004002
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004003 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004004}
4005
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004006static void test_gbproxy_tlli_expire(void)
4007{
4008 struct gbproxy_config cfg = {0};
4009 struct gbproxy_peer *peer;
4010 const char *err_msg = NULL;
4011 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4012 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004013 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004014 const uint32_t tlli1 = 1234 | 0xc0000000;
4015 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004016 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004017 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004018 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004019
4020 printf("Test TLLI info expiry\n\n");
4021
4022 gbproxy_init_config(&cfg);
4023
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004024 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4025 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004026 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4027 err_msg);
4028 OSMO_ASSERT(err_msg == NULL);
4029 }
4030
4031 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004032 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004033
4034 printf("Test TLLI replacement:\n");
4035
4036 cfg.tlli_max_len = 0;
4037 cfg.tlli_max_age = 0;
4038 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004039 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004040
4041 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004042 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004043 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004044 OSMO_ASSERT(link_info);
4045 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004046 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004047
4048 /* replace the old entry */
4049 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004050 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004051 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004052 OSMO_ASSERT(link_info);
4053 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004054 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004055
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004056 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004057
4058 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004059 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4060 OSMO_ASSERT(link_info);
4061 OSMO_ASSERT(link_info->tlli.current == tlli2);
4062 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4063 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004064
4065 printf("\n");
4066
4067 gbproxy_peer_free(peer);
4068 }
4069
4070 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004071 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004072
4073 printf("Test IMSI replacement:\n");
4074
4075 cfg.tlli_max_len = 0;
4076 cfg.tlli_max_age = 0;
4077 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004078 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004079
4080 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004081 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004082 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004083 OSMO_ASSERT(link_info);
4084 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004085 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004086
4087 /* try to replace the old entry */
4088 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004089 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004090 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004091 OSMO_ASSERT(link_info);
4092 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004093 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004094
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004095 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004096
4097 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004098 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4099 OSMO_ASSERT(!link_info);
4100 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4101 OSMO_ASSERT(link_info);
4102 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004103
4104 printf("\n");
4105
4106 gbproxy_peer_free(peer);
4107 }
4108
4109 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004110 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004111 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004112
4113 printf("Test TLLI expiry, max_len == 1:\n");
4114
4115 cfg.tlli_max_len = 1;
4116 cfg.tlli_max_age = 0;
4117 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004118 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004119
4120 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004121 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004122 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004123
4124 /* replace the old entry */
4125 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004126 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004127 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004128
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004129 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004130 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004131 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004132
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004133 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004134
4135 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004136 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4137 OSMO_ASSERT(!link_info);
4138 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4139 OSMO_ASSERT(link_info);
4140 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004141
4142 printf("\n");
4143
4144 gbproxy_peer_free(peer);
4145 }
4146
4147 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004148 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004149 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004150
4151 printf("Test TLLI expiry, max_age == 1:\n");
4152
4153 cfg.tlli_max_len = 0;
4154 cfg.tlli_max_age = 1;
4155 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004156 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004157
4158 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004159 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004160 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004161
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004162 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004163 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004164 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004165 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004166
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004167 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004168 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004169 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004170
4171 dump_peers(stdout, 2, now + 2, &cfg);
4172
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004173 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004174 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4175 OSMO_ASSERT(!link_info);
4176 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4177 OSMO_ASSERT(link_info);
4178 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004179
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004180 printf("\n");
4181
4182 gbproxy_peer_free(peer);
4183 }
4184
4185 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004186 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004187 int num_removed;
4188
4189 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4190
4191 cfg.tlli_max_len = 0;
4192 cfg.tlli_max_age = 1;
4193 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004194 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004195
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004196 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004197 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004198 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004199
4200 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004201 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004202 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004203 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004204
4205 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004206 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004207 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004208 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004209
4210 dump_peers(stdout, 2, now + 2, &cfg);
4211
4212 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004213 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004214 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004215 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004216
4217 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004218
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004219 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004220 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4221 OSMO_ASSERT(!link_info);
4222 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4223 OSMO_ASSERT(!link_info);
4224 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4225 OSMO_ASSERT(link_info);
4226 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004227
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004228 printf("\n");
4229
4230 gbproxy_peer_free(peer);
4231 }
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004232 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4233 gbprox_reset(&cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004234}
4235
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004236static void test_gbproxy_imsi_matching(void)
4237{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004238 const char *err_msg = NULL;
4239 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4240 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4241 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4242 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4243 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4244 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4245 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4246 const char *filter_re1 = ".*";
4247 const char *filter_re2 = "^1234";
4248 const char *filter_re3 = "^4321";
4249 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004250 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004251
4252 printf("=== Test IMSI/TMSI matching ===\n\n");
4253
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004254 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004255
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004256 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4257 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004258
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004259 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4260 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004261
4262 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004263 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004264 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004265 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004266
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004267 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4268 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004269
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004270 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4271 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004272
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004273 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4274 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004275
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004276 gbproxy_clear_patch_filter(&match);
4277 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004278
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004279 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4280 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004281
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004282 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4283 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004284 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004285 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004286 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004287 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4288 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4289 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4290 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4291 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004292
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004293 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4294 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004295
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004296 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4297 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4298 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4299 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4300 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4301 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4302 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004303
4304 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004305
4306 gbproxy_clear_patch_filter(&match);
4307 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004308}
4309
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004310static struct log_info_cat gprs_categories[] = {
4311 [DGPRS] = {
4312 .name = "DGPRS",
4313 .description = "GPRS Packet Service",
4314 .enabled = 1, .loglevel = LOGL_DEBUG,
4315 },
4316 [DNS] = {
4317 .name = "DNS",
4318 .description = "GPRS Network Service (NS)",
4319 .enabled = 1, .loglevel = LOGL_INFO,
4320 },
4321 [DBSSGP] = {
4322 .name = "DBSSGP",
4323 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4324 .enabled = 1, .loglevel = LOGL_DEBUG,
4325 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004326};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004327
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004328static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004329 .cat = gprs_categories,
4330 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004331};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004332
4333int main(int argc, char **argv)
4334{
4335 osmo_init_logging(&info);
4336 log_set_use_color(osmo_stderr_target, 0);
4337 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02004338 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004339
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004340 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004341 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4342 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004343
4344 rate_ctr_init(NULL);
4345
4346 setlinebuf(stdout);
4347
4348 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004349 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004350 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004351 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004352 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004353 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004354 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004355 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004356 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004357 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004358 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004359 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004360 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004361 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004362
4363 exit(EXIT_SUCCESS);
4364}