blob: 566432a313bb70a9b13f06a9b2800a9812d02e79 [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);
1560 struct expect_result *er;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001561
1562 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001563
1564 bssgp_nsi = nsi;
1565 gbcfg.nsi = bssgp_nsi;
1566 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001567 gbcfg.core_mcc = 123;
1568 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001569 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001570 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001571 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001572
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001573 configure_sgsn_peer(&sgsn_peer);
1574 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001575
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001576 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
1577 patch_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001578 fprintf(stderr, "Failed to compile RE '%s': %s\n",
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001579 patch_re, err_msg);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001580 exit(1);
1581 }
1582
1583
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001584 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001585 printf("--- Initialise SGSN ---\n\n");
1586
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001587 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001588 gprs_dump_nsi(nsi);
1589
1590 printf("--- Initialise BSS 1 ---\n\n");
1591
1592 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001593
1594 received_messages = &rcv_list;
1595
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001596 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1597 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001598 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001599
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001600 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001601 OSMO_ASSERT(peer != NULL);
1602
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001603 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1604
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001605 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1606
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001607 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1608
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001609 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001610
1611 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1612
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001613 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001614
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001615 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1616
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001617 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001618 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001619
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001620 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1621 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1622
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001623 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1624
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001625 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1626 foreign_tlli, &rai_bss, cell_id,
1627 GPRS_SAPI_GMM, 0,
1628 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001629
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001630 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001631 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001632
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001633 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1634 foreign_tlli, 0, NULL, 0,
1635 GPRS_SAPI_GMM, 0,
1636 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001637
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001638 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1639
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001640 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1641 foreign_tlli, &rai_bss, cell_id,
1642 GPRS_SAPI_GMM, 3,
1643 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001644
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001645 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1646
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001647 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1648 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1649
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001650 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1651 foreign_tlli, 1, imsi, sizeof(imsi),
1652 GPRS_SAPI_GMM, 1,
1653 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001654
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001655 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1656
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001657 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1658
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001659 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1660 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1661 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1662
1663 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1664 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1665 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1666
1667 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1668 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1669 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1670
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001671 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1672 OSMO_ASSERT(link_info);
1673 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1674 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1675 OSMO_ASSERT(!link_info->tlli.bss_validated);
1676 OSMO_ASSERT(!link_info->tlli.net_validated);
1677 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1678 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1679 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1680 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001681
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001682 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1683 local_tlli, &rai_bss, cell_id,
1684 GPRS_SAPI_GMM, 4,
1685 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001686
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001687 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1688
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001689 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1690
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001691 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1692 OSMO_ASSERT(link_info);
1693 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1694 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1695 OSMO_ASSERT(link_info->tlli.bss_validated);
1696 OSMO_ASSERT(!link_info->tlli.net_validated);
1697 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1698 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1699 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1700 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001701
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001702 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001703 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1704 local_tlli, &rai_bss, cell_id,
1705 GPRS_SAPI_GMM, 3,
1706 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001707
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001708 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1709
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001710 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1711
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001712 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1713 OSMO_ASSERT(link_info);
1714 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1715 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1716 OSMO_ASSERT(link_info->tlli.bss_validated);
1717 OSMO_ASSERT(!link_info->tlli.net_validated);
1718 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1719 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1720 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1721 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001722
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001723 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1724 local_tlli, 1, imsi, sizeof(imsi),
1725 GPRS_SAPI_GMM, 2,
1726 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001727
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001728 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1729
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001730 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1731
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001732 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1733 OSMO_ASSERT(link_info);
1734 OSMO_ASSERT(link_info->tlli.assigned == 0);
1735 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1736 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1737 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001738
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001739 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001740 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1741 local_tlli, &rai_bss, cell_id,
1742 GPRS_SAPI_GMM, 3,
1743 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001744
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001745 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1746 OSMO_ASSERT(er->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
1747
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001748 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1749
Jacob Erlbeck73685282014-05-23 20:48:07 +02001750 gbcfg.core_apn[0] = 0;
1751 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001752
1753 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001754 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1755 local_tlli, &rai_bss, cell_id,
1756 GPRS_SAPI_GMM, 3,
1757 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001758
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001759 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1760 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1761
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001762 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1763
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001764 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001765
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001766 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001767 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1768 local_tlli, &rai_bss, cell_id,
1769 GPRS_SAPI_GMM, 6,
1770 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001771
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001772 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1773
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001774 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1775 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1776
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001777 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1778 local_tlli, 1, imsi, sizeof(imsi),
1779 GPRS_SAPI_GMM, 5,
1780 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001781
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001782 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1783
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001784 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001785
1786 printf("--- RA update ---\n\n");
1787
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001788 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1789 foreign_tlli, &rai_bss, 0x7080,
1790 GPRS_SAPI_GMM, 5,
1791 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001792
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001793 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1794
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001795 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1796
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001797 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1798 foreign_tlli, 1, imsi, sizeof(imsi),
1799 GPRS_SAPI_GMM, 6,
1800 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001801
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001802 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1803
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001804 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1805
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001806 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001807 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1808 local_tlli, &rai_bss, cell_id,
1809 GPRS_SAPI_GMM, 3,
1810 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001811
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001812 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1813 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1814
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001815 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1816
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001817 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001818
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001819 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001820 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1821 local_tlli, &rai_bss, cell_id,
1822 GPRS_SAPI_GMM, 6,
1823 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001824
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001825 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1826
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001827 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1828
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001829 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001830 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001831
1832 printf("--- Bad cases ---\n\n");
1833
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001834 /* The RAI in the Attach Request message differs from the RAI in the
1835 * BSSGP message, only patch the latter */
1836
1837 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1838 foreign_tlli2, &rai_bss, cell_id,
1839 GPRS_SAPI_GMM, 0,
1840 dtap_attach_req2, sizeof(dtap_attach_req2));
1841
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001842 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1843
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001844 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1845
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001846 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001847 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1848 local_tlli, &rai_bss, cell_id,
1849 GPRS_SAPI_GMM, 3,
1850 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001851
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001852 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1853
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001854 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001855 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001856
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001857 /* TODO: The following breaks with the current libosmocore, enable it
1858 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1859 * is integrated */
1860 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1861 OSMO_ASSERT(expect_msg());
1862
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001863 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001864 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001865
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001866 OSMO_ASSERT(!expect_msg());
1867 received_messages = NULL;
1868
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001869 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001870 gprs_ns_destroy(nsi);
1871 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001872}
1873
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001874static void test_gbproxy_ptmsi_assignment()
1875{
1876 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1877 struct sockaddr_in bss_peer[1] = {{0},};
1878 struct sockaddr_in sgsn_peer= {0};
1879 struct gprs_ra_id rai_bss =
1880 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1881 struct gprs_ra_id rai_unknown =
1882 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1883 uint16_t cell_id = 0x1234;
1884
1885 const uint32_t ptmsi = 0xefe2b700;
1886 const uint32_t local_tlli = 0xefe2b700;
1887
1888 const uint32_t foreign_tlli1 = 0x8000dead;
1889 const uint32_t foreign_tlli2 = 0x8000beef;
1890
1891 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1892 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1893
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001894 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001895 struct gbproxy_peer *peer;
1896 unsigned bss_nu = 0;
1897 unsigned sgsn_nu = 0;
1898
1899 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1900
1901 bssgp_nsi = nsi;
1902 gbcfg.nsi = bssgp_nsi;
1903 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1904 gbcfg.core_mcc = 0;
1905 gbcfg.core_mnc = 0;
1906 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1907 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1908 gbcfg.patch_ptmsi = 0;
1909 gbcfg.bss_ptmsi_state = 0;
1910 gbcfg.sgsn_tlli_state = 1;
1911
1912 configure_sgsn_peer(&sgsn_peer);
1913 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1914
1915 printf("=== %s ===\n", __func__);
1916 printf("--- Initialise SGSN ---\n\n");
1917
1918 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1919
1920 printf("--- Initialise BSS 1 ---\n\n");
1921
1922 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1923 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1924
1925 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1926 OSMO_ASSERT(peer != NULL);
1927
1928 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1929
1930 gprs_dump_nsi(nsi);
1931 dump_global(stdout, 0);
1932 dump_peers(stdout, 0, 0, &gbcfg);
1933
1934 printf("--- Establish first LLC connection ---\n\n");
1935
1936 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1937 foreign_tlli1, &rai_unknown, cell_id,
1938 GPRS_SAPI_GMM, bss_nu++,
1939 dtap_attach_req, sizeof(dtap_attach_req));
1940
1941 dump_peers(stdout, 0, 0, &gbcfg);
1942
1943 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1944 foreign_tlli1, 0, NULL, 0,
1945 GPRS_SAPI_GMM, sgsn_nu++,
1946 dtap_identity_req, sizeof(dtap_identity_req));
1947
1948 dump_peers(stdout, 0, 0, &gbcfg);
1949
1950 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1951 foreign_tlli1, &rai_bss, cell_id,
1952 GPRS_SAPI_GMM, bss_nu++,
1953 dtap_identity_resp, sizeof(dtap_identity_resp));
1954
1955 dump_peers(stdout, 0, 0, &gbcfg);
1956
1957 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1958 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1959 GPRS_SAPI_GMM, sgsn_nu++,
1960 dtap_attach_acc, sizeof(dtap_attach_acc));
1961
1962 dump_peers(stdout, 0, 0, &gbcfg);
1963
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001964 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1965 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1966 OSMO_ASSERT(link_info);
1967 OSMO_ASSERT(link_info == link_info2);
1968 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1969 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1970 OSMO_ASSERT(!link_info->tlli.bss_validated);
1971 OSMO_ASSERT(!link_info->tlli.net_validated);
1972 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001973
1974 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1975 local_tlli, &rai_bss, cell_id,
1976 GPRS_SAPI_GMM, bss_nu++,
1977 dtap_attach_complete, sizeof(dtap_attach_complete));
1978
1979 dump_peers(stdout, 0, 0, &gbcfg);
1980
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001981 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1982 OSMO_ASSERT(link_info);
1983 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1984 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1985 OSMO_ASSERT(link_info->tlli.bss_validated);
1986 OSMO_ASSERT(!link_info->tlli.net_validated);
1987 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001988
1989
1990 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1991 local_tlli, 1, imsi1, sizeof(imsi1),
1992 GPRS_SAPI_GMM, sgsn_nu++,
1993 dtap_gmm_information, sizeof(dtap_gmm_information));
1994
1995 dump_peers(stdout, 0, 0, &gbcfg);
1996
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001997 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1998 OSMO_ASSERT(link_info);
1999 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2000 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002001
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002002 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2003 OSMO_ASSERT(link_info == link_info2);
2004 OSMO_ASSERT(link_info->tlli.assigned == 0);
2005 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2006 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002007
2008 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2009
2010 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2011 foreign_tlli2, &rai_unknown, cell_id,
2012 GPRS_SAPI_GMM, bss_nu++,
2013 dtap_attach_req, sizeof(dtap_attach_req));
2014
2015 dump_peers(stdout, 0, 0, &gbcfg);
2016
2017 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2018 foreign_tlli2, 0, NULL, 0,
2019 GPRS_SAPI_GMM, sgsn_nu++,
2020 dtap_identity_req, sizeof(dtap_identity_req));
2021
2022 dump_peers(stdout, 0, 0, &gbcfg);
2023
2024 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2025 foreign_tlli2, &rai_bss, cell_id,
2026 GPRS_SAPI_GMM, bss_nu++,
2027 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2028
2029 dump_peers(stdout, 0, 0, &gbcfg);
2030
2031 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2032 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2033 GPRS_SAPI_GMM, sgsn_nu++,
2034 dtap_attach_acc, sizeof(dtap_attach_acc));
2035
2036 dump_peers(stdout, 0, 0, &gbcfg);
2037
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002038 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2039 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2040 OSMO_ASSERT(link_info);
2041 OSMO_ASSERT(link_info == link_info2);
2042 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2043 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2044 OSMO_ASSERT(!link_info->tlli.bss_validated);
2045 OSMO_ASSERT(!link_info->tlli.net_validated);
2046 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002047
2048 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2049 local_tlli, &rai_bss, cell_id,
2050 GPRS_SAPI_GMM, bss_nu++,
2051 dtap_attach_complete, sizeof(dtap_attach_complete));
2052
2053 dump_peers(stdout, 0, 0, &gbcfg);
2054
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002055 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2056 OSMO_ASSERT(link_info);
2057 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2058 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2059 OSMO_ASSERT(link_info->tlli.bss_validated);
2060 OSMO_ASSERT(!link_info->tlli.net_validated);
2061 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002062
2063 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2064 local_tlli, 1, imsi2, sizeof(imsi2),
2065 GPRS_SAPI_GMM, sgsn_nu++,
2066 dtap_gmm_information, sizeof(dtap_gmm_information));
2067
2068 dump_peers(stdout, 0, 0, &gbcfg);
2069
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002070 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2071 OSMO_ASSERT(link_info);
2072 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2073 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002074
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002075 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2076 OSMO_ASSERT(link_info == link_info2);
2077 OSMO_ASSERT(link_info->tlli.assigned == 0);
2078 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2079 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002080
2081 dump_global(stdout, 0);
2082
2083 gbprox_reset(&gbcfg);
2084 gprs_ns_destroy(nsi);
2085 nsi = NULL;
2086}
2087
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002088static void test_gbproxy_ptmsi_patching()
2089{
2090 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2091 struct sockaddr_in bss_peer[1] = {{0},};
2092 struct sockaddr_in sgsn_peer= {0};
2093 struct gprs_ra_id rai_bss =
2094 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2095 struct gprs_ra_id rai_sgsn =
2096 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002097 struct gprs_ra_id rai_wrong_mcc_sgsn =
2098 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002099 struct gprs_ra_id rai_unknown =
2100 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2101 uint16_t cell_id = 0x1234;
2102
2103 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002104 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2105 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002106 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002107 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2108 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002109 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002110 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002111
2112 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002113 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2114 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002115 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002116 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2117 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002118 const uint32_t foreign_bss_tlli = 0x8000dead;
2119
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002120
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002121 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002122 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002123 struct gbproxy_peer *peer;
2124 unsigned bss_nu = 0;
2125 unsigned sgsn_nu = 0;
2126
2127 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002128 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2129 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2130 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2131 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2132 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002133
2134 bssgp_nsi = nsi;
2135 gbcfg.nsi = bssgp_nsi;
2136 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2137 gbcfg.core_mcc = 123;
2138 gbcfg.core_mnc = 456;
2139 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2140 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2141 gbcfg.patch_ptmsi = 1;
2142 gbcfg.bss_ptmsi_state = 0;
2143 gbcfg.sgsn_tlli_state = 1;
2144
2145 configure_sgsn_peer(&sgsn_peer);
2146 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2147
2148 printf("=== %s ===\n", __func__);
2149 printf("--- Initialise SGSN ---\n\n");
2150
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002151 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002152
2153 printf("--- Initialise BSS 1 ---\n\n");
2154
2155 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2156 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2157
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002158 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002159 OSMO_ASSERT(peer != NULL);
2160
2161 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2162
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002163 gprs_dump_nsi(nsi);
2164 dump_global(stdout, 0);
2165 dump_peers(stdout, 0, 0, &gbcfg);
2166
2167 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2168
2169 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2170 foreign_bss_tlli, &rai_unknown, cell_id,
2171 GPRS_SAPI_GMM, bss_nu++,
2172 dtap_attach_req, sizeof(dtap_attach_req));
2173
2174 dump_peers(stdout, 0, 0, &gbcfg);
2175
2176 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2177 random_sgsn_tlli, 0, NULL, 0,
2178 GPRS_SAPI_GMM, sgsn_nu++,
2179 dtap_identity_req, sizeof(dtap_identity_req));
2180
2181 dump_peers(stdout, 0, 0, &gbcfg);
2182
2183 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2184 foreign_bss_tlli, &rai_bss, cell_id,
2185 GPRS_SAPI_GMM, bss_nu++,
2186 dtap_identity_resp, sizeof(dtap_identity_resp));
2187
2188 dump_peers(stdout, 0, 0, &gbcfg);
2189
2190 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2191 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2192 GPRS_SAPI_GMM, sgsn_nu++,
2193 dtap_attach_acc, sizeof(dtap_attach_acc));
2194
2195 dump_peers(stdout, 0, 0, &gbcfg);
2196
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002197 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2198 OSMO_ASSERT(link_info);
2199 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2200 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2201 OSMO_ASSERT(!link_info->tlli.bss_validated);
2202 OSMO_ASSERT(!link_info->tlli.net_validated);
2203 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2204 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2205 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2206 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2207 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2208 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002209
2210 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2211 local_bss_tlli, &rai_bss, cell_id,
2212 GPRS_SAPI_GMM, bss_nu++,
2213 dtap_attach_complete, sizeof(dtap_attach_complete));
2214
2215 dump_peers(stdout, 0, 0, &gbcfg);
2216
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002217 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2218 OSMO_ASSERT(link_info);
2219 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2220 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2221 OSMO_ASSERT(link_info->tlli.bss_validated);
2222 OSMO_ASSERT(!link_info->tlli.net_validated);
2223 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2224 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2225 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2226 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002227
2228 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2229 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2230 GPRS_SAPI_GMM, sgsn_nu++,
2231 dtap_gmm_information, sizeof(dtap_gmm_information));
2232
2233 dump_peers(stdout, 0, 0, &gbcfg);
2234
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002235 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2236 OSMO_ASSERT(link_info);
2237 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2238 OSMO_ASSERT(link_info->tlli.assigned == 0);
2239 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2240 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002241
Jacob Erlbeck82add782014-09-05 18:08:12 +02002242 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2243 local_bss_tlli, &rai_bss, cell_id,
2244 GPRS_SAPI_GMM, bss_nu++,
2245 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2246
2247 dump_peers(stdout, 0, 0, &gbcfg);
2248
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002249 /* Non-DTAP */
2250 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2251 local_bss_tlli, &rai_bss, cell_id,
2252 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2253
2254 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2255 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2256 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2257
2258 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2259 local_bss_tlli, &rai_bss, cell_id,
2260 llc_ui_ll11_dns_query_ul,
2261 sizeof(llc_ui_ll11_dns_query_ul));
2262
2263 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2264 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2265 llc_ui_ll11_dns_resp_dl,
2266 sizeof(llc_ui_ll11_dns_resp_dl));
2267
2268 dump_peers(stdout, 0, 0, &gbcfg);
2269
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002270 /* Repeated RA Update Requests */
2271 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2272 local_bss_tlli, &rai_bss, 0x7080,
2273 GPRS_SAPI_GMM, bss_nu++,
2274 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2275
2276 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2277 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2278 GPRS_SAPI_GMM, sgsn_nu++,
2279 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2280
2281 dump_peers(stdout, 0, 0, &gbcfg);
2282
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002283 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2284 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2285 OSMO_ASSERT(link_info);
2286 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2287 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2288 OSMO_ASSERT(!link_info->tlli.bss_validated);
2289 OSMO_ASSERT(!link_info->tlli.net_validated);
2290 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2291 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2292 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2293 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2294 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2295 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002296
2297 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2298 local_bss_tlli2, &rai_bss, 0x7080,
2299 GPRS_SAPI_GMM, bss_nu++,
2300 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2301
2302 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2303 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2304 GPRS_SAPI_GMM, sgsn_nu++,
2305 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2306
2307 dump_peers(stdout, 0, 0, &gbcfg);
2308
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002309 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2310 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2311 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2312 OSMO_ASSERT(link_info);
2313 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2314 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2315 OSMO_ASSERT(!link_info->tlli.bss_validated);
2316 OSMO_ASSERT(!link_info->tlli.net_validated);
2317 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2318 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2319 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2320 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2321 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2322 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002323
2324 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2325 local_bss_tlli3, &rai_bss, 0x7080,
2326 GPRS_SAPI_GMM, bss_nu++,
2327 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2328
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002329 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002330
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002331 OSMO_ASSERT(link_info);
2332 OSMO_ASSERT(link_info->tlli.bss_validated);
2333 OSMO_ASSERT(!link_info->tlli.net_validated);
2334 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2335 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002336
2337 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2338 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2339 GPRS_SAPI_GMM, sgsn_nu++,
2340 dtap_gmm_information, sizeof(dtap_gmm_information));
2341
2342 dump_peers(stdout, 0, 0, &gbcfg);
2343
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002344 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2345 OSMO_ASSERT(link_info);
2346 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2347 OSMO_ASSERT(link_info->tlli.assigned == 0);
2348 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2349 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002350
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002351 /* Other messages */
2352 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002353 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002354
2355 dump_peers(stdout, 0, 0, &gbcfg);
2356
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002357 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
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_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002362
2363 dump_peers(stdout, 0, 0, &gbcfg);
2364
2365 /* Bad case: Invalid BVCI */
2366 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002367 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002368 dump_global(stdout, 0);
2369
2370 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002371 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002372
2373 dump_global(stdout, 0);
2374
2375 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002376 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002377 &rai_wrong_mcc_sgsn);
2378
2379 dump_global(stdout, 0);
2380
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002381 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2382 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2383 unknown_sgsn_tlli, 1, NULL, 0,
2384 GPRS_SAPI_GMM, 2,
2385 dtap_gmm_information, sizeof(dtap_gmm_information));
2386
2387 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2388 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2389 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2390 GPRS_SAPI_GMM, 3,
2391 dtap_gmm_information, sizeof(dtap_gmm_information));
2392
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002393 /* Detach */
2394 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002395 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002396 GPRS_SAPI_GMM, bss_nu++,
2397 dtap_detach_req, sizeof(dtap_detach_req));
2398
2399 dump_peers(stdout, 0, 0, &gbcfg);
2400
2401 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002402 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002403 GPRS_SAPI_GMM, sgsn_nu++,
2404 dtap_detach_acc, sizeof(dtap_detach_acc));
2405
2406 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002407
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002408 dump_global(stdout, 0);
2409
2410 gbprox_reset(&gbcfg);
2411 gprs_ns_destroy(nsi);
2412 nsi = NULL;
2413}
2414
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002415static void test_gbproxy_imsi_acquisition()
2416{
2417 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2418 struct sockaddr_in bss_peer[1] = {{0},};
2419 struct sockaddr_in sgsn_peer= {0};
2420 struct gprs_ra_id rai_bss =
2421 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2422 struct gprs_ra_id rai_sgsn =
2423 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2424 struct gprs_ra_id rai_wrong_mcc_sgsn =
2425 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2426 struct gprs_ra_id rai_unknown =
2427 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2428 uint16_t cell_id = 0x1234;
2429
2430 const uint32_t sgsn_ptmsi = 0xefe2b700;
2431 const uint32_t local_sgsn_tlli = 0xefe2b700;
2432 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002433 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002434
2435 const uint32_t bss_ptmsi = 0xc00f7304;
2436 const uint32_t local_bss_tlli = 0xc00f7304;
2437 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002438 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002439
2440 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002441 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002442 struct gbproxy_peer *peer;
2443 unsigned bss_nu = 0;
2444 unsigned sgsn_nu = 0;
2445
2446 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2447
2448 bssgp_nsi = nsi;
2449 gbcfg.nsi = bssgp_nsi;
2450 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2451 gbcfg.core_mcc = 123;
2452 gbcfg.core_mnc = 456;
2453 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2454 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2455 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002456 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002457 gbcfg.bss_ptmsi_state = 0;
2458 gbcfg.sgsn_tlli_state = 1;
2459
2460 configure_sgsn_peer(&sgsn_peer);
2461 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2462
2463 printf("=== %s ===\n", __func__);
2464 printf("--- Initialise SGSN ---\n\n");
2465
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002466 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002467
2468 printf("--- Initialise BSS 1 ---\n\n");
2469
2470 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2471 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2472
2473 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2474 OSMO_ASSERT(peer != NULL);
2475
2476 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2477
2478 gprs_dump_nsi(nsi);
2479 dump_global(stdout, 0);
2480 dump_peers(stdout, 0, 0, &gbcfg);
2481
2482 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2483
2484 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002485 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002486 GPRS_SAPI_GMM, bss_nu++,
2487 dtap_attach_req, sizeof(dtap_attach_req));
2488
2489 dump_peers(stdout, 0, 0, &gbcfg);
2490
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002491 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2492 foreign_bss_tlli, &rai_bss, cell_id,
2493 GPRS_SAPI_GMM, bss_nu++,
2494 dtap_identity_resp, sizeof(dtap_identity_resp));
2495
2496 dump_peers(stdout, 0, 0, &gbcfg);
2497
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002498 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2499 random_sgsn_tlli, 0, NULL, 0,
2500 GPRS_SAPI_GMM, sgsn_nu++,
2501 dtap_identity_req, sizeof(dtap_identity_req));
2502
2503 dump_peers(stdout, 0, 0, &gbcfg);
2504
2505 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2506 foreign_bss_tlli, &rai_bss, cell_id,
2507 GPRS_SAPI_GMM, bss_nu++,
2508 dtap_identity_resp, sizeof(dtap_identity_resp));
2509
2510 dump_peers(stdout, 0, 0, &gbcfg);
2511
2512 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2513 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2514 GPRS_SAPI_GMM, sgsn_nu++,
2515 dtap_attach_acc, sizeof(dtap_attach_acc));
2516
2517 dump_peers(stdout, 0, 0, &gbcfg);
2518
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002519 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2520 OSMO_ASSERT(link_info);
2521 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2522 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2523 OSMO_ASSERT(!link_info->tlli.bss_validated);
2524 OSMO_ASSERT(!link_info->tlli.net_validated);
2525 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2526 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2527 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2528 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2529 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2530 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002531
2532 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2533 local_bss_tlli, &rai_bss, cell_id,
2534 GPRS_SAPI_GMM, bss_nu++,
2535 dtap_attach_complete, sizeof(dtap_attach_complete));
2536
2537 dump_peers(stdout, 0, 0, &gbcfg);
2538
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002539 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2540 OSMO_ASSERT(link_info);
2541 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2542 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2543 OSMO_ASSERT(link_info->tlli.bss_validated);
2544 OSMO_ASSERT(!link_info->tlli.net_validated);
2545 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2546 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2547 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2548 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002549
2550 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2551 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2552 GPRS_SAPI_GMM, sgsn_nu++,
2553 dtap_gmm_information, sizeof(dtap_gmm_information));
2554
2555 dump_peers(stdout, 0, 0, &gbcfg);
2556
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002557 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2558 OSMO_ASSERT(link_info);
2559 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2560 OSMO_ASSERT(link_info->tlli.assigned == 0);
2561 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2562 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002563
2564 /* Non-DTAP */
2565 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2566 local_bss_tlli, &rai_bss, cell_id,
2567 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2568
2569 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2570 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2571 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2572
2573 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2574 local_bss_tlli, &rai_bss, cell_id,
2575 llc_ui_ll11_dns_query_ul,
2576 sizeof(llc_ui_ll11_dns_query_ul));
2577
2578 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2579 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2580 llc_ui_ll11_dns_resp_dl,
2581 sizeof(llc_ui_ll11_dns_resp_dl));
2582
2583 dump_peers(stdout, 0, 0, &gbcfg);
2584
2585 /* Other messages */
2586 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2587 local_bss_tlli, 1, 12);
2588
2589 dump_peers(stdout, 0, 0, &gbcfg);
2590
2591 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2592 local_sgsn_tlli, 1, 12);
2593
2594 dump_peers(stdout, 0, 0, &gbcfg);
2595
2596 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2597
2598 dump_peers(stdout, 0, 0, &gbcfg);
2599
2600 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2601
2602 dump_peers(stdout, 0, 0, &gbcfg);
2603
2604 /* Bad case: Invalid BVCI */
2605 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2606 local_bss_tlli, 1, 12);
2607 dump_global(stdout, 0);
2608
2609 /* Bad case: Invalid RAI */
2610 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2611
2612 dump_global(stdout, 0);
2613
2614 /* Bad case: Invalid MCC (LAC ok) */
2615 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2616 &rai_wrong_mcc_sgsn);
2617
2618 dump_global(stdout, 0);
2619
2620 /* Detach */
2621 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2622 local_bss_tlli, &rai_bss, cell_id,
2623 GPRS_SAPI_GMM, bss_nu++,
2624 dtap_detach_req, sizeof(dtap_detach_req));
2625
2626 dump_peers(stdout, 0, 0, &gbcfg);
2627
2628 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2629 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2630 GPRS_SAPI_GMM, sgsn_nu++,
2631 dtap_detach_acc, sizeof(dtap_detach_acc));
2632
2633 dump_peers(stdout, 0, 0, &gbcfg);
2634
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002635 /* RA Update request */
2636
2637 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2638 foreign_bss_tlli, &rai_unknown, 0x7080,
2639 GPRS_SAPI_GMM, bss_nu++,
2640 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2641
2642 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2643 foreign_bss_tlli, &rai_bss, cell_id,
2644 GPRS_SAPI_GMM, bss_nu++,
2645 dtap_identity_resp, sizeof(dtap_identity_resp));
2646
2647 dump_peers(stdout, 0, 0, &gbcfg);
2648
2649 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2650 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2651 GPRS_SAPI_GMM, sgsn_nu++,
2652 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2653
2654 dump_peers(stdout, 0, 0, &gbcfg);
2655
2656 /* Detach */
2657
2658 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2659 local_bss_tlli, &rai_bss, cell_id,
2660 GPRS_SAPI_GMM, bss_nu++,
2661 dtap_detach_req, sizeof(dtap_detach_req));
2662
2663 dump_peers(stdout, 0, 0, &gbcfg);
2664
2665 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2666 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2667 GPRS_SAPI_GMM, sgsn_nu++,
2668 dtap_detach_acc, sizeof(dtap_detach_acc));
2669
2670 dump_peers(stdout, 0, 0, &gbcfg);
2671
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002672 /* Special case: Repeated Attach Requests */
2673
2674 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2675 foreign_bss_tlli, &rai_unknown, cell_id,
2676 GPRS_SAPI_GMM, bss_nu++,
2677 dtap_attach_req, sizeof(dtap_attach_req));
2678
2679 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2680 foreign_bss_tlli, &rai_unknown, cell_id,
2681 GPRS_SAPI_GMM, bss_nu++,
2682 dtap_attach_req, sizeof(dtap_attach_req));
2683
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002684 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2685 foreign_bss_tlli, &rai_bss, cell_id,
2686 GPRS_SAPI_GMM, bss_nu++,
2687 dtap_detach_req, sizeof(dtap_detach_req));
2688
2689 dump_peers(stdout, 0, 0, &gbcfg);
2690
2691 /* Special case: Detach from an unknown TLLI */
2692
2693 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2694 other_bss_tlli, &rai_bss, cell_id,
2695 GPRS_SAPI_GMM, bss_nu++,
2696 dtap_detach_req, sizeof(dtap_detach_req));
2697
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002698 dump_peers(stdout, 0, 0, &gbcfg);
2699
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002700 /* Special case: Repeated RA Update Requests */
2701
2702 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2703 foreign_bss_tlli, &rai_unknown, 0x7080,
2704 GPRS_SAPI_GMM, bss_nu++,
2705 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2706
2707 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2708 foreign_bss_tlli, &rai_unknown, 0x7080,
2709 GPRS_SAPI_GMM, bss_nu++,
2710 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2711
2712 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2713 foreign_bss_tlli, &rai_bss, cell_id,
2714 GPRS_SAPI_GMM, bss_nu++,
2715 dtap_detach_req, sizeof(dtap_detach_req));
2716
2717 dump_peers(stdout, 0, 0, &gbcfg);
2718
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002719 dump_global(stdout, 0);
2720
2721 gbprox_reset(&gbcfg);
2722 gprs_ns_destroy(nsi);
2723 nsi = NULL;
2724}
2725
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002726static void test_gbproxy_secondary_sgsn()
2727{
2728 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2729 struct sockaddr_in bss_peer[1] = {{0},};
2730 struct sockaddr_in sgsn_peer[2]= {{0},};
2731 struct gprs_ra_id rai_bss =
2732 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2733 struct gprs_ra_id rai_sgsn =
2734 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2735 struct gprs_ra_id rai_unknown =
2736 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2737 uint16_t cell_id = 0x1234;
2738
2739 const uint32_t sgsn_ptmsi = 0xefe2b700;
2740 const uint32_t local_sgsn_tlli = 0xefe2b700;
2741 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2742
2743 const uint32_t bss_ptmsi = 0xc00f7304;
2744 const uint32_t local_bss_tlli = 0xc00f7304;
2745 const uint32_t foreign_bss_tlli = 0x8000dead;
2746
2747 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2748 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2749 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2750 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2751 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2752 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2753
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002754 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002755 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002756 const uint32_t local_bss_tlli3 = 0xead4775a;
2757 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2758
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002759 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2760 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002761 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002762 struct gbproxy_link_info *link_info;
2763 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002764 struct gbproxy_peer *peer;
2765 unsigned bss_nu = 0;
2766 unsigned sgsn_nu = 0;
2767
2768 const char *err_msg = NULL;
2769 const char *filter_re = "999999";
2770
2771 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2772 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2773
2774 bssgp_nsi = nsi;
2775 gbcfg.nsi = bssgp_nsi;
2776 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2777 gbcfg.core_mcc = 123;
2778 gbcfg.core_mnc = 456;
2779 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2780 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2781 gbcfg.patch_ptmsi = 1;
2782 gbcfg.acquire_imsi = 1;
2783 gbcfg.bss_ptmsi_state = 0;
2784 gbcfg.sgsn_tlli_state = 1;
2785 gbcfg.route_to_sgsn2 = 1;
2786 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2787
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02002788 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
2789 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002790 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2791 err_msg);
2792 OSMO_ASSERT(err_msg == NULL);
2793 }
2794
2795 configure_sgsn_peer(&sgsn_peer[0]);
2796 configure_sgsn2_peer(&sgsn_peer[1]);
2797 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2798
2799 printf("=== %s ===\n", __func__);
2800 printf("--- Initialise SGSN 1 ---\n\n");
2801
2802 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2803
2804 printf("--- Initialise SGSN 2 ---\n\n");
2805
2806 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2807
2808 printf("--- Initialise BSS 1 ---\n\n");
2809
2810 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2811 setup_bssgp(nsi, &bss_peer[0], 0x0);
2812 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2813 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2814 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2815 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2816
2817 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2818 OSMO_ASSERT(peer != NULL);
2819
2820 gprs_dump_nsi(nsi);
2821 dump_global(stdout, 0);
2822 dump_peers(stdout, 0, 0, &gbcfg);
2823
2824 printf("--- Flow control ---\n\n");
2825
2826 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2827 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2828 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2829
2830 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2831
2832 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2833 foreign_bss_tlli, &rai_unknown, cell_id,
2834 GPRS_SAPI_GMM, bss_nu++,
2835 dtap_attach_req, sizeof(dtap_attach_req));
2836
2837 dump_peers(stdout, 0, 0, &gbcfg);
2838
2839 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2840 foreign_bss_tlli, &rai_bss, cell_id,
2841 GPRS_SAPI_GMM, bss_nu++,
2842 dtap_identity_resp, sizeof(dtap_identity_resp));
2843
2844 dump_peers(stdout, 0, 0, &gbcfg);
2845
2846 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2847 random_sgsn_tlli, 0, NULL, 0,
2848 GPRS_SAPI_GMM, sgsn_nu++,
2849 dtap_identity_req, sizeof(dtap_identity_req));
2850
2851 dump_peers(stdout, 0, 0, &gbcfg);
2852
2853 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2854 foreign_bss_tlli, &rai_bss, cell_id,
2855 GPRS_SAPI_GMM, bss_nu++,
2856 dtap_identity_resp, sizeof(dtap_identity_resp));
2857
2858 dump_peers(stdout, 0, 0, &gbcfg);
2859
2860 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2861 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2862 GPRS_SAPI_GMM, sgsn_nu++,
2863 dtap_attach_acc, sizeof(dtap_attach_acc));
2864
2865 dump_peers(stdout, 0, 0, &gbcfg);
2866
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002867 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2868 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2869 OSMO_ASSERT(link_info);
2870 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2871 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2872 OSMO_ASSERT(!link_info->tlli.bss_validated);
2873 OSMO_ASSERT(!link_info->tlli.net_validated);
2874 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2875 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2876 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2877 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2878 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2879 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002880
2881 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2882 local_bss_tlli, &rai_bss, cell_id,
2883 GPRS_SAPI_GMM, bss_nu++,
2884 dtap_attach_complete, sizeof(dtap_attach_complete));
2885
2886 dump_peers(stdout, 0, 0, &gbcfg);
2887
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002888 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2889 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2890 OSMO_ASSERT(link_info);
2891 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2892 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2893 OSMO_ASSERT(link_info->tlli.bss_validated);
2894 OSMO_ASSERT(!link_info->tlli.net_validated);
2895 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2896 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2897 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2898 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002899
2900 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2901 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2902 GPRS_SAPI_GMM, sgsn_nu++,
2903 dtap_gmm_information, sizeof(dtap_gmm_information));
2904
2905 dump_peers(stdout, 0, 0, &gbcfg);
2906
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002907 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2908 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2909 OSMO_ASSERT(link_info);
2910 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2911 OSMO_ASSERT(link_info->tlli.assigned == 0);
2912 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2913 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002914
2915 /* Non-DTAP */
2916 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2917 local_bss_tlli, &rai_bss, cell_id,
2918 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2919
2920 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2921 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2922 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2923
2924 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2925 local_bss_tlli, &rai_bss, cell_id,
2926 llc_ui_ll11_dns_query_ul,
2927 sizeof(llc_ui_ll11_dns_query_ul));
2928
2929 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2930 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2931 llc_ui_ll11_dns_resp_dl,
2932 sizeof(llc_ui_ll11_dns_resp_dl));
2933
2934 dump_peers(stdout, 0, 0, &gbcfg);
2935
2936 /* Other messages */
2937 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2938 local_bss_tlli, 1, 12);
2939
2940 dump_peers(stdout, 0, 0, &gbcfg);
2941
2942 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2943 local_sgsn_tlli, 1, 12);
2944
2945 dump_peers(stdout, 0, 0, &gbcfg);
2946
2947 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2948
2949 dump_peers(stdout, 0, 0, &gbcfg);
2950
2951 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2952
2953 dump_peers(stdout, 0, 0, &gbcfg);
2954
2955 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2956
2957 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2958 foreign_bss_tlli2, &rai_unknown, cell_id,
2959 GPRS_SAPI_GMM, bss_nu++,
2960 dtap_attach_req, sizeof(dtap_attach_req));
2961
2962 dump_peers(stdout, 0, 0, &gbcfg);
2963
2964 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2965 foreign_bss_tlli2, &rai_bss, cell_id,
2966 GPRS_SAPI_GMM, bss_nu++,
2967 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2968
2969 dump_peers(stdout, 0, 0, &gbcfg);
2970
2971 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2972 random_sgsn_tlli2, 0, NULL, 0,
2973 GPRS_SAPI_GMM, sgsn_nu++,
2974 dtap_identity_req, sizeof(dtap_identity_req));
2975
2976 dump_peers(stdout, 0, 0, &gbcfg);
2977
2978 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2979 foreign_bss_tlli2, &rai_bss, cell_id,
2980 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002981 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002982
2983 dump_peers(stdout, 0, 0, &gbcfg);
2984
2985 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2986 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2987 GPRS_SAPI_GMM, sgsn_nu++,
2988 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2989
2990 dump_peers(stdout, 0, 0, &gbcfg);
2991
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002992 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2993 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2994 OSMO_ASSERT(link_info);
2995 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2996 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2997 OSMO_ASSERT(!link_info->tlli.bss_validated);
2998 OSMO_ASSERT(!link_info->tlli.net_validated);
2999 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3000 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3001 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3002 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3003 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3004 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003005
3006 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3007 local_bss_tlli2, &rai_bss, cell_id,
3008 GPRS_SAPI_GMM, bss_nu++,
3009 dtap_attach_complete, sizeof(dtap_attach_complete));
3010
3011 dump_peers(stdout, 0, 0, &gbcfg);
3012
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003013 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3014 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3015 OSMO_ASSERT(link_info);
3016 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3017 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3018 OSMO_ASSERT(link_info->tlli.bss_validated);
3019 OSMO_ASSERT(!link_info->tlli.net_validated);
3020 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3021 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3022 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3023 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003024
3025 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3026 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3027 GPRS_SAPI_GMM, sgsn_nu++,
3028 dtap_gmm_information, sizeof(dtap_gmm_information));
3029
3030 dump_peers(stdout, 0, 0, &gbcfg);
3031
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003032 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3033 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3034 OSMO_ASSERT(link_info);
3035 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3036 OSMO_ASSERT(link_info->tlli.assigned == 0);
3037 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3038 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003039
3040 /* Non-DTAP */
3041 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3042 local_bss_tlli2, &rai_bss, cell_id,
3043 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3044
3045 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3046 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3047 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3048
3049 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3050 local_bss_tlli2, &rai_bss, cell_id,
3051 llc_ui_ll11_dns_query_ul,
3052 sizeof(llc_ui_ll11_dns_query_ul));
3053
3054 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3055 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3056 llc_ui_ll11_dns_resp_dl,
3057 sizeof(llc_ui_ll11_dns_resp_dl));
3058
3059 dump_peers(stdout, 0, 0, &gbcfg);
3060
3061 /* Other messages */
3062 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3063 local_bss_tlli2, 1, 12);
3064
3065 dump_peers(stdout, 0, 0, &gbcfg);
3066
3067 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3068 local_sgsn_tlli2, 1, 12);
3069
3070 dump_peers(stdout, 0, 0, &gbcfg);
3071
3072 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3073
3074 dump_peers(stdout, 0, 0, &gbcfg);
3075
3076 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003080 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3081
3082 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3083 foreign_bss_tlli3, &rai_unknown, cell_id,
3084 GPRS_SAPI_GMM, bss_nu++,
3085 dtap_attach_req, sizeof(dtap_attach_req));
3086
3087 dump_peers(stdout, 0, 0, &gbcfg);
3088
3089 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3090 foreign_bss_tlli3, &rai_bss, cell_id,
3091 GPRS_SAPI_GMM, bss_nu++,
3092 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3093
3094 dump_peers(stdout, 0, 0, &gbcfg);
3095
3096 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3097 random_sgsn_tlli3, 0, NULL, 0,
3098 GPRS_SAPI_GMM, sgsn_nu++,
3099 dtap_identity_req, sizeof(dtap_identity_req));
3100
3101 dump_peers(stdout, 0, 0, &gbcfg);
3102
3103 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3104 foreign_bss_tlli3, &rai_bss, cell_id,
3105 GPRS_SAPI_GMM, bss_nu++,
3106 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3107
3108 dump_peers(stdout, 0, 0, &gbcfg);
3109
3110 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3111 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3112 GPRS_SAPI_GMM, sgsn_nu++,
3113 dtap_attach_acc, sizeof(dtap_attach_acc));
3114
3115 dump_peers(stdout, 0, 0, &gbcfg);
3116
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003117 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3118 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3119 OSMO_ASSERT(link_info);
3120 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3121 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3122 OSMO_ASSERT(!link_info->tlli.bss_validated);
3123 OSMO_ASSERT(!link_info->tlli.net_validated);
3124 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3125 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3126 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3127 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3128 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3129 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003130
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003131 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3132 local_bss_tlli3, &rai_bss, cell_id,
3133 GPRS_SAPI_GMM, bss_nu++,
3134 dtap_attach_complete, sizeof(dtap_attach_complete));
3135
3136 dump_peers(stdout, 0, 0, &gbcfg);
3137
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003138 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003139 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003140 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3141 OSMO_ASSERT(link_info);
3142 OSMO_ASSERT(link_info != other_info);
3143 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3144 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3145 OSMO_ASSERT(link_info->tlli.bss_validated);
3146 OSMO_ASSERT(!link_info->tlli.net_validated);
3147 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3148 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3149 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3150 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003151
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003152 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3153 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3154 GPRS_SAPI_GMM, sgsn_nu++,
3155 dtap_gmm_information, sizeof(dtap_gmm_information));
3156
3157 dump_peers(stdout, 0, 0, &gbcfg);
3158
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003159 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003160 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003161 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3162 OSMO_ASSERT(link_info);
3163 OSMO_ASSERT(link_info != other_info);
3164 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3165 OSMO_ASSERT(link_info->tlli.assigned == 0);
3166 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3167 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003168
3169
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003170 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3171
3172 /* Detach */
3173 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3174 local_bss_tlli, &rai_bss, cell_id,
3175 GPRS_SAPI_GMM, bss_nu++,
3176 dtap_detach_req, sizeof(dtap_detach_req));
3177
3178 dump_peers(stdout, 0, 0, &gbcfg);
3179
3180 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3181 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3182 GPRS_SAPI_GMM, sgsn_nu++,
3183 dtap_detach_acc, sizeof(dtap_detach_acc));
3184
3185 dump_peers(stdout, 0, 0, &gbcfg);
3186
3187 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3188
3189 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3190 local_bss_tlli2, &rai_bss, cell_id,
3191 GPRS_SAPI_GMM, bss_nu++,
3192 dtap_detach_req, sizeof(dtap_detach_req));
3193
3194 dump_peers(stdout, 0, 0, &gbcfg);
3195
3196 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3197 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3198 GPRS_SAPI_GMM, sgsn_nu++,
3199 dtap_detach_acc, sizeof(dtap_detach_acc));
3200
3201 dump_peers(stdout, 0, 0, &gbcfg);
3202
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003203 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3204
3205 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3206 local_bss_tlli3, &rai_bss, cell_id,
3207 GPRS_SAPI_GMM, bss_nu++,
3208 dtap_detach_req, sizeof(dtap_detach_req));
3209
3210 dump_peers(stdout, 0, 0, &gbcfg);
3211
3212 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3213 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3214 GPRS_SAPI_GMM, sgsn_nu++,
3215 dtap_detach_acc, sizeof(dtap_detach_acc));
3216
3217 dump_peers(stdout, 0, 0, &gbcfg);
3218
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003219 dump_global(stdout, 0);
3220
3221 gbprox_reset(&gbcfg);
3222 gprs_ns_destroy(nsi);
3223 nsi = NULL;
3224}
3225
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003226static void test_gbproxy_keep_info()
3227{
3228 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3229 struct sockaddr_in bss_peer[1] = {{0},};
3230 struct sockaddr_in sgsn_peer= {0};
3231 struct gprs_ra_id rai_bss =
3232 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3233 uint16_t cell_id = 0x1234;
3234
3235 const uint32_t ptmsi = 0xefe2b700;
3236 const uint32_t local_tlli = 0xefe2b700;
3237 const uint32_t foreign_tlli = 0xafe2b700;
3238
3239 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003240 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003241 struct gbproxy_peer *peer;
3242 unsigned bss_nu = 0;
3243 unsigned sgsn_nu = 0;
3244
3245 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3246
3247 bssgp_nsi = nsi;
3248 gbcfg.nsi = bssgp_nsi;
3249 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3250 gbcfg.patch_ptmsi = 0;
3251 gbcfg.acquire_imsi = 1;
3252 gbcfg.bss_ptmsi_state = 0;
3253 gbcfg.sgsn_tlli_state = 1;
3254 gbcfg.core_mcc = 0;
3255 gbcfg.core_mnc = 0;
3256 gbcfg.core_apn = NULL;
3257 gbcfg.core_apn_size = 0;
3258 gbcfg.route_to_sgsn2 = 0;
3259 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003260 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003261
3262 configure_sgsn_peer(&sgsn_peer);
3263 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3264
3265 printf("=== %s ===\n", __func__);
3266 printf("--- Initialise SGSN ---\n\n");
3267
3268 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3269
3270 printf("--- Initialise BSS 1 ---\n\n");
3271
3272 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3273 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3274
3275 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3276 OSMO_ASSERT(peer != NULL);
3277
3278 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3279
3280 gprs_dump_nsi(nsi);
3281 dump_global(stdout, 0);
3282 dump_peers(stdout, 0, 0, &gbcfg);
3283
3284 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3285
3286 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3287 foreign_tlli, &rai_bss, cell_id,
3288 GPRS_SAPI_GMM, bss_nu++,
3289 dtap_attach_req, sizeof(dtap_attach_req));
3290
3291 dump_peers(stdout, 0, 0, &gbcfg);
3292
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003293 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3294 OSMO_ASSERT(link_info);
3295 OSMO_ASSERT(link_info->imsi_len == 0);
3296 OSMO_ASSERT(!link_info->is_deregistered);
3297 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003298
3299 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3300 foreign_tlli, &rai_bss, cell_id,
3301 GPRS_SAPI_GMM, bss_nu++,
3302 dtap_identity_resp, sizeof(dtap_identity_resp));
3303
3304 dump_peers(stdout, 0, 0, &gbcfg);
3305
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003306 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3307 OSMO_ASSERT(link_info);
3308 OSMO_ASSERT(link_info->imsi_len > 0);
3309 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003310
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003311 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3312 foreign_tlli, 0, NULL, 0,
3313 GPRS_SAPI_GMM, sgsn_nu++,
3314 dtap_identity_req, sizeof(dtap_identity_req));
3315
3316 dump_peers(stdout, 0, 0, &gbcfg);
3317
3318 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3319 foreign_tlli, &rai_bss, cell_id,
3320 GPRS_SAPI_GMM, bss_nu++,
3321 dtap_identity_resp, sizeof(dtap_identity_resp));
3322
3323 dump_peers(stdout, 0, 0, &gbcfg);
3324
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003325 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3326 OSMO_ASSERT(link_info);
3327 OSMO_ASSERT(link_info->imsi_len > 0);
3328 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003329
3330 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3331 foreign_tlli, 1, imsi, sizeof(imsi),
3332 GPRS_SAPI_GMM, sgsn_nu++,
3333 dtap_attach_acc, sizeof(dtap_attach_acc));
3334
3335 dump_peers(stdout, 0, 0, &gbcfg);
3336
3337 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3338 local_tlli, &rai_bss, cell_id,
3339 GPRS_SAPI_GMM, bss_nu++,
3340 dtap_attach_complete, sizeof(dtap_attach_complete));
3341
3342 dump_peers(stdout, 0, 0, &gbcfg);
3343
3344 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3345 local_tlli, 1, imsi, sizeof(imsi),
3346 GPRS_SAPI_GMM, sgsn_nu++,
3347 dtap_gmm_information, sizeof(dtap_gmm_information));
3348
3349 dump_peers(stdout, 0, 0, &gbcfg);
3350
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003351 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3352 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003353
3354 /* Detach (MO) */
3355 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3356 local_tlli, &rai_bss, cell_id,
3357 GPRS_SAPI_GMM, bss_nu++,
3358 dtap_detach_req, sizeof(dtap_detach_req));
3359
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003360 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3361 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003362
3363 dump_peers(stdout, 0, 0, &gbcfg);
3364
3365 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3366 local_tlli, 1, imsi, sizeof(imsi),
3367 GPRS_SAPI_GMM, sgsn_nu++,
3368 dtap_detach_acc, sizeof(dtap_detach_acc));
3369
3370 dump_peers(stdout, 0, 0, &gbcfg);
3371
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003372 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3373 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3374 OSMO_ASSERT(link_info);
3375 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003376
3377 /* Re-Attach */
3378 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3379 foreign_tlli, &rai_bss, cell_id,
3380 GPRS_SAPI_GMM, bss_nu++,
3381 dtap_attach_req3, sizeof(dtap_attach_req3));
3382
3383 dump_peers(stdout, 0, 0, &gbcfg);
3384
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003385 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3386 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3387 OSMO_ASSERT(link_info);
3388 OSMO_ASSERT(link_info == link_info2);
3389 OSMO_ASSERT(link_info->imsi_len != 0);
3390 OSMO_ASSERT(!link_info->is_deregistered);
3391 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003392
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003393 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3394 foreign_tlli, 1, imsi, sizeof(imsi),
3395 GPRS_SAPI_GMM, sgsn_nu++,
3396 dtap_attach_acc, sizeof(dtap_attach_acc));
3397
3398 dump_peers(stdout, 0, 0, &gbcfg);
3399
3400 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3401 local_tlli, &rai_bss, cell_id,
3402 GPRS_SAPI_GMM, bss_nu++,
3403 dtap_attach_complete, sizeof(dtap_attach_complete));
3404
3405 dump_peers(stdout, 0, 0, &gbcfg);
3406
3407 /* Detach (MT) */
3408 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3409 local_tlli, 1, imsi, sizeof(imsi),
3410 GPRS_SAPI_GMM, sgsn_nu++,
3411 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3412
3413 dump_peers(stdout, 0, 0, &gbcfg);
3414
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003415 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3416 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003417
3418 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3419 local_tlli, &rai_bss, cell_id,
3420 GPRS_SAPI_GMM, bss_nu++,
3421 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3422
3423 dump_peers(stdout, 0, 0, &gbcfg);
3424
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003425 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3426 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3427 OSMO_ASSERT(link_info);
3428 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003429
3430 /* Re-Attach */
3431 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3432 foreign_tlli, &rai_bss, cell_id,
3433 GPRS_SAPI_GMM, bss_nu++,
3434 dtap_attach_req3, sizeof(dtap_attach_req3));
3435
3436 dump_peers(stdout, 0, 0, &gbcfg);
3437
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003438 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3439 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3440 OSMO_ASSERT(link_info);
3441 OSMO_ASSERT(link_info == link_info2);
3442 OSMO_ASSERT(link_info->imsi_len != 0);
3443 OSMO_ASSERT(!link_info->is_deregistered);
3444 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003445
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003446 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3447 foreign_tlli, 1, imsi, sizeof(imsi),
3448 GPRS_SAPI_GMM, sgsn_nu++,
3449 dtap_attach_acc, sizeof(dtap_attach_acc));
3450
3451 dump_peers(stdout, 0, 0, &gbcfg);
3452
3453 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3454 local_tlli, &rai_bss, cell_id,
3455 GPRS_SAPI_GMM, bss_nu++,
3456 dtap_attach_complete, sizeof(dtap_attach_complete));
3457
3458 dump_peers(stdout, 0, 0, &gbcfg);
3459
3460 /* Detach (MT) */
3461 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3462 local_tlli, 1, imsi, sizeof(imsi),
3463 GPRS_SAPI_GMM, sgsn_nu++,
3464 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3465
3466 dump_peers(stdout, 0, 0, &gbcfg);
3467
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003468 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3469 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003470
3471 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3472 local_tlli, &rai_bss, cell_id,
3473 GPRS_SAPI_GMM, bss_nu++,
3474 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3475
3476 dump_peers(stdout, 0, 0, &gbcfg);
3477
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003478 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3479 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3480 OSMO_ASSERT(link_info);
3481 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003482
3483 /* Re-Attach */
3484 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3485 foreign_tlli, &rai_bss, cell_id,
3486 GPRS_SAPI_GMM, bss_nu++,
3487 dtap_attach_req3, sizeof(dtap_attach_req3));
3488
3489 dump_peers(stdout, 0, 0, &gbcfg);
3490
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003491 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3492 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3493 OSMO_ASSERT(link_info);
3494 OSMO_ASSERT(link_info == link_info2);
3495 OSMO_ASSERT(link_info->imsi_len != 0);
3496 OSMO_ASSERT(!link_info->is_deregistered);
3497 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003498
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003499 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3500 foreign_tlli, 1, imsi, sizeof(imsi),
3501 GPRS_SAPI_GMM, sgsn_nu++,
3502 dtap_attach_acc, sizeof(dtap_attach_acc));
3503
3504 dump_peers(stdout, 0, 0, &gbcfg);
3505
3506 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3507 local_tlli, &rai_bss, cell_id,
3508 GPRS_SAPI_GMM, bss_nu++,
3509 dtap_attach_complete, sizeof(dtap_attach_complete));
3510
3511 dump_peers(stdout, 0, 0, &gbcfg);
3512
3513 /* RA update procedure (reject -> Detach) */
3514 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3515 local_tlli, &rai_bss, 0x7080,
3516 GPRS_SAPI_GMM, bss_nu++,
3517 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3518
3519 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3520 local_tlli, 1, imsi, sizeof(imsi),
3521 GPRS_SAPI_GMM, sgsn_nu++,
3522 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3523
3524 dump_peers(stdout, 0, 0, &gbcfg);
3525
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003526 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3527 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3528 OSMO_ASSERT(link_info);
3529 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003530
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003531 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3532 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3533 foreign_tlli, &rai_bss, cell_id,
3534 GPRS_SAPI_GMM, bss_nu++,
3535 dtap_attach_req, sizeof(dtap_attach_req));
3536
3537 dump_peers(stdout, 0, 0, &gbcfg);
3538
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003539 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3540 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3541 OSMO_ASSERT(link_info);
3542 OSMO_ASSERT(link_info != link_info2);
3543 OSMO_ASSERT(link_info->imsi_len == 0);
3544 OSMO_ASSERT(!link_info->is_deregistered);
3545 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003546
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003547 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3548 foreign_tlli, &rai_bss, cell_id,
3549 GPRS_SAPI_GMM, bss_nu++,
3550 dtap_identity_resp, sizeof(dtap_identity_resp));
3551
3552 dump_peers(stdout, 0, 0, &gbcfg);
3553
3554 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3555 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3556 OSMO_ASSERT(link_info);
3557 OSMO_ASSERT(link_info == link_info2);
3558 OSMO_ASSERT(link_info->imsi_len != 0);
3559 OSMO_ASSERT(!link_info->is_deregistered);
3560 OSMO_ASSERT(!link_info->imsi_acq_pending);
3561
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003562 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3563 foreign_tlli, 1, imsi, sizeof(imsi),
3564 GPRS_SAPI_GMM, sgsn_nu++,
3565 dtap_attach_acc, sizeof(dtap_attach_acc));
3566
3567 dump_peers(stdout, 0, 0, &gbcfg);
3568
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003569 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3570 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3571 OSMO_ASSERT(link_info);
3572 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003573 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003574
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003575 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3576 local_tlli, &rai_bss, cell_id,
3577 GPRS_SAPI_GMM, bss_nu++,
3578 dtap_attach_complete, sizeof(dtap_attach_complete));
3579
3580 dump_peers(stdout, 0, 0, &gbcfg);
3581
3582 /* Detach (MT) */
3583 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3584 local_tlli, 1, imsi, sizeof(imsi),
3585 GPRS_SAPI_GMM, sgsn_nu++,
3586 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3587
3588 dump_peers(stdout, 0, 0, &gbcfg);
3589
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003590 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3591 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003592
3593 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3594 local_tlli, &rai_bss, cell_id,
3595 GPRS_SAPI_GMM, bss_nu++,
3596 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3597
3598 dump_peers(stdout, 0, 0, &gbcfg);
3599
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003600 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3601 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3602 OSMO_ASSERT(link_info);
3603 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003604
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003605 /* Attach rejected */
3606
3607 gbproxy_delete_link_infos(peer);
3608
3609 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3610 foreign_tlli, &rai_bss, cell_id,
3611 GPRS_SAPI_GMM, bss_nu++,
3612 dtap_attach_req, sizeof(dtap_attach_req));
3613
3614 dump_peers(stdout, 0, 0, &gbcfg);
3615
3616 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3617 OSMO_ASSERT(link_info);
3618 OSMO_ASSERT(link_info->imsi_len == 0);
3619 OSMO_ASSERT(!link_info->is_deregistered);
3620 OSMO_ASSERT(link_info->imsi_acq_pending);
3621
3622 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3623 foreign_tlli, &rai_bss, cell_id,
3624 GPRS_SAPI_GMM, bss_nu++,
3625 dtap_identity_resp, sizeof(dtap_identity_resp));
3626
3627 dump_peers(stdout, 0, 0, &gbcfg);
3628
3629 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3630 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3631 OSMO_ASSERT(link_info);
3632 OSMO_ASSERT(link_info == link_info2);
3633 OSMO_ASSERT(link_info->imsi_len != 0);
3634 OSMO_ASSERT(!link_info->is_deregistered);
3635 OSMO_ASSERT(!link_info->imsi_acq_pending);
3636
3637 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3638 foreign_tlli, 1, imsi, sizeof(imsi),
3639 GPRS_SAPI_GMM, sgsn_nu++,
3640 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3641
3642 dump_peers(stdout, 0, 0, &gbcfg);
3643
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003644 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3645
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003646 /* Attach (incomplete) and Detach (MO) */
3647
3648 gbproxy_delete_link_infos(peer);
3649
3650 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3651 foreign_tlli, &rai_bss, cell_id,
3652 GPRS_SAPI_GMM, bss_nu++,
3653 dtap_attach_req, sizeof(dtap_attach_req));
3654
3655 dump_peers(stdout, 0, 0, &gbcfg);
3656
3657 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3658 OSMO_ASSERT(link_info);
3659 OSMO_ASSERT(link_info->imsi_len == 0);
3660 OSMO_ASSERT(!link_info->is_deregistered);
3661 OSMO_ASSERT(link_info->imsi_acq_pending);
3662
3663 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3664 foreign_tlli, &rai_bss, cell_id,
3665 GPRS_SAPI_GMM, bss_nu++,
3666 dtap_detach_req, sizeof(dtap_detach_req));
3667
3668 dump_peers(stdout, 0, 0, &gbcfg);
3669
3670 /* Attach (incomplete) and Detach (MT) */
3671
3672 gbproxy_delete_link_infos(peer);
3673
3674 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3675 foreign_tlli, &rai_bss, cell_id,
3676 GPRS_SAPI_GMM, bss_nu++,
3677 dtap_attach_req, sizeof(dtap_attach_req));
3678
3679 dump_peers(stdout, 0, 0, &gbcfg);
3680
3681 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3682 OSMO_ASSERT(link_info);
3683 OSMO_ASSERT(link_info->imsi_len == 0);
3684 OSMO_ASSERT(!link_info->is_deregistered);
3685 OSMO_ASSERT(link_info->imsi_acq_pending);
3686
3687 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3688 foreign_tlli, 1, imsi, sizeof(imsi),
3689 GPRS_SAPI_GMM, sgsn_nu++,
3690 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3691
3692 dump_peers(stdout, 0, 0, &gbcfg);
3693
3694 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3695 OSMO_ASSERT(link_info);
3696
3697 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3698 foreign_tlli, &rai_bss, cell_id,
3699 GPRS_SAPI_GMM, bss_nu++,
3700 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3701
3702 dump_peers(stdout, 0, 0, &gbcfg);
3703
3704 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3705 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3706 OSMO_ASSERT(link_info);
3707 OSMO_ASSERT(link_info->is_deregistered);
3708
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003709 dump_global(stdout, 0);
3710
3711 gbprox_reset(&gbcfg);
3712 gprs_ns_destroy(nsi);
3713 nsi = NULL;
3714}
3715
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003716/* TODO: Move tlv testing to libosmocore */
3717int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3718int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3719 uint8_t **value);
3720int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3721 size_t *value_len);
3722int lv_shift(uint8_t **data, size_t *data_len,
3723 uint8_t **value, size_t *value_len);
3724
3725static void check_tlv_match(uint8_t **data, size_t *data_len,
3726 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3727{
3728 uint8_t *value;
3729 size_t value_len;
3730 int rc;
3731
3732 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3733 OSMO_ASSERT(rc == 0);
3734
3735 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003736 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003737 OSMO_ASSERT(value_len == exp_len);
3738 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3739}
3740
3741static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3742 uint8_t tag, size_t len, const uint8_t *exp_val)
3743{
3744 uint8_t *value;
3745 int rc;
3746
3747 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3748 OSMO_ASSERT(rc == 0);
3749
3750 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003751 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003752 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3753}
3754
3755static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3756 size_t len, const uint8_t *exp_val)
3757{
3758 uint8_t *value;
3759 int rc;
3760
3761 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003762 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003763 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3764}
3765
3766static void check_lv_shift(uint8_t **data, size_t *data_len,
3767 size_t exp_len, const uint8_t *exp_val)
3768{
3769 uint8_t *value;
3770 size_t value_len;
3771 int rc;
3772
3773 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003774 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003775 OSMO_ASSERT(value_len == exp_len);
3776 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3777}
3778
3779static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3780 const uint8_t *test_data)
3781{
3782 uint8_t buf[300] = {0};
3783
3784 uint8_t *unchanged_ptr = buf - 1;
3785 size_t unchanged_len = 0xdead;
3786 size_t tmp_data_len = data_len;
3787 uint8_t *value = unchanged_ptr;
3788 size_t value_len = unchanged_len;
3789 uint8_t *data = buf;
3790
3791 OSMO_ASSERT(data_len <= sizeof(buf));
3792
3793 tlv_put(data, tag, len, test_data);
3794 if (data_len < len + 2) {
3795 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3796 tag, &value, &value_len));
3797 OSMO_ASSERT(tmp_data_len == 0);
3798 OSMO_ASSERT(data == buf + data_len);
3799 OSMO_ASSERT(value == unchanged_ptr);
3800 OSMO_ASSERT(value_len == unchanged_len);
3801 } else {
3802 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3803 tag, &value, &value_len));
3804 OSMO_ASSERT(value != unchanged_ptr);
3805 OSMO_ASSERT(value_len != unchanged_len);
3806 }
3807}
3808
3809static void check_tv_fixed_match_data_len(size_t data_len,
3810 uint8_t tag, size_t len,
3811 const uint8_t *test_data)
3812{
3813 uint8_t buf[300] = {0};
3814
3815 uint8_t *unchanged_ptr = buf - 1;
3816 size_t tmp_data_len = data_len;
3817 uint8_t *value = unchanged_ptr;
3818 uint8_t *data = buf;
3819
3820 OSMO_ASSERT(data_len <= sizeof(buf));
3821
3822 tv_fixed_put(data, tag, len, test_data);
3823
3824 if (data_len < len + 1) {
3825 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3826 tag, len, &value));
3827 OSMO_ASSERT(tmp_data_len == 0);
3828 OSMO_ASSERT(data == buf + data_len);
3829 OSMO_ASSERT(value == unchanged_ptr);
3830 } else {
3831 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3832 tag, len, &value));
3833 OSMO_ASSERT(value != unchanged_ptr);
3834 }
3835}
3836
3837static void check_v_fixed_shift_data_len(size_t data_len,
3838 size_t len, const uint8_t *test_data)
3839{
3840 uint8_t buf[300] = {0};
3841
3842 uint8_t *unchanged_ptr = buf - 1;
3843 size_t tmp_data_len = data_len;
3844 uint8_t *value = unchanged_ptr;
3845 uint8_t *data = buf;
3846
3847 OSMO_ASSERT(data_len <= sizeof(buf));
3848
3849 memcpy(data, test_data, len);
3850
3851 if (data_len < len) {
3852 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3853 len, &value));
3854 OSMO_ASSERT(tmp_data_len == 0);
3855 OSMO_ASSERT(data == buf + data_len);
3856 OSMO_ASSERT(value == unchanged_ptr);
3857 } else {
3858 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3859 len, &value));
3860 OSMO_ASSERT(value != unchanged_ptr);
3861 }
3862}
3863
3864static void check_lv_shift_data_len(size_t data_len,
3865 size_t len, const uint8_t *test_data)
3866{
3867 uint8_t buf[300] = {0};
3868
3869 uint8_t *unchanged_ptr = buf - 1;
3870 size_t unchanged_len = 0xdead;
3871 size_t tmp_data_len = data_len;
3872 uint8_t *value = unchanged_ptr;
3873 size_t value_len = unchanged_len;
3874 uint8_t *data = buf;
3875
3876 lv_put(data, len, test_data);
3877 if (data_len < len + 1) {
3878 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3879 &value, &value_len));
3880 OSMO_ASSERT(tmp_data_len == 0);
3881 OSMO_ASSERT(data == buf + data_len);
3882 OSMO_ASSERT(value == unchanged_ptr);
3883 OSMO_ASSERT(value_len == unchanged_len);
3884 } else {
3885 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3886 &value, &value_len));
3887 OSMO_ASSERT(value != unchanged_ptr);
3888 OSMO_ASSERT(value_len != unchanged_len);
3889 }
3890}
3891
3892static void test_tlv_shift_functions()
3893{
3894 uint8_t test_data[1024];
3895 uint8_t buf[1024];
3896 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003897 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003898 uint8_t *data;
3899 size_t data_len;
3900 const uint8_t tag = 0x1a;
3901
3902 printf("Test shift functions\n");
3903
3904 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3905 test_data[i] = (uint8_t)i;
3906
3907 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003908 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003909
3910 memset(buf, 0xee, sizeof(buf));
3911 data_end = data = buf;
3912
3913 for (i = 0; i < iterations; i++) {
3914 data_end = tlv_put(data_end, tag, len, test_data);
3915 data_end = tv_fixed_put(data_end, tag, len, test_data);
3916 /* v_fixed_put */
3917 memcpy(data_end, test_data, len);
3918 data_end += len;
3919 data_end = lv_put(data_end, len, test_data);
3920 }
3921
3922 data_len = data_end - data;
3923 OSMO_ASSERT(data_len <= sizeof(buf));
3924
3925 for (i = 0; i < iterations; i++) {
3926 check_tlv_match(&data, &data_len, tag, len, test_data);
3927 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3928 check_v_fixed_shift(&data, &data_len, len, test_data);
3929 check_lv_shift(&data, &data_len, len, test_data);
3930 }
3931
3932 OSMO_ASSERT(data == data_end);
3933
3934 /* Test at end of data */
3935
3936 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3937 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3938 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3939 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3940
3941 /* Test invalid data_len */
3942 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3943 check_tlv_match_data_len(data_len, tag, len, test_data);
3944 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3945 check_v_fixed_shift_data_len(data_len, len, test_data);
3946 check_lv_shift_data_len(data_len, len, test_data);
3947 }
3948 }
3949}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003950
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003951struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003952 struct gbproxy_peer *peer, uint32_t tlli,
3953 const uint8_t *imsi, size_t imsi_len, time_t now)
3954{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003955 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003956 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003957 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003958 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003959
3960 /* Check, whether the IMSI matches */
3961 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003962 imsi_matches = gbproxy_check_imsi(
3963 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003964 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003965 return NULL;
3966 }
3967
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003968 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003969
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003970 if (!link_info) {
3971 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003972
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003973 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003974 /* TLLI has changed somehow, adjust it */
3975 LOGP(DGPRS, LOGL_INFO,
3976 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003977 link_info->tlli.current, tlli);
3978 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003979 }
3980 }
3981
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003982 if (!link_info) {
3983 link_info = gbproxy_link_info_alloc(peer);
3984 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003985 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003986 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003987 tlli_already_known = 1;
3988 }
3989
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003990 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003991
3992 if (!tlli_already_known)
3993 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3994
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003995 gbproxy_attach_link_info(peer, now, link_info);
3996 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003997
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003998 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003999 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004000
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004001 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004002}
4003
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004004static void test_gbproxy_tlli_expire(void)
4005{
4006 struct gbproxy_config cfg = {0};
4007 struct gbproxy_peer *peer;
4008 const char *err_msg = NULL;
4009 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4010 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004011 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004012 const uint32_t tlli1 = 1234 | 0xc0000000;
4013 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004014 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004015 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004016 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004017
4018 printf("Test TLLI info expiry\n\n");
4019
4020 gbproxy_init_config(&cfg);
4021
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004022 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4023 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004024 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4025 err_msg);
4026 OSMO_ASSERT(err_msg == NULL);
4027 }
4028
4029 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004030 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004031
4032 printf("Test TLLI replacement:\n");
4033
4034 cfg.tlli_max_len = 0;
4035 cfg.tlli_max_age = 0;
4036 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004037 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004038
4039 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004040 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004041 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004042 OSMO_ASSERT(link_info);
4043 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004044 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004045
4046 /* replace the old entry */
4047 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004048 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004049 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004050 OSMO_ASSERT(link_info);
4051 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004052 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004053
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004054 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004055
4056 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004057 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4058 OSMO_ASSERT(link_info);
4059 OSMO_ASSERT(link_info->tlli.current == tlli2);
4060 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4061 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004062
4063 printf("\n");
4064
4065 gbproxy_peer_free(peer);
4066 }
4067
4068 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004069 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004070
4071 printf("Test IMSI replacement:\n");
4072
4073 cfg.tlli_max_len = 0;
4074 cfg.tlli_max_age = 0;
4075 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004076 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004077
4078 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004079 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004080 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004081 OSMO_ASSERT(link_info);
4082 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004083 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004084
4085 /* try to replace the old entry */
4086 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004087 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004088 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004089 OSMO_ASSERT(link_info);
4090 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004091 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004092
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004093 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004094
4095 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004096 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4097 OSMO_ASSERT(!link_info);
4098 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4099 OSMO_ASSERT(link_info);
4100 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004101
4102 printf("\n");
4103
4104 gbproxy_peer_free(peer);
4105 }
4106
4107 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004108 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004109 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004110
4111 printf("Test TLLI expiry, max_len == 1:\n");
4112
4113 cfg.tlli_max_len = 1;
4114 cfg.tlli_max_age = 0;
4115 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004116 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004117
4118 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004119 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004120 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004121
4122 /* replace the old entry */
4123 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004124 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004125 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004126
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004127 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004128 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004129 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004130
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004131 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004132
4133 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004134 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4135 OSMO_ASSERT(!link_info);
4136 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4137 OSMO_ASSERT(link_info);
4138 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004139
4140 printf("\n");
4141
4142 gbproxy_peer_free(peer);
4143 }
4144
4145 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004146 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004147 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004148
4149 printf("Test TLLI expiry, max_age == 1:\n");
4150
4151 cfg.tlli_max_len = 0;
4152 cfg.tlli_max_age = 1;
4153 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004154 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004155
4156 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004157 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004158 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004159
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004160 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004161 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004162 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004163 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004164
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004165 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004166 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004167 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004168
4169 dump_peers(stdout, 2, now + 2, &cfg);
4170
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004171 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004172 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4173 OSMO_ASSERT(!link_info);
4174 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4175 OSMO_ASSERT(link_info);
4176 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004177
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004178 printf("\n");
4179
4180 gbproxy_peer_free(peer);
4181 }
4182
4183 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004184 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004185 int num_removed;
4186
4187 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4188
4189 cfg.tlli_max_len = 0;
4190 cfg.tlli_max_age = 1;
4191 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004192 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004193
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004194 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004195 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004196 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004197
4198 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004199 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004200 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004201 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004202
4203 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004204 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004205 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004206 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004207
4208 dump_peers(stdout, 2, now + 2, &cfg);
4209
4210 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004211 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004212 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004213 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004214
4215 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004216
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004217 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004218 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4219 OSMO_ASSERT(!link_info);
4220 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4221 OSMO_ASSERT(!link_info);
4222 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4223 OSMO_ASSERT(link_info);
4224 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004225
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004226 printf("\n");
4227
4228 gbproxy_peer_free(peer);
4229 }
4230}
4231
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004232static void test_gbproxy_imsi_matching(void)
4233{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004234 const char *err_msg = NULL;
4235 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4236 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4237 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4238 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4239 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4240 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4241 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4242 const char *filter_re1 = ".*";
4243 const char *filter_re2 = "^1234";
4244 const char *filter_re3 = "^4321";
4245 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004246 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004247
4248 printf("=== Test IMSI/TMSI matching ===\n\n");
4249
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004250 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004251
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004252 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4253 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004254
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004255 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4256 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004257
4258 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004259 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004260 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004261 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004262
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004263 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4264 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004265
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004266 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4267 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004268
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004269 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4270 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004271
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004272 gbproxy_clear_patch_filter(&match);
4273 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004274
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004275 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4276 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004277
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004278 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4279 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004280 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004281 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004282 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004283 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4284 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4285 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4286 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4287 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004288
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004289 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4290 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004291
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004292 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4293 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4294 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4295 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4296 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4297 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4298 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004299
4300 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004301}
4302
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004303static struct log_info_cat gprs_categories[] = {
4304 [DGPRS] = {
4305 .name = "DGPRS",
4306 .description = "GPRS Packet Service",
4307 .enabled = 1, .loglevel = LOGL_DEBUG,
4308 },
4309 [DNS] = {
4310 .name = "DNS",
4311 .description = "GPRS Network Service (NS)",
4312 .enabled = 1, .loglevel = LOGL_INFO,
4313 },
4314 [DBSSGP] = {
4315 .name = "DBSSGP",
4316 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4317 .enabled = 1, .loglevel = LOGL_DEBUG,
4318 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004319};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004320
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004321static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004322 .cat = gprs_categories,
4323 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004324};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004325
4326int main(int argc, char **argv)
4327{
4328 osmo_init_logging(&info);
4329 log_set_use_color(osmo_stderr_target, 0);
4330 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02004331 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004332
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004333 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004334 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4335 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004336
4337 rate_ctr_init(NULL);
4338
4339 setlinebuf(stdout);
4340
4341 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004342 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004343 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004344 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004345 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004346 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004347 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004348 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004349 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004350 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004351 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004352 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004353 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004354 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004355
4356 exit(EXIT_SUCCESS);
4357}