blob: 16dbf5b460101c7c8587b243e94c1a903c58491d [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 Freythereece6272014-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 Freythereece6272014-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 Freythereece6272014-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);
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001560 struct expect_result *expect_res;
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 Erlbeckc79beec2014-10-10 09:48:12 +02001745 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1746 OSMO_ASSERT(expect_res != NULL);
1747 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001748
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001749 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1750
Jacob Erlbeck73685282014-05-23 20:48:07 +02001751 gbcfg.core_apn[0] = 0;
1752 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001753
1754 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001755 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1756 local_tlli, &rai_bss, cell_id,
1757 GPRS_SAPI_GMM, 3,
1758 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001759
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001760 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1761 OSMO_ASSERT(expect_res != NULL);
1762 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001763
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001764 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1765
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001766 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001767
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001768 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001769 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1770 local_tlli, &rai_bss, cell_id,
1771 GPRS_SAPI_GMM, 6,
1772 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001773
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001774 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1775
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001776 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1777 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1778
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001779 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1780 local_tlli, 1, imsi, sizeof(imsi),
1781 GPRS_SAPI_GMM, 5,
1782 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001783
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001784 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1785
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001786 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001787
1788 printf("--- RA update ---\n\n");
1789
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001790 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1791 foreign_tlli, &rai_bss, 0x7080,
1792 GPRS_SAPI_GMM, 5,
1793 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001794
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001795 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1796
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001797 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1798
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001799 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1800 foreign_tlli, 1, imsi, sizeof(imsi),
1801 GPRS_SAPI_GMM, 6,
1802 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001803
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001804 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1805
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001806 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1807
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001808 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001809 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1810 local_tlli, &rai_bss, cell_id,
1811 GPRS_SAPI_GMM, 3,
1812 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001813
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001814 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1815 OSMO_ASSERT(expect_res != NULL);
1816 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001817
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001818 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1819
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001820 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001821
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001822 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001823 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1824 local_tlli, &rai_bss, cell_id,
1825 GPRS_SAPI_GMM, 6,
1826 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001827
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001828 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1829
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001830 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1831
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001832 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001833 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001834
1835 printf("--- Bad cases ---\n\n");
1836
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001837 /* The RAI in the Attach Request message differs from the RAI in the
1838 * BSSGP message, only patch the latter */
1839
1840 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1841 foreign_tlli2, &rai_bss, cell_id,
1842 GPRS_SAPI_GMM, 0,
1843 dtap_attach_req2, sizeof(dtap_attach_req2));
1844
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001845 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1846
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001847 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1848
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001849 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001850 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1851 local_tlli, &rai_bss, cell_id,
1852 GPRS_SAPI_GMM, 3,
1853 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001854
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001855 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1856
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001857 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001858 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001859
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001860 /* TODO: The following breaks with the current libosmocore, enable it
1861 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1862 * is integrated */
1863 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1864 OSMO_ASSERT(expect_msg());
1865
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001866 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001867 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001868
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001869 OSMO_ASSERT(!expect_msg());
1870 received_messages = NULL;
1871
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02001872 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001873 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001874 gprs_ns_destroy(nsi);
1875 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001876}
1877
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001878static void test_gbproxy_ptmsi_assignment()
1879{
1880 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1881 struct sockaddr_in bss_peer[1] = {{0},};
1882 struct sockaddr_in sgsn_peer= {0};
1883 struct gprs_ra_id rai_bss =
1884 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1885 struct gprs_ra_id rai_unknown =
1886 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1887 uint16_t cell_id = 0x1234;
1888
1889 const uint32_t ptmsi = 0xefe2b700;
1890 const uint32_t local_tlli = 0xefe2b700;
1891
1892 const uint32_t foreign_tlli1 = 0x8000dead;
1893 const uint32_t foreign_tlli2 = 0x8000beef;
1894
1895 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1896 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1897
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001898 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001899 struct gbproxy_peer *peer;
1900 unsigned bss_nu = 0;
1901 unsigned sgsn_nu = 0;
1902
1903 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1904
1905 bssgp_nsi = nsi;
1906 gbcfg.nsi = bssgp_nsi;
1907 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1908 gbcfg.core_mcc = 0;
1909 gbcfg.core_mnc = 0;
1910 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1911 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1912 gbcfg.patch_ptmsi = 0;
1913 gbcfg.bss_ptmsi_state = 0;
1914 gbcfg.sgsn_tlli_state = 1;
1915
1916 configure_sgsn_peer(&sgsn_peer);
1917 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1918
1919 printf("=== %s ===\n", __func__);
1920 printf("--- Initialise SGSN ---\n\n");
1921
1922 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1923
1924 printf("--- Initialise BSS 1 ---\n\n");
1925
1926 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1927 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1928
1929 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1930 OSMO_ASSERT(peer != NULL);
1931
1932 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1933
1934 gprs_dump_nsi(nsi);
1935 dump_global(stdout, 0);
1936 dump_peers(stdout, 0, 0, &gbcfg);
1937
1938 printf("--- Establish first LLC connection ---\n\n");
1939
1940 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1941 foreign_tlli1, &rai_unknown, cell_id,
1942 GPRS_SAPI_GMM, bss_nu++,
1943 dtap_attach_req, sizeof(dtap_attach_req));
1944
1945 dump_peers(stdout, 0, 0, &gbcfg);
1946
1947 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1948 foreign_tlli1, 0, NULL, 0,
1949 GPRS_SAPI_GMM, sgsn_nu++,
1950 dtap_identity_req, sizeof(dtap_identity_req));
1951
1952 dump_peers(stdout, 0, 0, &gbcfg);
1953
1954 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1955 foreign_tlli1, &rai_bss, cell_id,
1956 GPRS_SAPI_GMM, bss_nu++,
1957 dtap_identity_resp, sizeof(dtap_identity_resp));
1958
1959 dump_peers(stdout, 0, 0, &gbcfg);
1960
1961 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1962 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1963 GPRS_SAPI_GMM, sgsn_nu++,
1964 dtap_attach_acc, sizeof(dtap_attach_acc));
1965
1966 dump_peers(stdout, 0, 0, &gbcfg);
1967
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001968 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1969 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1970 OSMO_ASSERT(link_info);
1971 OSMO_ASSERT(link_info == link_info2);
1972 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1973 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1974 OSMO_ASSERT(!link_info->tlli.bss_validated);
1975 OSMO_ASSERT(!link_info->tlli.net_validated);
1976 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001977
1978 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1979 local_tlli, &rai_bss, cell_id,
1980 GPRS_SAPI_GMM, bss_nu++,
1981 dtap_attach_complete, sizeof(dtap_attach_complete));
1982
1983 dump_peers(stdout, 0, 0, &gbcfg);
1984
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001985 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1986 OSMO_ASSERT(link_info);
1987 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1988 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1989 OSMO_ASSERT(link_info->tlli.bss_validated);
1990 OSMO_ASSERT(!link_info->tlli.net_validated);
1991 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001992
1993
1994 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1995 local_tlli, 1, imsi1, sizeof(imsi1),
1996 GPRS_SAPI_GMM, sgsn_nu++,
1997 dtap_gmm_information, sizeof(dtap_gmm_information));
1998
1999 dump_peers(stdout, 0, 0, &gbcfg);
2000
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002001 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
2002 OSMO_ASSERT(link_info);
2003 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2004 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002005
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002006 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2007 OSMO_ASSERT(link_info == link_info2);
2008 OSMO_ASSERT(link_info->tlli.assigned == 0);
2009 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2010 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002011
2012 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2013
2014 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2015 foreign_tlli2, &rai_unknown, cell_id,
2016 GPRS_SAPI_GMM, bss_nu++,
2017 dtap_attach_req, sizeof(dtap_attach_req));
2018
2019 dump_peers(stdout, 0, 0, &gbcfg);
2020
2021 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2022 foreign_tlli2, 0, NULL, 0,
2023 GPRS_SAPI_GMM, sgsn_nu++,
2024 dtap_identity_req, sizeof(dtap_identity_req));
2025
2026 dump_peers(stdout, 0, 0, &gbcfg);
2027
2028 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2029 foreign_tlli2, &rai_bss, cell_id,
2030 GPRS_SAPI_GMM, bss_nu++,
2031 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2032
2033 dump_peers(stdout, 0, 0, &gbcfg);
2034
2035 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2036 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2037 GPRS_SAPI_GMM, sgsn_nu++,
2038 dtap_attach_acc, sizeof(dtap_attach_acc));
2039
2040 dump_peers(stdout, 0, 0, &gbcfg);
2041
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002042 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2043 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2044 OSMO_ASSERT(link_info);
2045 OSMO_ASSERT(link_info == link_info2);
2046 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2047 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2048 OSMO_ASSERT(!link_info->tlli.bss_validated);
2049 OSMO_ASSERT(!link_info->tlli.net_validated);
2050 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002051
2052 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2053 local_tlli, &rai_bss, cell_id,
2054 GPRS_SAPI_GMM, bss_nu++,
2055 dtap_attach_complete, sizeof(dtap_attach_complete));
2056
2057 dump_peers(stdout, 0, 0, &gbcfg);
2058
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002059 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2060 OSMO_ASSERT(link_info);
2061 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2062 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2063 OSMO_ASSERT(link_info->tlli.bss_validated);
2064 OSMO_ASSERT(!link_info->tlli.net_validated);
2065 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002066
2067 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2068 local_tlli, 1, imsi2, sizeof(imsi2),
2069 GPRS_SAPI_GMM, sgsn_nu++,
2070 dtap_gmm_information, sizeof(dtap_gmm_information));
2071
2072 dump_peers(stdout, 0, 0, &gbcfg);
2073
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002074 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2075 OSMO_ASSERT(link_info);
2076 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2077 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002078
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002079 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2080 OSMO_ASSERT(link_info == link_info2);
2081 OSMO_ASSERT(link_info->tlli.assigned == 0);
2082 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2083 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002084
2085 dump_global(stdout, 0);
2086
2087 gbprox_reset(&gbcfg);
2088 gprs_ns_destroy(nsi);
2089 nsi = NULL;
2090}
2091
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002092static void test_gbproxy_ptmsi_patching()
2093{
2094 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2095 struct sockaddr_in bss_peer[1] = {{0},};
2096 struct sockaddr_in sgsn_peer= {0};
2097 struct gprs_ra_id rai_bss =
2098 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2099 struct gprs_ra_id rai_sgsn =
2100 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002101 struct gprs_ra_id rai_wrong_mcc_sgsn =
2102 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002103 struct gprs_ra_id rai_unknown =
2104 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2105 uint16_t cell_id = 0x1234;
2106
2107 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002108 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2109 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002110 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002111 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2112 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002113 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002114 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002115
2116 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002117 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2118 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002119 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002120 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2121 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002122 const uint32_t foreign_bss_tlli = 0x8000dead;
2123
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002124
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002125 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002126 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002127 struct gbproxy_peer *peer;
2128 unsigned bss_nu = 0;
2129 unsigned sgsn_nu = 0;
2130
2131 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002132 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2133 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2134 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2135 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2136 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002137
2138 bssgp_nsi = nsi;
2139 gbcfg.nsi = bssgp_nsi;
2140 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2141 gbcfg.core_mcc = 123;
2142 gbcfg.core_mnc = 456;
2143 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2144 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2145 gbcfg.patch_ptmsi = 1;
2146 gbcfg.bss_ptmsi_state = 0;
2147 gbcfg.sgsn_tlli_state = 1;
2148
2149 configure_sgsn_peer(&sgsn_peer);
2150 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2151
2152 printf("=== %s ===\n", __func__);
2153 printf("--- Initialise SGSN ---\n\n");
2154
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002155 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002156
2157 printf("--- Initialise BSS 1 ---\n\n");
2158
2159 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2160 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2161
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002162 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002163 OSMO_ASSERT(peer != NULL);
2164
2165 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2166
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002167 gprs_dump_nsi(nsi);
2168 dump_global(stdout, 0);
2169 dump_peers(stdout, 0, 0, &gbcfg);
2170
2171 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2172
2173 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2174 foreign_bss_tlli, &rai_unknown, cell_id,
2175 GPRS_SAPI_GMM, bss_nu++,
2176 dtap_attach_req, sizeof(dtap_attach_req));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
2180 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2181 random_sgsn_tlli, 0, NULL, 0,
2182 GPRS_SAPI_GMM, sgsn_nu++,
2183 dtap_identity_req, sizeof(dtap_identity_req));
2184
2185 dump_peers(stdout, 0, 0, &gbcfg);
2186
2187 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2188 foreign_bss_tlli, &rai_bss, cell_id,
2189 GPRS_SAPI_GMM, bss_nu++,
2190 dtap_identity_resp, sizeof(dtap_identity_resp));
2191
2192 dump_peers(stdout, 0, 0, &gbcfg);
2193
2194 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2195 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2196 GPRS_SAPI_GMM, sgsn_nu++,
2197 dtap_attach_acc, sizeof(dtap_attach_acc));
2198
2199 dump_peers(stdout, 0, 0, &gbcfg);
2200
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002201 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2202 OSMO_ASSERT(link_info);
2203 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2204 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2205 OSMO_ASSERT(!link_info->tlli.bss_validated);
2206 OSMO_ASSERT(!link_info->tlli.net_validated);
2207 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2208 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2209 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2210 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2211 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2212 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002213
2214 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2215 local_bss_tlli, &rai_bss, cell_id,
2216 GPRS_SAPI_GMM, bss_nu++,
2217 dtap_attach_complete, sizeof(dtap_attach_complete));
2218
2219 dump_peers(stdout, 0, 0, &gbcfg);
2220
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002221 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2222 OSMO_ASSERT(link_info);
2223 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2224 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2225 OSMO_ASSERT(link_info->tlli.bss_validated);
2226 OSMO_ASSERT(!link_info->tlli.net_validated);
2227 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2228 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2229 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2230 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002231
2232 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2233 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2234 GPRS_SAPI_GMM, sgsn_nu++,
2235 dtap_gmm_information, sizeof(dtap_gmm_information));
2236
2237 dump_peers(stdout, 0, 0, &gbcfg);
2238
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002239 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2240 OSMO_ASSERT(link_info);
2241 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2242 OSMO_ASSERT(link_info->tlli.assigned == 0);
2243 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2244 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002245
Jacob Erlbeck82add782014-09-05 18:08:12 +02002246 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2247 local_bss_tlli, &rai_bss, cell_id,
2248 GPRS_SAPI_GMM, bss_nu++,
2249 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2250
2251 dump_peers(stdout, 0, 0, &gbcfg);
2252
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002253 /* Non-DTAP */
2254 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2255 local_bss_tlli, &rai_bss, cell_id,
2256 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2257
2258 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2259 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2260 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2261
2262 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2263 local_bss_tlli, &rai_bss, cell_id,
2264 llc_ui_ll11_dns_query_ul,
2265 sizeof(llc_ui_ll11_dns_query_ul));
2266
2267 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2268 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2269 llc_ui_ll11_dns_resp_dl,
2270 sizeof(llc_ui_ll11_dns_resp_dl));
2271
2272 dump_peers(stdout, 0, 0, &gbcfg);
2273
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002274 /* Repeated RA Update Requests */
2275 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2276 local_bss_tlli, &rai_bss, 0x7080,
2277 GPRS_SAPI_GMM, bss_nu++,
2278 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2279
2280 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2281 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002287 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2288 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2289 OSMO_ASSERT(link_info);
2290 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2291 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2292 OSMO_ASSERT(!link_info->tlli.bss_validated);
2293 OSMO_ASSERT(!link_info->tlli.net_validated);
2294 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2295 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2296 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2297 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2298 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2299 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002300
2301 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2302 local_bss_tlli2, &rai_bss, 0x7080,
2303 GPRS_SAPI_GMM, bss_nu++,
2304 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2305
2306 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2307 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2308 GPRS_SAPI_GMM, sgsn_nu++,
2309 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2310
2311 dump_peers(stdout, 0, 0, &gbcfg);
2312
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002313 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2314 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2315 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2316 OSMO_ASSERT(link_info);
2317 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2318 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2319 OSMO_ASSERT(!link_info->tlli.bss_validated);
2320 OSMO_ASSERT(!link_info->tlli.net_validated);
2321 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2322 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2323 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2324 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2325 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2326 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002327
2328 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2329 local_bss_tlli3, &rai_bss, 0x7080,
2330 GPRS_SAPI_GMM, bss_nu++,
2331 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2332
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002333 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002334
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002335 OSMO_ASSERT(link_info);
2336 OSMO_ASSERT(link_info->tlli.bss_validated);
2337 OSMO_ASSERT(!link_info->tlli.net_validated);
2338 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2339 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002340
2341 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2342 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2343 GPRS_SAPI_GMM, sgsn_nu++,
2344 dtap_gmm_information, sizeof(dtap_gmm_information));
2345
2346 dump_peers(stdout, 0, 0, &gbcfg);
2347
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002348 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2349 OSMO_ASSERT(link_info);
2350 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2351 OSMO_ASSERT(link_info->tlli.assigned == 0);
2352 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2353 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002354
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002355 /* Other messages */
2356 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002357 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002358
2359 dump_peers(stdout, 0, 0, &gbcfg);
2360
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002361 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002362
2363 dump_peers(stdout, 0, 0, &gbcfg);
2364
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002365 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002366
2367 dump_peers(stdout, 0, 0, &gbcfg);
2368
2369 /* Bad case: Invalid BVCI */
2370 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002371 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002372 dump_global(stdout, 0);
2373
2374 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002375 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002376
2377 dump_global(stdout, 0);
2378
2379 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002380 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002381 &rai_wrong_mcc_sgsn);
2382
2383 dump_global(stdout, 0);
2384
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002385 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2386 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2387 unknown_sgsn_tlli, 1, NULL, 0,
2388 GPRS_SAPI_GMM, 2,
2389 dtap_gmm_information, sizeof(dtap_gmm_information));
2390
2391 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2392 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2393 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2394 GPRS_SAPI_GMM, 3,
2395 dtap_gmm_information, sizeof(dtap_gmm_information));
2396
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002397 /* Detach */
2398 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002399 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002400 GPRS_SAPI_GMM, bss_nu++,
2401 dtap_detach_req, sizeof(dtap_detach_req));
2402
2403 dump_peers(stdout, 0, 0, &gbcfg);
2404
2405 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002406 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002407 GPRS_SAPI_GMM, sgsn_nu++,
2408 dtap_detach_acc, sizeof(dtap_detach_acc));
2409
2410 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002411
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002412 dump_global(stdout, 0);
2413
2414 gbprox_reset(&gbcfg);
2415 gprs_ns_destroy(nsi);
2416 nsi = NULL;
2417}
2418
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002419static void test_gbproxy_imsi_acquisition()
2420{
2421 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2422 struct sockaddr_in bss_peer[1] = {{0},};
2423 struct sockaddr_in sgsn_peer= {0};
2424 struct gprs_ra_id rai_bss =
2425 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2426 struct gprs_ra_id rai_sgsn =
2427 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2428 struct gprs_ra_id rai_wrong_mcc_sgsn =
2429 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2430 struct gprs_ra_id rai_unknown =
2431 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2432 uint16_t cell_id = 0x1234;
2433
2434 const uint32_t sgsn_ptmsi = 0xefe2b700;
2435 const uint32_t local_sgsn_tlli = 0xefe2b700;
2436 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002437 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002438
2439 const uint32_t bss_ptmsi = 0xc00f7304;
2440 const uint32_t local_bss_tlli = 0xc00f7304;
2441 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002442 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002443
2444 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002445 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002446 struct gbproxy_peer *peer;
2447 unsigned bss_nu = 0;
2448 unsigned sgsn_nu = 0;
2449
2450 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2451
2452 bssgp_nsi = nsi;
2453 gbcfg.nsi = bssgp_nsi;
2454 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2455 gbcfg.core_mcc = 123;
2456 gbcfg.core_mnc = 456;
2457 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2458 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2459 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002460 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002461 gbcfg.bss_ptmsi_state = 0;
2462 gbcfg.sgsn_tlli_state = 1;
2463
2464 configure_sgsn_peer(&sgsn_peer);
2465 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2466
2467 printf("=== %s ===\n", __func__);
2468 printf("--- Initialise SGSN ---\n\n");
2469
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002470 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002471
2472 printf("--- Initialise BSS 1 ---\n\n");
2473
2474 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2475 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2476
2477 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2478 OSMO_ASSERT(peer != NULL);
2479
2480 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2481
2482 gprs_dump_nsi(nsi);
2483 dump_global(stdout, 0);
2484 dump_peers(stdout, 0, 0, &gbcfg);
2485
2486 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2487
2488 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002489 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002490 GPRS_SAPI_GMM, bss_nu++,
2491 dtap_attach_req, sizeof(dtap_attach_req));
2492
2493 dump_peers(stdout, 0, 0, &gbcfg);
2494
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002495 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2496 foreign_bss_tlli, &rai_bss, cell_id,
2497 GPRS_SAPI_GMM, bss_nu++,
2498 dtap_identity_resp, sizeof(dtap_identity_resp));
2499
2500 dump_peers(stdout, 0, 0, &gbcfg);
2501
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002502 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2503 random_sgsn_tlli, 0, NULL, 0,
2504 GPRS_SAPI_GMM, sgsn_nu++,
2505 dtap_identity_req, sizeof(dtap_identity_req));
2506
2507 dump_peers(stdout, 0, 0, &gbcfg);
2508
2509 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2510 foreign_bss_tlli, &rai_bss, cell_id,
2511 GPRS_SAPI_GMM, bss_nu++,
2512 dtap_identity_resp, sizeof(dtap_identity_resp));
2513
2514 dump_peers(stdout, 0, 0, &gbcfg);
2515
2516 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2517 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2518 GPRS_SAPI_GMM, sgsn_nu++,
2519 dtap_attach_acc, sizeof(dtap_attach_acc));
2520
2521 dump_peers(stdout, 0, 0, &gbcfg);
2522
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002523 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2524 OSMO_ASSERT(link_info);
2525 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2526 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2527 OSMO_ASSERT(!link_info->tlli.bss_validated);
2528 OSMO_ASSERT(!link_info->tlli.net_validated);
2529 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2530 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2531 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2532 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2533 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2534 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002535
2536 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2537 local_bss_tlli, &rai_bss, cell_id,
2538 GPRS_SAPI_GMM, bss_nu++,
2539 dtap_attach_complete, sizeof(dtap_attach_complete));
2540
2541 dump_peers(stdout, 0, 0, &gbcfg);
2542
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002543 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2544 OSMO_ASSERT(link_info);
2545 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2546 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2547 OSMO_ASSERT(link_info->tlli.bss_validated);
2548 OSMO_ASSERT(!link_info->tlli.net_validated);
2549 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2550 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2551 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2552 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002553
2554 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2555 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2556 GPRS_SAPI_GMM, sgsn_nu++,
2557 dtap_gmm_information, sizeof(dtap_gmm_information));
2558
2559 dump_peers(stdout, 0, 0, &gbcfg);
2560
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002561 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2562 OSMO_ASSERT(link_info);
2563 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2564 OSMO_ASSERT(link_info->tlli.assigned == 0);
2565 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2566 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002567
2568 /* Non-DTAP */
2569 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2570 local_bss_tlli, &rai_bss, cell_id,
2571 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2572
2573 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2574 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2575 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2576
2577 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2578 local_bss_tlli, &rai_bss, cell_id,
2579 llc_ui_ll11_dns_query_ul,
2580 sizeof(llc_ui_ll11_dns_query_ul));
2581
2582 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2583 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2584 llc_ui_ll11_dns_resp_dl,
2585 sizeof(llc_ui_ll11_dns_resp_dl));
2586
2587 dump_peers(stdout, 0, 0, &gbcfg);
2588
2589 /* Other messages */
2590 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2591 local_bss_tlli, 1, 12);
2592
2593 dump_peers(stdout, 0, 0, &gbcfg);
2594
2595 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2596 local_sgsn_tlli, 1, 12);
2597
2598 dump_peers(stdout, 0, 0, &gbcfg);
2599
2600 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2601
2602 dump_peers(stdout, 0, 0, &gbcfg);
2603
2604 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2605
2606 dump_peers(stdout, 0, 0, &gbcfg);
2607
2608 /* Bad case: Invalid BVCI */
2609 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2610 local_bss_tlli, 1, 12);
2611 dump_global(stdout, 0);
2612
2613 /* Bad case: Invalid RAI */
2614 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2615
2616 dump_global(stdout, 0);
2617
2618 /* Bad case: Invalid MCC (LAC ok) */
2619 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2620 &rai_wrong_mcc_sgsn);
2621
2622 dump_global(stdout, 0);
2623
2624 /* Detach */
2625 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2626 local_bss_tlli, &rai_bss, cell_id,
2627 GPRS_SAPI_GMM, bss_nu++,
2628 dtap_detach_req, sizeof(dtap_detach_req));
2629
2630 dump_peers(stdout, 0, 0, &gbcfg);
2631
2632 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2633 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2634 GPRS_SAPI_GMM, sgsn_nu++,
2635 dtap_detach_acc, sizeof(dtap_detach_acc));
2636
2637 dump_peers(stdout, 0, 0, &gbcfg);
2638
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002639 /* RA Update request */
2640
2641 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2642 foreign_bss_tlli, &rai_unknown, 0x7080,
2643 GPRS_SAPI_GMM, bss_nu++,
2644 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2645
2646 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2647 foreign_bss_tlli, &rai_bss, cell_id,
2648 GPRS_SAPI_GMM, bss_nu++,
2649 dtap_identity_resp, sizeof(dtap_identity_resp));
2650
2651 dump_peers(stdout, 0, 0, &gbcfg);
2652
2653 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2654 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2655 GPRS_SAPI_GMM, sgsn_nu++,
2656 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2657
2658 dump_peers(stdout, 0, 0, &gbcfg);
2659
2660 /* Detach */
2661
2662 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2663 local_bss_tlli, &rai_bss, cell_id,
2664 GPRS_SAPI_GMM, bss_nu++,
2665 dtap_detach_req, sizeof(dtap_detach_req));
2666
2667 dump_peers(stdout, 0, 0, &gbcfg);
2668
2669 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2670 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2671 GPRS_SAPI_GMM, sgsn_nu++,
2672 dtap_detach_acc, sizeof(dtap_detach_acc));
2673
2674 dump_peers(stdout, 0, 0, &gbcfg);
2675
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002676 /* Special case: Repeated Attach Requests */
2677
2678 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2679 foreign_bss_tlli, &rai_unknown, cell_id,
2680 GPRS_SAPI_GMM, bss_nu++,
2681 dtap_attach_req, sizeof(dtap_attach_req));
2682
2683 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2684 foreign_bss_tlli, &rai_unknown, cell_id,
2685 GPRS_SAPI_GMM, bss_nu++,
2686 dtap_attach_req, sizeof(dtap_attach_req));
2687
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002688 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2689 foreign_bss_tlli, &rai_bss, cell_id,
2690 GPRS_SAPI_GMM, bss_nu++,
2691 dtap_detach_req, sizeof(dtap_detach_req));
2692
2693 dump_peers(stdout, 0, 0, &gbcfg);
2694
2695 /* Special case: Detach from an unknown TLLI */
2696
2697 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2698 other_bss_tlli, &rai_bss, cell_id,
2699 GPRS_SAPI_GMM, bss_nu++,
2700 dtap_detach_req, sizeof(dtap_detach_req));
2701
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002702 dump_peers(stdout, 0, 0, &gbcfg);
2703
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002704 /* Special case: Repeated RA Update Requests */
2705
2706 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2707 foreign_bss_tlli, &rai_unknown, 0x7080,
2708 GPRS_SAPI_GMM, bss_nu++,
2709 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2710
2711 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2712 foreign_bss_tlli, &rai_unknown, 0x7080,
2713 GPRS_SAPI_GMM, bss_nu++,
2714 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2715
2716 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2717 foreign_bss_tlli, &rai_bss, cell_id,
2718 GPRS_SAPI_GMM, bss_nu++,
2719 dtap_detach_req, sizeof(dtap_detach_req));
2720
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002723 dump_global(stdout, 0);
2724
2725 gbprox_reset(&gbcfg);
2726 gprs_ns_destroy(nsi);
2727 nsi = NULL;
2728}
2729
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002730static void test_gbproxy_secondary_sgsn()
2731{
2732 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2733 struct sockaddr_in bss_peer[1] = {{0},};
2734 struct sockaddr_in sgsn_peer[2]= {{0},};
2735 struct gprs_ra_id rai_bss =
2736 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2737 struct gprs_ra_id rai_sgsn =
2738 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2739 struct gprs_ra_id rai_unknown =
2740 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2741 uint16_t cell_id = 0x1234;
2742
2743 const uint32_t sgsn_ptmsi = 0xefe2b700;
2744 const uint32_t local_sgsn_tlli = 0xefe2b700;
2745 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2746
2747 const uint32_t bss_ptmsi = 0xc00f7304;
2748 const uint32_t local_bss_tlli = 0xc00f7304;
2749 const uint32_t foreign_bss_tlli = 0x8000dead;
2750
2751 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2752 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2753 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2754 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2755 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2756 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2757
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002758 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002759 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002760 const uint32_t local_bss_tlli3 = 0xead4775a;
2761 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2762
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002763 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2764 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002765 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002766 struct gbproxy_link_info *link_info;
2767 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002768 struct gbproxy_peer *peer;
2769 unsigned bss_nu = 0;
2770 unsigned sgsn_nu = 0;
2771
2772 const char *err_msg = NULL;
2773 const char *filter_re = "999999";
2774
2775 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2776 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2777
2778 bssgp_nsi = nsi;
2779 gbcfg.nsi = bssgp_nsi;
2780 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2781 gbcfg.core_mcc = 123;
2782 gbcfg.core_mnc = 456;
2783 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2784 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2785 gbcfg.patch_ptmsi = 1;
2786 gbcfg.acquire_imsi = 1;
2787 gbcfg.bss_ptmsi_state = 0;
2788 gbcfg.sgsn_tlli_state = 1;
2789 gbcfg.route_to_sgsn2 = 1;
2790 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2791
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02002792 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02002793 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002794 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2795 err_msg);
2796 OSMO_ASSERT(err_msg == NULL);
2797 }
2798
2799 configure_sgsn_peer(&sgsn_peer[0]);
2800 configure_sgsn2_peer(&sgsn_peer[1]);
2801 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2802
2803 printf("=== %s ===\n", __func__);
2804 printf("--- Initialise SGSN 1 ---\n\n");
2805
2806 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2807
2808 printf("--- Initialise SGSN 2 ---\n\n");
2809
2810 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2811
2812 printf("--- Initialise BSS 1 ---\n\n");
2813
2814 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2815 setup_bssgp(nsi, &bss_peer[0], 0x0);
2816 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2817 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2818 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2819 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2820
2821 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2822 OSMO_ASSERT(peer != NULL);
2823
2824 gprs_dump_nsi(nsi);
2825 dump_global(stdout, 0);
2826 dump_peers(stdout, 0, 0, &gbcfg);
2827
2828 printf("--- Flow control ---\n\n");
2829
2830 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2831 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2832 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2833
2834 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2835
2836 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2837 foreign_bss_tlli, &rai_unknown, cell_id,
2838 GPRS_SAPI_GMM, bss_nu++,
2839 dtap_attach_req, sizeof(dtap_attach_req));
2840
2841 dump_peers(stdout, 0, 0, &gbcfg);
2842
2843 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2844 foreign_bss_tlli, &rai_bss, cell_id,
2845 GPRS_SAPI_GMM, bss_nu++,
2846 dtap_identity_resp, sizeof(dtap_identity_resp));
2847
2848 dump_peers(stdout, 0, 0, &gbcfg);
2849
2850 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2851 random_sgsn_tlli, 0, NULL, 0,
2852 GPRS_SAPI_GMM, sgsn_nu++,
2853 dtap_identity_req, sizeof(dtap_identity_req));
2854
2855 dump_peers(stdout, 0, 0, &gbcfg);
2856
2857 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2858 foreign_bss_tlli, &rai_bss, cell_id,
2859 GPRS_SAPI_GMM, bss_nu++,
2860 dtap_identity_resp, sizeof(dtap_identity_resp));
2861
2862 dump_peers(stdout, 0, 0, &gbcfg);
2863
2864 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2865 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2866 GPRS_SAPI_GMM, sgsn_nu++,
2867 dtap_attach_acc, sizeof(dtap_attach_acc));
2868
2869 dump_peers(stdout, 0, 0, &gbcfg);
2870
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002871 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2872 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2873 OSMO_ASSERT(link_info);
2874 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2875 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2876 OSMO_ASSERT(!link_info->tlli.bss_validated);
2877 OSMO_ASSERT(!link_info->tlli.net_validated);
2878 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2879 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2880 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2881 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2882 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2883 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002884
2885 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2886 local_bss_tlli, &rai_bss, cell_id,
2887 GPRS_SAPI_GMM, bss_nu++,
2888 dtap_attach_complete, sizeof(dtap_attach_complete));
2889
2890 dump_peers(stdout, 0, 0, &gbcfg);
2891
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002892 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2893 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2894 OSMO_ASSERT(link_info);
2895 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2896 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2897 OSMO_ASSERT(link_info->tlli.bss_validated);
2898 OSMO_ASSERT(!link_info->tlli.net_validated);
2899 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2900 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2901 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2902 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002903
2904 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2905 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2906 GPRS_SAPI_GMM, sgsn_nu++,
2907 dtap_gmm_information, sizeof(dtap_gmm_information));
2908
2909 dump_peers(stdout, 0, 0, &gbcfg);
2910
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002911 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2912 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2913 OSMO_ASSERT(link_info);
2914 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2915 OSMO_ASSERT(link_info->tlli.assigned == 0);
2916 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2917 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002918
2919 /* Non-DTAP */
2920 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2921 local_bss_tlli, &rai_bss, cell_id,
2922 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2923
2924 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2925 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2926 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2927
2928 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2929 local_bss_tlli, &rai_bss, cell_id,
2930 llc_ui_ll11_dns_query_ul,
2931 sizeof(llc_ui_ll11_dns_query_ul));
2932
2933 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2934 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2935 llc_ui_ll11_dns_resp_dl,
2936 sizeof(llc_ui_ll11_dns_resp_dl));
2937
2938 dump_peers(stdout, 0, 0, &gbcfg);
2939
2940 /* Other messages */
2941 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2942 local_bss_tlli, 1, 12);
2943
2944 dump_peers(stdout, 0, 0, &gbcfg);
2945
2946 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2947 local_sgsn_tlli, 1, 12);
2948
2949 dump_peers(stdout, 0, 0, &gbcfg);
2950
2951 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2952
2953 dump_peers(stdout, 0, 0, &gbcfg);
2954
2955 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2956
2957 dump_peers(stdout, 0, 0, &gbcfg);
2958
2959 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2960
2961 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2962 foreign_bss_tlli2, &rai_unknown, cell_id,
2963 GPRS_SAPI_GMM, bss_nu++,
2964 dtap_attach_req, sizeof(dtap_attach_req));
2965
2966 dump_peers(stdout, 0, 0, &gbcfg);
2967
2968 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2969 foreign_bss_tlli2, &rai_bss, cell_id,
2970 GPRS_SAPI_GMM, bss_nu++,
2971 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2972
2973 dump_peers(stdout, 0, 0, &gbcfg);
2974
2975 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2976 random_sgsn_tlli2, 0, NULL, 0,
2977 GPRS_SAPI_GMM, sgsn_nu++,
2978 dtap_identity_req, sizeof(dtap_identity_req));
2979
2980 dump_peers(stdout, 0, 0, &gbcfg);
2981
2982 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2983 foreign_bss_tlli2, &rai_bss, cell_id,
2984 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002985 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002986
2987 dump_peers(stdout, 0, 0, &gbcfg);
2988
2989 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2990 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2991 GPRS_SAPI_GMM, sgsn_nu++,
2992 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2993
2994 dump_peers(stdout, 0, 0, &gbcfg);
2995
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002996 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2997 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2998 OSMO_ASSERT(link_info);
2999 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3000 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3001 OSMO_ASSERT(!link_info->tlli.bss_validated);
3002 OSMO_ASSERT(!link_info->tlli.net_validated);
3003 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3004 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3005 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3006 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3007 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3008 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003009
3010 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3011 local_bss_tlli2, &rai_bss, cell_id,
3012 GPRS_SAPI_GMM, bss_nu++,
3013 dtap_attach_complete, sizeof(dtap_attach_complete));
3014
3015 dump_peers(stdout, 0, 0, &gbcfg);
3016
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003017 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3018 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3019 OSMO_ASSERT(link_info);
3020 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3021 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3022 OSMO_ASSERT(link_info->tlli.bss_validated);
3023 OSMO_ASSERT(!link_info->tlli.net_validated);
3024 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3025 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3026 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3027 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003028
3029 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3030 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3031 GPRS_SAPI_GMM, sgsn_nu++,
3032 dtap_gmm_information, sizeof(dtap_gmm_information));
3033
3034 dump_peers(stdout, 0, 0, &gbcfg);
3035
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003036 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3037 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3038 OSMO_ASSERT(link_info);
3039 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3040 OSMO_ASSERT(link_info->tlli.assigned == 0);
3041 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3042 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003043
3044 /* Non-DTAP */
3045 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3046 local_bss_tlli2, &rai_bss, cell_id,
3047 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3048
3049 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3050 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3051 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3052
3053 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3054 local_bss_tlli2, &rai_bss, cell_id,
3055 llc_ui_ll11_dns_query_ul,
3056 sizeof(llc_ui_ll11_dns_query_ul));
3057
3058 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3059 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3060 llc_ui_ll11_dns_resp_dl,
3061 sizeof(llc_ui_ll11_dns_resp_dl));
3062
3063 dump_peers(stdout, 0, 0, &gbcfg);
3064
3065 /* Other messages */
3066 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3067 local_bss_tlli2, 1, 12);
3068
3069 dump_peers(stdout, 0, 0, &gbcfg);
3070
3071 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3072 local_sgsn_tlli2, 1, 12);
3073
3074 dump_peers(stdout, 0, 0, &gbcfg);
3075
3076 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
3080 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3081
3082 dump_peers(stdout, 0, 0, &gbcfg);
3083
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003084 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3085
3086 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3087 foreign_bss_tlli3, &rai_unknown, cell_id,
3088 GPRS_SAPI_GMM, bss_nu++,
3089 dtap_attach_req, sizeof(dtap_attach_req));
3090
3091 dump_peers(stdout, 0, 0, &gbcfg);
3092
3093 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3094 foreign_bss_tlli3, &rai_bss, cell_id,
3095 GPRS_SAPI_GMM, bss_nu++,
3096 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3097
3098 dump_peers(stdout, 0, 0, &gbcfg);
3099
3100 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3101 random_sgsn_tlli3, 0, NULL, 0,
3102 GPRS_SAPI_GMM, sgsn_nu++,
3103 dtap_identity_req, sizeof(dtap_identity_req));
3104
3105 dump_peers(stdout, 0, 0, &gbcfg);
3106
3107 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3108 foreign_bss_tlli3, &rai_bss, cell_id,
3109 GPRS_SAPI_GMM, bss_nu++,
3110 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3111
3112 dump_peers(stdout, 0, 0, &gbcfg);
3113
3114 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3115 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3116 GPRS_SAPI_GMM, sgsn_nu++,
3117 dtap_attach_acc, sizeof(dtap_attach_acc));
3118
3119 dump_peers(stdout, 0, 0, &gbcfg);
3120
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003121 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3122 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3123 OSMO_ASSERT(link_info);
3124 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3125 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3126 OSMO_ASSERT(!link_info->tlli.bss_validated);
3127 OSMO_ASSERT(!link_info->tlli.net_validated);
3128 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3129 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3130 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3131 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3132 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3133 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003134
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003135 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3136 local_bss_tlli3, &rai_bss, cell_id,
3137 GPRS_SAPI_GMM, bss_nu++,
3138 dtap_attach_complete, sizeof(dtap_attach_complete));
3139
3140 dump_peers(stdout, 0, 0, &gbcfg);
3141
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003142 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003143 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003144 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3145 OSMO_ASSERT(link_info);
3146 OSMO_ASSERT(link_info != other_info);
3147 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3148 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3149 OSMO_ASSERT(link_info->tlli.bss_validated);
3150 OSMO_ASSERT(!link_info->tlli.net_validated);
3151 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3152 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3153 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3154 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003155
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003156 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3157 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3158 GPRS_SAPI_GMM, sgsn_nu++,
3159 dtap_gmm_information, sizeof(dtap_gmm_information));
3160
3161 dump_peers(stdout, 0, 0, &gbcfg);
3162
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003163 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003164 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003165 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3166 OSMO_ASSERT(link_info);
3167 OSMO_ASSERT(link_info != other_info);
3168 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3169 OSMO_ASSERT(link_info->tlli.assigned == 0);
3170 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3171 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003172
3173
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003174 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3175
3176 /* Detach */
3177 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3178 local_bss_tlli, &rai_bss, cell_id,
3179 GPRS_SAPI_GMM, bss_nu++,
3180 dtap_detach_req, sizeof(dtap_detach_req));
3181
3182 dump_peers(stdout, 0, 0, &gbcfg);
3183
3184 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3185 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3186 GPRS_SAPI_GMM, sgsn_nu++,
3187 dtap_detach_acc, sizeof(dtap_detach_acc));
3188
3189 dump_peers(stdout, 0, 0, &gbcfg);
3190
3191 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3192
3193 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3194 local_bss_tlli2, &rai_bss, cell_id,
3195 GPRS_SAPI_GMM, bss_nu++,
3196 dtap_detach_req, sizeof(dtap_detach_req));
3197
3198 dump_peers(stdout, 0, 0, &gbcfg);
3199
3200 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3201 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3202 GPRS_SAPI_GMM, sgsn_nu++,
3203 dtap_detach_acc, sizeof(dtap_detach_acc));
3204
3205 dump_peers(stdout, 0, 0, &gbcfg);
3206
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003207 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3208
3209 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3210 local_bss_tlli3, &rai_bss, cell_id,
3211 GPRS_SAPI_GMM, bss_nu++,
3212 dtap_detach_req, sizeof(dtap_detach_req));
3213
3214 dump_peers(stdout, 0, 0, &gbcfg);
3215
3216 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3217 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3218 GPRS_SAPI_GMM, sgsn_nu++,
3219 dtap_detach_acc, sizeof(dtap_detach_acc));
3220
3221 dump_peers(stdout, 0, 0, &gbcfg);
3222
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003223 dump_global(stdout, 0);
3224
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003225 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003226 gbprox_reset(&gbcfg);
3227 gprs_ns_destroy(nsi);
3228 nsi = NULL;
3229}
3230
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003231static void test_gbproxy_keep_info()
3232{
3233 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3234 struct sockaddr_in bss_peer[1] = {{0},};
3235 struct sockaddr_in sgsn_peer= {0};
3236 struct gprs_ra_id rai_bss =
3237 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3238 uint16_t cell_id = 0x1234;
3239
3240 const uint32_t ptmsi = 0xefe2b700;
3241 const uint32_t local_tlli = 0xefe2b700;
3242 const uint32_t foreign_tlli = 0xafe2b700;
3243
3244 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003245 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003246 struct gbproxy_peer *peer;
3247 unsigned bss_nu = 0;
3248 unsigned sgsn_nu = 0;
3249
3250 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3251
3252 bssgp_nsi = nsi;
3253 gbcfg.nsi = bssgp_nsi;
3254 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3255 gbcfg.patch_ptmsi = 0;
3256 gbcfg.acquire_imsi = 1;
3257 gbcfg.bss_ptmsi_state = 0;
3258 gbcfg.sgsn_tlli_state = 1;
3259 gbcfg.core_mcc = 0;
3260 gbcfg.core_mnc = 0;
3261 gbcfg.core_apn = NULL;
3262 gbcfg.core_apn_size = 0;
3263 gbcfg.route_to_sgsn2 = 0;
3264 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003265 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003266
3267 configure_sgsn_peer(&sgsn_peer);
3268 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3269
3270 printf("=== %s ===\n", __func__);
3271 printf("--- Initialise SGSN ---\n\n");
3272
3273 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3274
3275 printf("--- Initialise BSS 1 ---\n\n");
3276
3277 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3278 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3279
3280 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3281 OSMO_ASSERT(peer != NULL);
3282
3283 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3284
3285 gprs_dump_nsi(nsi);
3286 dump_global(stdout, 0);
3287 dump_peers(stdout, 0, 0, &gbcfg);
3288
3289 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3290
3291 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3292 foreign_tlli, &rai_bss, cell_id,
3293 GPRS_SAPI_GMM, bss_nu++,
3294 dtap_attach_req, sizeof(dtap_attach_req));
3295
3296 dump_peers(stdout, 0, 0, &gbcfg);
3297
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003298 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3299 OSMO_ASSERT(link_info);
3300 OSMO_ASSERT(link_info->imsi_len == 0);
3301 OSMO_ASSERT(!link_info->is_deregistered);
3302 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003303
3304 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3305 foreign_tlli, &rai_bss, cell_id,
3306 GPRS_SAPI_GMM, bss_nu++,
3307 dtap_identity_resp, sizeof(dtap_identity_resp));
3308
3309 dump_peers(stdout, 0, 0, &gbcfg);
3310
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003311 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3312 OSMO_ASSERT(link_info);
3313 OSMO_ASSERT(link_info->imsi_len > 0);
3314 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003315
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003316 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3317 foreign_tlli, 0, NULL, 0,
3318 GPRS_SAPI_GMM, sgsn_nu++,
3319 dtap_identity_req, sizeof(dtap_identity_req));
3320
3321 dump_peers(stdout, 0, 0, &gbcfg);
3322
3323 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3324 foreign_tlli, &rai_bss, cell_id,
3325 GPRS_SAPI_GMM, bss_nu++,
3326 dtap_identity_resp, sizeof(dtap_identity_resp));
3327
3328 dump_peers(stdout, 0, 0, &gbcfg);
3329
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003330 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3331 OSMO_ASSERT(link_info);
3332 OSMO_ASSERT(link_info->imsi_len > 0);
3333 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003334
3335 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3336 foreign_tlli, 1, imsi, sizeof(imsi),
3337 GPRS_SAPI_GMM, sgsn_nu++,
3338 dtap_attach_acc, sizeof(dtap_attach_acc));
3339
3340 dump_peers(stdout, 0, 0, &gbcfg);
3341
3342 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3343 local_tlli, &rai_bss, cell_id,
3344 GPRS_SAPI_GMM, bss_nu++,
3345 dtap_attach_complete, sizeof(dtap_attach_complete));
3346
3347 dump_peers(stdout, 0, 0, &gbcfg);
3348
3349 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3350 local_tlli, 1, imsi, sizeof(imsi),
3351 GPRS_SAPI_GMM, sgsn_nu++,
3352 dtap_gmm_information, sizeof(dtap_gmm_information));
3353
3354 dump_peers(stdout, 0, 0, &gbcfg);
3355
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003356 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3357 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003358
3359 /* Detach (MO) */
3360 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3361 local_tlli, &rai_bss, cell_id,
3362 GPRS_SAPI_GMM, bss_nu++,
3363 dtap_detach_req, sizeof(dtap_detach_req));
3364
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003365 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3366 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003367
3368 dump_peers(stdout, 0, 0, &gbcfg);
3369
3370 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3371 local_tlli, 1, imsi, sizeof(imsi),
3372 GPRS_SAPI_GMM, sgsn_nu++,
3373 dtap_detach_acc, sizeof(dtap_detach_acc));
3374
3375 dump_peers(stdout, 0, 0, &gbcfg);
3376
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003377 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3378 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3379 OSMO_ASSERT(link_info);
3380 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003381
3382 /* Re-Attach */
3383 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3384 foreign_tlli, &rai_bss, cell_id,
3385 GPRS_SAPI_GMM, bss_nu++,
3386 dtap_attach_req3, sizeof(dtap_attach_req3));
3387
3388 dump_peers(stdout, 0, 0, &gbcfg);
3389
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003390 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3391 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3392 OSMO_ASSERT(link_info);
3393 OSMO_ASSERT(link_info == link_info2);
3394 OSMO_ASSERT(link_info->imsi_len != 0);
3395 OSMO_ASSERT(!link_info->is_deregistered);
3396 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003397
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003398 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3399 foreign_tlli, 1, imsi, sizeof(imsi),
3400 GPRS_SAPI_GMM, sgsn_nu++,
3401 dtap_attach_acc, sizeof(dtap_attach_acc));
3402
3403 dump_peers(stdout, 0, 0, &gbcfg);
3404
3405 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3406 local_tlli, &rai_bss, cell_id,
3407 GPRS_SAPI_GMM, bss_nu++,
3408 dtap_attach_complete, sizeof(dtap_attach_complete));
3409
3410 dump_peers(stdout, 0, 0, &gbcfg);
3411
3412 /* Detach (MT) */
3413 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3414 local_tlli, 1, imsi, sizeof(imsi),
3415 GPRS_SAPI_GMM, sgsn_nu++,
3416 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3417
3418 dump_peers(stdout, 0, 0, &gbcfg);
3419
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003420 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3421 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003422
3423 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3424 local_tlli, &rai_bss, cell_id,
3425 GPRS_SAPI_GMM, bss_nu++,
3426 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3427
3428 dump_peers(stdout, 0, 0, &gbcfg);
3429
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003430 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3431 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3432 OSMO_ASSERT(link_info);
3433 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003434
3435 /* Re-Attach */
3436 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3437 foreign_tlli, &rai_bss, cell_id,
3438 GPRS_SAPI_GMM, bss_nu++,
3439 dtap_attach_req3, sizeof(dtap_attach_req3));
3440
3441 dump_peers(stdout, 0, 0, &gbcfg);
3442
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003443 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3444 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3445 OSMO_ASSERT(link_info);
3446 OSMO_ASSERT(link_info == link_info2);
3447 OSMO_ASSERT(link_info->imsi_len != 0);
3448 OSMO_ASSERT(!link_info->is_deregistered);
3449 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003450
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003451 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3452 foreign_tlli, 1, imsi, sizeof(imsi),
3453 GPRS_SAPI_GMM, sgsn_nu++,
3454 dtap_attach_acc, sizeof(dtap_attach_acc));
3455
3456 dump_peers(stdout, 0, 0, &gbcfg);
3457
3458 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3459 local_tlli, &rai_bss, cell_id,
3460 GPRS_SAPI_GMM, bss_nu++,
3461 dtap_attach_complete, sizeof(dtap_attach_complete));
3462
3463 dump_peers(stdout, 0, 0, &gbcfg);
3464
3465 /* Detach (MT) */
3466 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3467 local_tlli, 1, imsi, sizeof(imsi),
3468 GPRS_SAPI_GMM, sgsn_nu++,
3469 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3470
3471 dump_peers(stdout, 0, 0, &gbcfg);
3472
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003473 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3474 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003475
3476 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3477 local_tlli, &rai_bss, cell_id,
3478 GPRS_SAPI_GMM, bss_nu++,
3479 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3480
3481 dump_peers(stdout, 0, 0, &gbcfg);
3482
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003483 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3484 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3485 OSMO_ASSERT(link_info);
3486 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003487
3488 /* Re-Attach */
3489 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3490 foreign_tlli, &rai_bss, cell_id,
3491 GPRS_SAPI_GMM, bss_nu++,
3492 dtap_attach_req3, sizeof(dtap_attach_req3));
3493
3494 dump_peers(stdout, 0, 0, &gbcfg);
3495
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003496 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3497 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3498 OSMO_ASSERT(link_info);
3499 OSMO_ASSERT(link_info == link_info2);
3500 OSMO_ASSERT(link_info->imsi_len != 0);
3501 OSMO_ASSERT(!link_info->is_deregistered);
3502 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003503
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003504 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3505 foreign_tlli, 1, imsi, sizeof(imsi),
3506 GPRS_SAPI_GMM, sgsn_nu++,
3507 dtap_attach_acc, sizeof(dtap_attach_acc));
3508
3509 dump_peers(stdout, 0, 0, &gbcfg);
3510
3511 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3512 local_tlli, &rai_bss, cell_id,
3513 GPRS_SAPI_GMM, bss_nu++,
3514 dtap_attach_complete, sizeof(dtap_attach_complete));
3515
3516 dump_peers(stdout, 0, 0, &gbcfg);
3517
3518 /* RA update procedure (reject -> Detach) */
3519 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3520 local_tlli, &rai_bss, 0x7080,
3521 GPRS_SAPI_GMM, bss_nu++,
3522 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3523
3524 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3525 local_tlli, 1, imsi, sizeof(imsi),
3526 GPRS_SAPI_GMM, sgsn_nu++,
3527 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3528
3529 dump_peers(stdout, 0, 0, &gbcfg);
3530
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003531 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3532 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3533 OSMO_ASSERT(link_info);
3534 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003535
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003536 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3537 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3538 foreign_tlli, &rai_bss, cell_id,
3539 GPRS_SAPI_GMM, bss_nu++,
3540 dtap_attach_req, sizeof(dtap_attach_req));
3541
3542 dump_peers(stdout, 0, 0, &gbcfg);
3543
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003544 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3545 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3546 OSMO_ASSERT(link_info);
3547 OSMO_ASSERT(link_info != link_info2);
3548 OSMO_ASSERT(link_info->imsi_len == 0);
3549 OSMO_ASSERT(!link_info->is_deregistered);
3550 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003551
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003552 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3553 foreign_tlli, &rai_bss, cell_id,
3554 GPRS_SAPI_GMM, bss_nu++,
3555 dtap_identity_resp, sizeof(dtap_identity_resp));
3556
3557 dump_peers(stdout, 0, 0, &gbcfg);
3558
3559 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3560 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3561 OSMO_ASSERT(link_info);
3562 OSMO_ASSERT(link_info == link_info2);
3563 OSMO_ASSERT(link_info->imsi_len != 0);
3564 OSMO_ASSERT(!link_info->is_deregistered);
3565 OSMO_ASSERT(!link_info->imsi_acq_pending);
3566
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003567 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3568 foreign_tlli, 1, imsi, sizeof(imsi),
3569 GPRS_SAPI_GMM, sgsn_nu++,
3570 dtap_attach_acc, sizeof(dtap_attach_acc));
3571
3572 dump_peers(stdout, 0, 0, &gbcfg);
3573
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003574 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3575 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3576 OSMO_ASSERT(link_info);
3577 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003578 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003579
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003580 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3581 local_tlli, &rai_bss, cell_id,
3582 GPRS_SAPI_GMM, bss_nu++,
3583 dtap_attach_complete, sizeof(dtap_attach_complete));
3584
3585 dump_peers(stdout, 0, 0, &gbcfg);
3586
3587 /* Detach (MT) */
3588 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3589 local_tlli, 1, imsi, sizeof(imsi),
3590 GPRS_SAPI_GMM, sgsn_nu++,
3591 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3592
3593 dump_peers(stdout, 0, 0, &gbcfg);
3594
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003595 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3596 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003597
3598 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3599 local_tlli, &rai_bss, cell_id,
3600 GPRS_SAPI_GMM, bss_nu++,
3601 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3602
3603 dump_peers(stdout, 0, 0, &gbcfg);
3604
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003605 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3606 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3607 OSMO_ASSERT(link_info);
3608 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003609
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003610 /* Attach rejected */
3611
3612 gbproxy_delete_link_infos(peer);
3613
3614 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3615 foreign_tlli, &rai_bss, cell_id,
3616 GPRS_SAPI_GMM, bss_nu++,
3617 dtap_attach_req, sizeof(dtap_attach_req));
3618
3619 dump_peers(stdout, 0, 0, &gbcfg);
3620
3621 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3622 OSMO_ASSERT(link_info);
3623 OSMO_ASSERT(link_info->imsi_len == 0);
3624 OSMO_ASSERT(!link_info->is_deregistered);
3625 OSMO_ASSERT(link_info->imsi_acq_pending);
3626
3627 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3628 foreign_tlli, &rai_bss, cell_id,
3629 GPRS_SAPI_GMM, bss_nu++,
3630 dtap_identity_resp, sizeof(dtap_identity_resp));
3631
3632 dump_peers(stdout, 0, 0, &gbcfg);
3633
3634 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3635 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3636 OSMO_ASSERT(link_info);
3637 OSMO_ASSERT(link_info == link_info2);
3638 OSMO_ASSERT(link_info->imsi_len != 0);
3639 OSMO_ASSERT(!link_info->is_deregistered);
3640 OSMO_ASSERT(!link_info->imsi_acq_pending);
3641
3642 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3643 foreign_tlli, 1, imsi, sizeof(imsi),
3644 GPRS_SAPI_GMM, sgsn_nu++,
3645 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3646
3647 dump_peers(stdout, 0, 0, &gbcfg);
3648
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003649 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3650
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003651 /* Attach (incomplete) and Detach (MO) */
3652
3653 gbproxy_delete_link_infos(peer);
3654
3655 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3656 foreign_tlli, &rai_bss, cell_id,
3657 GPRS_SAPI_GMM, bss_nu++,
3658 dtap_attach_req, sizeof(dtap_attach_req));
3659
3660 dump_peers(stdout, 0, 0, &gbcfg);
3661
3662 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3663 OSMO_ASSERT(link_info);
3664 OSMO_ASSERT(link_info->imsi_len == 0);
3665 OSMO_ASSERT(!link_info->is_deregistered);
3666 OSMO_ASSERT(link_info->imsi_acq_pending);
3667
3668 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3669 foreign_tlli, &rai_bss, cell_id,
3670 GPRS_SAPI_GMM, bss_nu++,
3671 dtap_detach_req, sizeof(dtap_detach_req));
3672
3673 dump_peers(stdout, 0, 0, &gbcfg);
3674
3675 /* Attach (incomplete) and Detach (MT) */
3676
3677 gbproxy_delete_link_infos(peer);
3678
3679 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3680 foreign_tlli, &rai_bss, cell_id,
3681 GPRS_SAPI_GMM, bss_nu++,
3682 dtap_attach_req, sizeof(dtap_attach_req));
3683
3684 dump_peers(stdout, 0, 0, &gbcfg);
3685
3686 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3687 OSMO_ASSERT(link_info);
3688 OSMO_ASSERT(link_info->imsi_len == 0);
3689 OSMO_ASSERT(!link_info->is_deregistered);
3690 OSMO_ASSERT(link_info->imsi_acq_pending);
3691
3692 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3693 foreign_tlli, 1, imsi, sizeof(imsi),
3694 GPRS_SAPI_GMM, sgsn_nu++,
3695 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3696
3697 dump_peers(stdout, 0, 0, &gbcfg);
3698
3699 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3700 OSMO_ASSERT(link_info);
3701
3702 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3703 foreign_tlli, &rai_bss, cell_id,
3704 GPRS_SAPI_GMM, bss_nu++,
3705 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3706
3707 dump_peers(stdout, 0, 0, &gbcfg);
3708
3709 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3710 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3711 OSMO_ASSERT(link_info);
3712 OSMO_ASSERT(link_info->is_deregistered);
3713
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003714 dump_global(stdout, 0);
3715
3716 gbprox_reset(&gbcfg);
3717 gprs_ns_destroy(nsi);
3718 nsi = NULL;
3719}
3720
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003721/* TODO: Move tlv testing to libosmocore */
3722int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3723int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3724 uint8_t **value);
3725int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3726 size_t *value_len);
3727int lv_shift(uint8_t **data, size_t *data_len,
3728 uint8_t **value, size_t *value_len);
3729
3730static void check_tlv_match(uint8_t **data, size_t *data_len,
3731 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3732{
3733 uint8_t *value;
3734 size_t value_len;
3735 int rc;
3736
3737 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3738 OSMO_ASSERT(rc == 0);
3739
3740 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003741 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003742 OSMO_ASSERT(value_len == exp_len);
3743 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3744}
3745
3746static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3747 uint8_t tag, size_t len, const uint8_t *exp_val)
3748{
3749 uint8_t *value;
3750 int rc;
3751
3752 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3753 OSMO_ASSERT(rc == 0);
3754
3755 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003756 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003757 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3758}
3759
3760static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3761 size_t len, const uint8_t *exp_val)
3762{
3763 uint8_t *value;
3764 int rc;
3765
3766 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003767 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003768 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3769}
3770
3771static void check_lv_shift(uint8_t **data, size_t *data_len,
3772 size_t exp_len, const uint8_t *exp_val)
3773{
3774 uint8_t *value;
3775 size_t value_len;
3776 int rc;
3777
3778 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003779 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003780 OSMO_ASSERT(value_len == exp_len);
3781 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3782}
3783
3784static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3785 const uint8_t *test_data)
3786{
3787 uint8_t buf[300] = {0};
3788
3789 uint8_t *unchanged_ptr = buf - 1;
3790 size_t unchanged_len = 0xdead;
3791 size_t tmp_data_len = data_len;
3792 uint8_t *value = unchanged_ptr;
3793 size_t value_len = unchanged_len;
3794 uint8_t *data = buf;
3795
3796 OSMO_ASSERT(data_len <= sizeof(buf));
3797
3798 tlv_put(data, tag, len, test_data);
3799 if (data_len < len + 2) {
3800 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3801 tag, &value, &value_len));
3802 OSMO_ASSERT(tmp_data_len == 0);
3803 OSMO_ASSERT(data == buf + data_len);
3804 OSMO_ASSERT(value == unchanged_ptr);
3805 OSMO_ASSERT(value_len == unchanged_len);
3806 } else {
3807 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3808 tag, &value, &value_len));
3809 OSMO_ASSERT(value != unchanged_ptr);
3810 OSMO_ASSERT(value_len != unchanged_len);
3811 }
3812}
3813
3814static void check_tv_fixed_match_data_len(size_t data_len,
3815 uint8_t tag, size_t len,
3816 const uint8_t *test_data)
3817{
3818 uint8_t buf[300] = {0};
3819
3820 uint8_t *unchanged_ptr = buf - 1;
3821 size_t tmp_data_len = data_len;
3822 uint8_t *value = unchanged_ptr;
3823 uint8_t *data = buf;
3824
3825 OSMO_ASSERT(data_len <= sizeof(buf));
3826
3827 tv_fixed_put(data, tag, len, test_data);
3828
3829 if (data_len < len + 1) {
3830 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3831 tag, len, &value));
3832 OSMO_ASSERT(tmp_data_len == 0);
3833 OSMO_ASSERT(data == buf + data_len);
3834 OSMO_ASSERT(value == unchanged_ptr);
3835 } else {
3836 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3837 tag, len, &value));
3838 OSMO_ASSERT(value != unchanged_ptr);
3839 }
3840}
3841
3842static void check_v_fixed_shift_data_len(size_t data_len,
3843 size_t len, const uint8_t *test_data)
3844{
3845 uint8_t buf[300] = {0};
3846
3847 uint8_t *unchanged_ptr = buf - 1;
3848 size_t tmp_data_len = data_len;
3849 uint8_t *value = unchanged_ptr;
3850 uint8_t *data = buf;
3851
3852 OSMO_ASSERT(data_len <= sizeof(buf));
3853
3854 memcpy(data, test_data, len);
3855
3856 if (data_len < len) {
3857 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3858 len, &value));
3859 OSMO_ASSERT(tmp_data_len == 0);
3860 OSMO_ASSERT(data == buf + data_len);
3861 OSMO_ASSERT(value == unchanged_ptr);
3862 } else {
3863 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3864 len, &value));
3865 OSMO_ASSERT(value != unchanged_ptr);
3866 }
3867}
3868
3869static void check_lv_shift_data_len(size_t data_len,
3870 size_t len, const uint8_t *test_data)
3871{
3872 uint8_t buf[300] = {0};
3873
3874 uint8_t *unchanged_ptr = buf - 1;
3875 size_t unchanged_len = 0xdead;
3876 size_t tmp_data_len = data_len;
3877 uint8_t *value = unchanged_ptr;
3878 size_t value_len = unchanged_len;
3879 uint8_t *data = buf;
3880
3881 lv_put(data, len, test_data);
3882 if (data_len < len + 1) {
3883 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3884 &value, &value_len));
3885 OSMO_ASSERT(tmp_data_len == 0);
3886 OSMO_ASSERT(data == buf + data_len);
3887 OSMO_ASSERT(value == unchanged_ptr);
3888 OSMO_ASSERT(value_len == unchanged_len);
3889 } else {
3890 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3891 &value, &value_len));
3892 OSMO_ASSERT(value != unchanged_ptr);
3893 OSMO_ASSERT(value_len != unchanged_len);
3894 }
3895}
3896
3897static void test_tlv_shift_functions()
3898{
3899 uint8_t test_data[1024];
3900 uint8_t buf[1024];
3901 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003902 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003903 uint8_t *data;
3904 size_t data_len;
3905 const uint8_t tag = 0x1a;
3906
3907 printf("Test shift functions\n");
3908
3909 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3910 test_data[i] = (uint8_t)i;
3911
3912 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003913 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003914
3915 memset(buf, 0xee, sizeof(buf));
3916 data_end = data = buf;
3917
3918 for (i = 0; i < iterations; i++) {
3919 data_end = tlv_put(data_end, tag, len, test_data);
3920 data_end = tv_fixed_put(data_end, tag, len, test_data);
3921 /* v_fixed_put */
3922 memcpy(data_end, test_data, len);
3923 data_end += len;
3924 data_end = lv_put(data_end, len, test_data);
3925 }
3926
3927 data_len = data_end - data;
3928 OSMO_ASSERT(data_len <= sizeof(buf));
3929
3930 for (i = 0; i < iterations; i++) {
3931 check_tlv_match(&data, &data_len, tag, len, test_data);
3932 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3933 check_v_fixed_shift(&data, &data_len, len, test_data);
3934 check_lv_shift(&data, &data_len, len, test_data);
3935 }
3936
3937 OSMO_ASSERT(data == data_end);
3938
3939 /* Test at end of data */
3940
3941 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3942 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3943 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3944 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3945
3946 /* Test invalid data_len */
3947 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3948 check_tlv_match_data_len(data_len, tag, len, test_data);
3949 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3950 check_v_fixed_shift_data_len(data_len, len, test_data);
3951 check_lv_shift_data_len(data_len, len, test_data);
3952 }
3953 }
3954}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003955
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003956struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003957 struct gbproxy_peer *peer, uint32_t tlli,
3958 const uint8_t *imsi, size_t imsi_len, time_t now)
3959{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003960 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003961 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003962 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003963 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003964
3965 /* Check, whether the IMSI matches */
3966 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003967 imsi_matches = gbproxy_check_imsi(
3968 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003969 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003970 return NULL;
3971 }
3972
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003973 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003974
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003975 if (!link_info) {
3976 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003977
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003978 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003979 /* TLLI has changed somehow, adjust it */
3980 LOGP(DGPRS, LOGL_INFO,
3981 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003982 link_info->tlli.current, tlli);
3983 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003984 }
3985 }
3986
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003987 if (!link_info) {
3988 link_info = gbproxy_link_info_alloc(peer);
3989 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003990 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003991 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003992 tlli_already_known = 1;
3993 }
3994
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003995 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003996
3997 if (!tlli_already_known)
3998 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3999
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004000 gbproxy_attach_link_info(peer, now, link_info);
4001 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004002
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004003 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004004 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004005
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004006 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004007}
4008
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004009static void test_gbproxy_tlli_expire(void)
4010{
4011 struct gbproxy_config cfg = {0};
4012 struct gbproxy_peer *peer;
4013 const char *err_msg = NULL;
4014 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4015 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004016 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004017 const uint32_t tlli1 = 1234 | 0xc0000000;
4018 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004019 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004020 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004021 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004022
4023 printf("Test TLLI info expiry\n\n");
4024
4025 gbproxy_init_config(&cfg);
4026
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004027 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4028 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004029 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4030 err_msg);
4031 OSMO_ASSERT(err_msg == NULL);
4032 }
4033
4034 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004035 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004036
4037 printf("Test TLLI replacement:\n");
4038
4039 cfg.tlli_max_len = 0;
4040 cfg.tlli_max_age = 0;
4041 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004042 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004043
4044 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004045 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004046 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004047 OSMO_ASSERT(link_info);
4048 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004049 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004050
4051 /* replace the old entry */
4052 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004053 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004054 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004055 OSMO_ASSERT(link_info);
4056 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004057 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004058
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004059 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004060
4061 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004062 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4063 OSMO_ASSERT(link_info);
4064 OSMO_ASSERT(link_info->tlli.current == tlli2);
4065 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4066 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004067
4068 printf("\n");
4069
4070 gbproxy_peer_free(peer);
4071 }
4072
4073 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004074 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004075
4076 printf("Test IMSI replacement:\n");
4077
4078 cfg.tlli_max_len = 0;
4079 cfg.tlli_max_age = 0;
4080 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004081 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004082
4083 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004084 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004085 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004086 OSMO_ASSERT(link_info);
4087 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004088 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004089
4090 /* try to replace the old entry */
4091 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004092 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004093 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004094 OSMO_ASSERT(link_info);
4095 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004096 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004097
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004098 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004099
4100 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004101 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4102 OSMO_ASSERT(!link_info);
4103 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4104 OSMO_ASSERT(link_info);
4105 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004106
4107 printf("\n");
4108
4109 gbproxy_peer_free(peer);
4110 }
4111
4112 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004113 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004114 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004115
4116 printf("Test TLLI expiry, max_len == 1:\n");
4117
4118 cfg.tlli_max_len = 1;
4119 cfg.tlli_max_age = 0;
4120 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004121 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004122
4123 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004124 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004125 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004126
4127 /* replace the old entry */
4128 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004129 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004130 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004131
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004132 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004133 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004134 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004135
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004136 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004137
4138 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004139 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4140 OSMO_ASSERT(!link_info);
4141 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4142 OSMO_ASSERT(link_info);
4143 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004144
4145 printf("\n");
4146
4147 gbproxy_peer_free(peer);
4148 }
4149
4150 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004151 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004152 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004153
4154 printf("Test TLLI expiry, max_age == 1:\n");
4155
4156 cfg.tlli_max_len = 0;
4157 cfg.tlli_max_age = 1;
4158 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004159 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004160
4161 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004162 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004163 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004164
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004165 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004166 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004167 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004168 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004169
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004170 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004171 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004172 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004173
4174 dump_peers(stdout, 2, now + 2, &cfg);
4175
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004176 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004177 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4178 OSMO_ASSERT(!link_info);
4179 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4180 OSMO_ASSERT(link_info);
4181 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004182
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004183 printf("\n");
4184
4185 gbproxy_peer_free(peer);
4186 }
4187
4188 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004189 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004190 int num_removed;
4191
4192 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4193
4194 cfg.tlli_max_len = 0;
4195 cfg.tlli_max_age = 1;
4196 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004197 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004198
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004199 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004200 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004201 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004202
4203 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004204 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004205 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004206 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004207
4208 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004209 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004210 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004211 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004212
4213 dump_peers(stdout, 2, now + 2, &cfg);
4214
4215 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004216 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004217 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004218 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004219
4220 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004221
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004222 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004223 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4224 OSMO_ASSERT(!link_info);
4225 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4226 OSMO_ASSERT(!link_info);
4227 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4228 OSMO_ASSERT(link_info);
4229 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004230
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004231 printf("\n");
4232
4233 gbproxy_peer_free(peer);
4234 }
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004235 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4236 gbprox_reset(&cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004237}
4238
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004239static void test_gbproxy_imsi_matching(void)
4240{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004241 const char *err_msg = NULL;
4242 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4243 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4244 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4245 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4246 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4247 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4248 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4249 const char *filter_re1 = ".*";
4250 const char *filter_re2 = "^1234";
4251 const char *filter_re3 = "^4321";
4252 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004253 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004254
4255 printf("=== Test IMSI/TMSI matching ===\n\n");
4256
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004257 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004258
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004259 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4260 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004261
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004262 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4263 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004264
4265 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004266 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004267 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004268 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004269
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004270 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4271 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004272
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004273 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4274 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004275
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004276 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4277 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004278
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004279 gbproxy_clear_patch_filter(&match);
4280 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004281
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004282 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4283 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004284
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004285 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4286 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004287 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004288 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004289 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004290 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4291 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4292 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4293 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4294 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004295
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004296 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4297 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004298
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004299 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4300 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4301 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4302 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4303 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4304 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4305 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004306
4307 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004308
4309 gbproxy_clear_patch_filter(&match);
4310 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004311}
4312
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004313static struct log_info_cat gprs_categories[] = {
4314 [DGPRS] = {
4315 .name = "DGPRS",
4316 .description = "GPRS Packet Service",
4317 .enabled = 1, .loglevel = LOGL_DEBUG,
4318 },
4319 [DNS] = {
4320 .name = "DNS",
4321 .description = "GPRS Network Service (NS)",
4322 .enabled = 1, .loglevel = LOGL_INFO,
4323 },
4324 [DBSSGP] = {
4325 .name = "DBSSGP",
4326 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4327 .enabled = 1, .loglevel = LOGL_DEBUG,
4328 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004329};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004330
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004331static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004332 .cat = gprs_categories,
4333 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004334};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004335
4336int main(int argc, char **argv)
4337{
4338 osmo_init_logging(&info);
4339 log_set_use_color(osmo_stderr_target, 0);
4340 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02004341 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004342
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004343 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004344 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4345 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004346
4347 rate_ctr_init(NULL);
4348
4349 setlinebuf(stdout);
4350
4351 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004352 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004353 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004354 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004355 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004356 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004357 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004358 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004359 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004360 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004361 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004362 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004363 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004364 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004365
4366 exit(EXIT_SUCCESS);
4367}