blob: 3986325a7bea5ffa03dc4111ac3ecfa1e0267c29 [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 Erlbeckc37ef6c2014-09-30 13:49:43 +0200724static void send_bssgp_paging(struct gprs_ns_inst *nsi,
725 struct sockaddr_in *src_addr,
726 const uint8_t *imsi, size_t imsi_size,
727 struct gprs_ra_id *raid, uint32_t ptmsi)
728{
729 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
730 unsigned char msg[100] = {
731 0x06,
732 };
733
734 const unsigned char drx_ie[] = {0x0a, 0x82, 0x07, 0x04};
735 const unsigned char qos_ie[] = {0x18, 0x83, 0x00, 0x00, 0x00};
736
737 size_t bssgp_msg_size = 1;
738
739 if (imsi) {
740 OSMO_ASSERT(imsi_size <= 127);
741 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
742 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
743 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
744 bssgp_msg_size += 2 + imsi_size;
745 }
746
747 memcpy(msg + bssgp_msg_size, drx_ie, sizeof(drx_ie));
748 bssgp_msg_size += sizeof(drx_ie);
749
750 if (raid) {
751 msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA;
752 msg[bssgp_msg_size+1] = 0x86;
753 gsm48_construct_ra(msg + bssgp_msg_size + 2, raid);
754 bssgp_msg_size += 8;
755 }
756
757 memcpy(msg + bssgp_msg_size, qos_ie, sizeof(qos_ie));
758 bssgp_msg_size += sizeof(qos_ie);
759
760 if (ptmsi != GSM_RESERVED_TMSI) {
761 const uint32_t ptmsi_be = htonl(ptmsi);
762 msg[bssgp_msg_size] = BSSGP_IE_TMSI;
763 msg[bssgp_msg_size+1] = 0x84;
764 memcpy(msg + bssgp_msg_size + 2, &ptmsi_be, 4);
765 bssgp_msg_size += 6;
766 }
767
768 send_ns_unitdata(nsi, "PAGING_PS", src_addr, 0, msg, bssgp_msg_size);
769}
770
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200771static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
772 struct sockaddr_in *src_addr,
773 uint16_t bvci, uint8_t tag)
774{
775 /* GPRS Network Service, PDU type: NS_UNITDATA,
776 * BSSGP FLOW_CONTROL_BVC */
777 unsigned char msg[] = {
778 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
779 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
780 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
781 };
782
783 msg[3] = tag;
784
785 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
786 msg, sizeof(msg));
787}
788
789static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
790 struct sockaddr_in *src_addr,
791 uint16_t bvci, uint8_t tag)
792{
793 /* GPRS Network Service, PDU type: NS_UNITDATA,
794 * BSSGP FLOW_CONTROL_BVC_ACK */
795 unsigned char msg[] = {
796 0x27, 0x1e, 0x81, /* Tag */ 0xce
797 };
798
799 msg[3] = tag;
800
801 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
802 msg, sizeof(msg));
803}
804
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200805static void send_llc_ul_ui(
806 struct gprs_ns_inst *nsi, const char *text,
807 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
808 struct gprs_ra_id *raid, uint16_t cell_id,
809 unsigned sapi, unsigned nu,
810 const uint8_t *msg, size_t msg_size)
811{
812 unsigned char llc_msg[4096] = {
813 0x00, 0xc0, 0x01
814 };
815
816 size_t llc_msg_size = 3 + msg_size + 3;
817 uint8_t e_bit = 0;
818 uint8_t pm_bit = 1;
819 unsigned fcs;
820
821 nu &= 0x01ff;
822
823 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
824
825 llc_msg[0] = (sapi & 0x0f);
826 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
827 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
828
829 memcpy(llc_msg + 3, msg, msg_size);
830
831 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
832 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
833 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
834 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
835
836 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
837 src_addr, nsbvci, tlli, raid, cell_id,
838 llc_msg, llc_msg_size);
839}
840
841static void send_llc_dl_ui(
842 struct gprs_ns_inst *nsi, const char *text,
843 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
844 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
845 unsigned sapi, unsigned nu,
846 const uint8_t *msg, size_t msg_size)
847{
848 /* GPRS Network Service, PDU type: NS_UNITDATA */
849 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
850 unsigned char llc_msg[4096] = {
851 0x00, 0x00, 0x01
852 };
853
854 size_t llc_msg_size = 3 + msg_size + 3;
855 uint8_t e_bit = 0;
856 uint8_t pm_bit = 1;
857 unsigned fcs;
858
859 nu &= 0x01ff;
860
861 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
862
863 llc_msg[0] = 0x40 | (sapi & 0x0f);
864 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
865 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
866
867 memcpy(llc_msg + 3, msg, msg_size);
868
869 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
870 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
871 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
872 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
873
874 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
875 src_addr, nsbvci, tlli,
876 with_racap_drx, imsi, imsi_size,
877 llc_msg, llc_msg_size);
878}
879
880
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200881static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
882 uint16_t nsvci, uint16_t nsei)
883{
884 printf("Setup NS-VC: remote 0x%08x:%d, "
885 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
886 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
887 nsvci, nsvci, nsei, nsei);
888
889 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
890 send_ns_alive(nsi, src_addr);
891 send_ns_unblock(nsi, src_addr);
892 send_ns_alive_ack(nsi, src_addr);
893}
894
895static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
896 uint16_t bvci)
897{
898 printf("Setup BSSGP: remote 0x%08x:%d, "
899 "BVCI 0x%04x(%d)\n\n",
900 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
901 bvci, bvci);
902
903 send_bssgp_reset(nsi, src_addr, bvci);
904}
905
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200906static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
907 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200908{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200909 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
910 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200911 send_ns_alive_ack(nsi, sgsn_peer);
912 send_ns_unblock_ack(nsi, sgsn_peer);
913 send_ns_alive(nsi, sgsn_peer);
914}
915
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200916static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
917{
918 sgsn_peer->sin_family = AF_INET;
919 sgsn_peer->sin_port = htons(32000);
920 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
921}
922
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200923static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
924{
925 sgsn_peer->sin_family = AF_INET;
926 sgsn_peer->sin_port = htons(32001);
927 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
928}
929
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200930static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
931{
932 size_t i;
933
934 for (i = 0; i < size; ++i) {
935 bss_peers[i].sin_family = AF_INET;
936 bss_peers[i].sin_port = htons((i + 1) * 1111);
937 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
938 }
939}
940
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200941int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
942 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
943
944/* override */
945int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
946 struct msgb *msg, uint16_t bvci)
947{
948 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
949 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200950 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200951
952 switch (event) {
953 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200954 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200955 default:
956 break;
957 }
958 return 0;
959}
960
961/* override */
962ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
963 const struct sockaddr *dest_addr, socklen_t addrlen)
964{
965 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
966 const struct sockaddr *, socklen_t);
967 static sendto_t real_sendto = NULL;
968 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200969 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200970
971 if (!real_sendto)
972 real_sendto = dlsym(RTLD_NEXT, "sendto");
973
974 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200975 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
976 dest_host, dest_port,
977 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200979 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
980 dest_host, dest_port,
981 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200982 else if (dest_host == REMOTE_SGSN2_ADDR)
983 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
984 dest_host, dest_port,
985 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200986 else
987 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
988
989 return len;
990}
991
992/* override */
993int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
994{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200995 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
996 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200997 uint16_t bvci = msgb_bvci(msg);
998 uint16_t nsei = msgb_nsei(msg);
999
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001000 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001001
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001002 if (!real_gprs_ns_sendmsg)
1003 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
1004
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001005 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001006 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
1007 "msg length %d (%s)\n",
1008 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001009 else if (nsei == SGSN2_NSEI)
1010 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
1011 "msg length %d (%s)\n",
1012 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001013 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001014 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
1015 "msg length %d (%s)\n",
1016 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001017
Jacob Erlbeckacfaff32014-09-22 18:54:34 +02001018 if (received_messages) {
1019 struct msgb *msg_copy;
1020 msg_copy = gprs_msgb_copy(msg, "received_messages");
1021 llist_add_tail(&msg_copy->list, received_messages);
1022 }
1023
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001024 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001025}
1026
Jacob Erlbeckacfaff32014-09-22 18:54:34 +02001027/* Get the next message from the receive FIFO
1028 *
1029 * \returns a pointer to the message which will be invalidated at the next call
1030 * to expect_msg. Returns NULL, if there is no message left.
1031 */
1032static struct msgb *expect_msg(void)
1033{
1034 static struct msgb *msg = NULL;
1035
1036 msgb_free(msg);
1037 msg = NULL;
1038
1039 if (!received_messages)
1040 return NULL;
1041
1042 if (llist_empty(received_messages))
1043 return NULL;
1044
1045 msg = llist_entry(received_messages->next, struct msgb, list);
1046 llist_del(&msg->list);
1047
1048 return msg;
1049}
1050
1051struct expect_result {
1052 struct msgb *msg;
1053 struct gprs_gb_parse_context parse_ctx;
1054};
1055
1056static struct expect_result *expect_bssgp_msg(
1057 int match_nsei, int match_bvci, int match_pdu_type)
1058{
1059 static struct expect_result result;
1060 static const struct expect_result empty_result = {0,};
1061 static struct msgb *msg;
1062 uint16_t nsei;
1063 int rc;
1064
1065 memcpy(&result, &empty_result, sizeof(result));
1066
1067 msg = expect_msg();
1068 if (!msg)
1069 return NULL;
1070
1071 nsei = msgb_nsei(msg);
1072
1073 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1074 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1075 __func__, match_nsei, nsei);
1076 return NULL;
1077 }
1078
1079 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1080 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1081 __func__, match_bvci, msgb_bvci(msg));
1082 return NULL;
1083 }
1084
1085 result.msg = msg;
1086
1087 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1088 result.parse_ctx.peer_nsei = nsei;
1089
1090 if (!msgb_bssgph(msg)) {
1091 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1092 return NULL;
1093 }
1094
1095 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1096 &result.parse_ctx);
1097
1098 if (!rc) {
1099 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1100 return NULL;
1101 }
1102
1103 if (match_pdu_type != MATCH_ANY &&
1104 match_pdu_type != result.parse_ctx.pdu_type) {
1105 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1106 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1107 return NULL;
1108 }
1109
1110 return &result;
1111}
1112
1113static struct expect_result *expect_llc_msg(
1114 int match_nsei, int match_bvci, int match_sapi, int match_type)
1115{
1116 static struct expect_result *result;
1117
1118 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1119 if (!result)
1120 return NULL;
1121
1122 if (!result->parse_ctx.llc) {
1123 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1124 return NULL;
1125 }
1126
1127 if (match_sapi != MATCH_ANY &&
1128 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1129 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1130 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1131 return NULL;
1132 }
1133
1134 if (match_type != MATCH_ANY &&
1135 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1136 fprintf(stderr,
1137 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1138 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1139 return NULL;
1140 }
1141
1142 return result;
1143}
1144
1145static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1146 int match_type)
1147{
1148 static struct expect_result *result;
1149
1150 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1151 if (!result)
1152 return NULL;
1153
1154 if (!result->parse_ctx.g48_hdr) {
1155 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1156 return NULL;
1157 }
1158
1159 if (match_type != MATCH_ANY &&
1160 match_type != result->parse_ctx.g48_hdr->msg_type) {
1161 fprintf(stderr,
1162 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1163 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1164 return NULL;
1165 }
1166
1167 return result;
1168}
1169
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001170static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1171 struct rate_ctr_group *ctrg)
1172{
1173 unsigned int i;
1174
1175 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1176 struct rate_ctr *ctr = &ctrg->ctr[i];
1177 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1178 fprintf(stream, " %s%s: %llu%s",
1179 prefix, ctrg->desc->ctr_desc[i].description,
1180 (long long)ctr->current,
1181 "\n");
1182 };
1183}
1184
1185/* Signal handler for signals from NS layer */
1186static int test_signal(unsigned int subsys, unsigned int signal,
1187 void *handler_data, void *signal_data)
1188{
1189 struct ns_signal_data *nssd = signal_data;
1190 int rc;
1191
1192 if (subsys != SS_L_NS)
1193 return 0;
1194
1195 switch (signal) {
1196 case S_NS_RESET:
1197 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1198 nssd->nsvc->nsvci,
1199 gprs_ns_ll_str(nssd->nsvc));
1200 break;
1201
1202 case S_NS_ALIVE_EXP:
1203 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1204 nssd->nsvc->nsvci,
1205 gprs_ns_ll_str(nssd->nsvc));
1206 break;
1207
1208 case S_NS_BLOCK:
1209 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1210 nssd->nsvc->nsvci,
1211 gprs_ns_ll_str(nssd->nsvc));
1212 break;
1213
1214 case S_NS_UNBLOCK:
1215 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1216 nssd->nsvc->nsvci,
1217 gprs_ns_ll_str(nssd->nsvc));
1218 break;
1219
1220 case S_NS_REPLACED:
1221 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1222 nssd->nsvc->nsvci,
1223 gprs_ns_ll_str(nssd->nsvc));
1224 printf(" -> 0x%04x/%s\n",
1225 nssd->old_nsvc->nsvci,
1226 gprs_ns_ll_str(nssd->old_nsvc));
1227 break;
1228
1229 default:
1230 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1231 nssd->nsvc->nsvci,
1232 gprs_ns_ll_str(nssd->nsvc));
1233 break;
1234 }
1235 printf("\n");
1236 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1237 return rc;
1238}
1239
1240static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1241{
1242 struct msgb *msg;
1243 int ret;
1244 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1245 fprintf(stderr, "message too long: %d\n", data_len);
1246 return -1;
1247 }
1248
1249 msg = gprs_ns_msgb_alloc();
1250 memmove(msg->data, data, data_len);
1251 msg->l2h = msg->data;
1252 msgb_put(msg, data_len);
1253
1254 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1255 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1256 osmo_hexdump(data, data_len));
1257
1258 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1259
1260 printf("result (%s) = %d\n\n", text, ret);
1261
1262 msgb_free(msg);
1263
1264 return ret;
1265}
1266
1267static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1268{
1269 struct gprs_nsvc *nsvc;
1270
1271 printf("Current NS-VCIs:\n");
1272 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1273 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001274 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001275 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001276 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1277 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1278 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001279 );
1280 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1281 }
1282 printf("\n");
1283}
1284
1285static void test_gbproxy()
1286{
1287 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1288 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001289 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001290
1291 bssgp_nsi = nsi;
1292 gbcfg.nsi = bssgp_nsi;
1293 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1294
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001295 configure_sgsn_peer(&sgsn_peer);
1296 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001297
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001298 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001299 printf("--- Initialise SGSN ---\n\n");
1300
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001301 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001302 gprs_dump_nsi(nsi);
1303
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001304 printf("--- Initialise BSS 1 ---\n\n");
1305
1306 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1307 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1308 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001309 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001310
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001311 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1312
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001313 printf("--- Initialise BSS 2 ---\n\n");
1314
1315 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1316 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1317 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001318 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001319
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001320 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1321
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001322 printf("--- Move BSS 1 to new port ---\n\n");
1323
1324 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1325 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001326 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001327
1328 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1329
1330 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1331 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001332 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001333
1334 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1335
1336 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1337 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001338 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001339
1340 printf("--- Move BSS 2 to new port ---\n\n");
1341
1342 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1343 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001344 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001345
1346 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1347
1348 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1349 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001350 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001351
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001352 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1353
1354 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1355 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001356 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001357
1358 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1359
1360 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1361 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001362 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001363
1364 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1365
1366 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1367
1368 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1369 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001370 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001371
1372 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1373
1374 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1375
1376 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1377 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001378 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001379
1380 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1381
1382 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1383
1384 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1385
1386 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1387
1388 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1389
1390 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1391
1392 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1393
1394 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1395
1396 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1397
1398 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1399
1400 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1401
1402 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1403
1404 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1405
1406 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1407
1408 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1409 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001410 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001411
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001412 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001413
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001414 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1415
1416 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1417
1418 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1419
1420 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1421
1422 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1423
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001424 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1425
1426 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1427
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001428 /* Find peer */
1429 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1430 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1431 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1432 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1433 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1434 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1435
1436
1437 /* Cleanup */
1438 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1439 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1440 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1441 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1442 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1443
1444 dump_peers(stdout, 0, 0, &gbcfg);
1445
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001446 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001447
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001448 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001449 gprs_ns_destroy(nsi);
1450 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001451}
1452
1453static void test_gbproxy_ident_changes()
1454{
1455 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1456 struct sockaddr_in bss_peer[1] = {{0},};
1457 struct sockaddr_in sgsn_peer= {0};
1458 uint16_t nsei[2] = {0x1000, 0x2000};
1459 uint16_t nsvci[2] = {0x1001, 0x2001};
1460 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1461
1462 bssgp_nsi = nsi;
1463 gbcfg.nsi = bssgp_nsi;
1464 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1465
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001466 configure_sgsn_peer(&sgsn_peer);
1467 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001468
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001469 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001470 printf("--- Initialise SGSN ---\n\n");
1471
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001472 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001473 gprs_dump_nsi(nsi);
1474
1475 printf("--- Initialise BSS 1 ---\n\n");
1476
1477 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1478 gprs_dump_nsi(nsi);
1479
1480 printf("--- Setup BVCI 1 ---\n\n");
1481
1482 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1483 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001484 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001485
1486 printf("--- Setup BVCI 2 ---\n\n");
1487
1488 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1489 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001490 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001491
1492 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1493
1494 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1495 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1496
1497 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1498
1499 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1500 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1501
1502 printf("--- Change NSEI ---\n\n");
1503
1504 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1505 gprs_dump_nsi(nsi);
1506
1507 printf("--- Setup BVCI 1 ---\n\n");
1508
1509 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1510 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001511 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001512
1513 printf("--- Setup BVCI 3 ---\n\n");
1514
1515 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1516 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001517 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001518
1519 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1520
1521 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1522 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1523
1524 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1525 " (should fail) ---\n\n");
1526
1527 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001528 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001529 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001530 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001531
1532 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1533
1534 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1535 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1536
1537 printf("--- Change NSVCI ---\n\n");
1538
1539 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1540 gprs_dump_nsi(nsi);
1541
1542 printf("--- Setup BVCI 1 ---\n\n");
1543
1544 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1545 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001546 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001547
1548 printf("--- Setup BVCI 4 ---\n\n");
1549
1550 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1551 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001552 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001553
1554 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1555
1556 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1557 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1558
1559 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1560 " (should fail) ---\n\n");
1561
1562 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001563 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001564 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001565 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001566
1567 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1568
1569 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1570 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1571
1572 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1573
1574 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1575 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1576
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001577 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001578 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001579
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001580 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001581 gprs_ns_destroy(nsi);
1582 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001583}
1584
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001585static void test_gbproxy_ra_patching()
1586{
1587 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1588 struct sockaddr_in bss_peer[1] = {{0},};
1589 struct sockaddr_in sgsn_peer= {0};
1590 struct gprs_ra_id rai_bss =
1591 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1592 struct gprs_ra_id rai_sgsn =
1593 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1594 struct gprs_ra_id rai_unknown =
1595 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001596 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001597 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001598 const uint32_t ptmsi = 0xefe2b700;
1599 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001600 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001601 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001602 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001603 const char *patch_re = "^9898|^121314";
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001604 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001605 struct gbproxy_peer *peer;
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001606 LLIST_HEAD(rcv_list);
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001607 struct expect_result *expect_res;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001608
1609 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001610
1611 bssgp_nsi = nsi;
1612 gbcfg.nsi = bssgp_nsi;
1613 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001614 gbcfg.core_mcc = 123;
1615 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001616 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001617 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001618 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001619
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001620 configure_sgsn_peer(&sgsn_peer);
1621 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001622
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001623 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
1624 patch_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001625 fprintf(stderr, "Failed to compile RE '%s': %s\n",
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001626 patch_re, err_msg);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001627 exit(1);
1628 }
1629
1630
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001631 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001632 printf("--- Initialise SGSN ---\n\n");
1633
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001634 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001635 gprs_dump_nsi(nsi);
1636
1637 printf("--- Initialise BSS 1 ---\n\n");
1638
1639 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001640
1641 received_messages = &rcv_list;
1642
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001643 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1644 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001645 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001646
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001647 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001648 OSMO_ASSERT(peer != NULL);
1649
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001650 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1651
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001652 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1653
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001654 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1655
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001656 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001657
1658 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1659
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001660 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001661
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001662 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1663
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001664 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001665 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001666
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001667 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1668 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1669
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001670 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1671
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001672 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1673 foreign_tlli, &rai_bss, cell_id,
1674 GPRS_SAPI_GMM, 0,
1675 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001676
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001677 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001678 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001679
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001680 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1681 foreign_tlli, 0, NULL, 0,
1682 GPRS_SAPI_GMM, 0,
1683 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001684
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001685 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1686
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001687 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1688 foreign_tlli, &rai_bss, cell_id,
1689 GPRS_SAPI_GMM, 3,
1690 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001691
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001692 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1693
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001694 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1695 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1696
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001697 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1698 foreign_tlli, 1, imsi, sizeof(imsi),
1699 GPRS_SAPI_GMM, 1,
1700 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001701
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001702 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1703
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001704 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1705
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001706 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1707 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1708 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1709
1710 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1711 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1712 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1713
1714 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1715 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1716 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1717
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001718 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1719 OSMO_ASSERT(link_info);
1720 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1721 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1722 OSMO_ASSERT(!link_info->tlli.bss_validated);
1723 OSMO_ASSERT(!link_info->tlli.net_validated);
1724 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1725 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1726 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1727 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001728
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001729 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1730 local_tlli, &rai_bss, cell_id,
1731 GPRS_SAPI_GMM, 4,
1732 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001733
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001734 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1735
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001736 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1737
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001738 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1739 OSMO_ASSERT(link_info);
1740 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1741 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1742 OSMO_ASSERT(link_info->tlli.bss_validated);
1743 OSMO_ASSERT(!link_info->tlli.net_validated);
1744 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1745 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1746 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1747 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001748
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001749 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001750 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1751 local_tlli, &rai_bss, cell_id,
1752 GPRS_SAPI_GMM, 3,
1753 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001754
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001755 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1756
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001757 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1758
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001759 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1760 OSMO_ASSERT(link_info);
1761 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1762 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1763 OSMO_ASSERT(link_info->tlli.bss_validated);
1764 OSMO_ASSERT(!link_info->tlli.net_validated);
1765 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1766 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1767 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1768 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001769
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001770 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1771 local_tlli, 1, imsi, sizeof(imsi),
1772 GPRS_SAPI_GMM, 2,
1773 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001774
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001775 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1776
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001777 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1778
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001779 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1780 OSMO_ASSERT(link_info);
1781 OSMO_ASSERT(link_info->tlli.assigned == 0);
1782 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1783 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1784 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001785
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001786 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001787 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1788 local_tlli, &rai_bss, cell_id,
1789 GPRS_SAPI_GMM, 3,
1790 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001791
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001792 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1793 OSMO_ASSERT(expect_res != NULL);
1794 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001795
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001796 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1797
Jacob Erlbeck73685282014-05-23 20:48:07 +02001798 gbcfg.core_apn[0] = 0;
1799 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001800
1801 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001802 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1803 local_tlli, &rai_bss, cell_id,
1804 GPRS_SAPI_GMM, 3,
1805 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001806
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001807 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1808 OSMO_ASSERT(expect_res != NULL);
1809 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001810
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001811 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1812
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001813 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001814
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001815 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001816 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1817 local_tlli, &rai_bss, cell_id,
1818 GPRS_SAPI_GMM, 6,
1819 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001820
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001821 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1822
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001823 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1824 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1825
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001826 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1827 local_tlli, 1, imsi, sizeof(imsi),
1828 GPRS_SAPI_GMM, 5,
1829 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001830
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001831 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1832
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001833 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001834
1835 printf("--- RA update ---\n\n");
1836
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001837 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1838 foreign_tlli, &rai_bss, 0x7080,
1839 GPRS_SAPI_GMM, 5,
1840 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001841
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001842 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1843
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001844 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1845
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001846 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1847 foreign_tlli, 1, imsi, sizeof(imsi),
1848 GPRS_SAPI_GMM, 6,
1849 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001850
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001851 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1852
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001853 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1854
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001855 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001856 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1857 local_tlli, &rai_bss, cell_id,
1858 GPRS_SAPI_GMM, 3,
1859 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001860
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001861 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1862 OSMO_ASSERT(expect_res != NULL);
1863 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001864
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001865 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1866
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001867 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001868
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001869 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001870 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1871 local_tlli, &rai_bss, cell_id,
1872 GPRS_SAPI_GMM, 6,
1873 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001874
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001875 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1876
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001877 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1878
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001879 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001880 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001881
1882 printf("--- Bad cases ---\n\n");
1883
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001884 /* The RAI in the Attach Request message differs from the RAI in the
1885 * BSSGP message, only patch the latter */
1886
1887 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1888 foreign_tlli2, &rai_bss, cell_id,
1889 GPRS_SAPI_GMM, 0,
1890 dtap_attach_req2, sizeof(dtap_attach_req2));
1891
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001892 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1893
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001894 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1895
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001896 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001897 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1898 local_tlli, &rai_bss, cell_id,
1899 GPRS_SAPI_GMM, 3,
1900 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001901
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001902 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1903
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001904 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001905 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001906
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001907 /* TODO: The following breaks with the current libosmocore, enable it
1908 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1909 * is integrated */
1910 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1911 OSMO_ASSERT(expect_msg());
1912
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001913 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001914 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001915
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001916 OSMO_ASSERT(!expect_msg());
1917 received_messages = NULL;
1918
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02001919 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001920 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001921 gprs_ns_destroy(nsi);
1922 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001923}
1924
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001925static void test_gbproxy_ptmsi_assignment()
1926{
1927 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1928 struct sockaddr_in bss_peer[1] = {{0},};
1929 struct sockaddr_in sgsn_peer= {0};
1930 struct gprs_ra_id rai_bss =
1931 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1932 struct gprs_ra_id rai_unknown =
1933 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1934 uint16_t cell_id = 0x1234;
1935
1936 const uint32_t ptmsi = 0xefe2b700;
1937 const uint32_t local_tlli = 0xefe2b700;
1938
1939 const uint32_t foreign_tlli1 = 0x8000dead;
1940 const uint32_t foreign_tlli2 = 0x8000beef;
1941
1942 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1943 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1944
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001945 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001946 struct gbproxy_peer *peer;
1947 unsigned bss_nu = 0;
1948 unsigned sgsn_nu = 0;
1949
1950 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1951
1952 bssgp_nsi = nsi;
1953 gbcfg.nsi = bssgp_nsi;
1954 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1955 gbcfg.core_mcc = 0;
1956 gbcfg.core_mnc = 0;
1957 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1958 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1959 gbcfg.patch_ptmsi = 0;
1960 gbcfg.bss_ptmsi_state = 0;
1961 gbcfg.sgsn_tlli_state = 1;
1962
1963 configure_sgsn_peer(&sgsn_peer);
1964 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1965
1966 printf("=== %s ===\n", __func__);
1967 printf("--- Initialise SGSN ---\n\n");
1968
1969 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1970
1971 printf("--- Initialise BSS 1 ---\n\n");
1972
1973 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1974 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1975
1976 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1977 OSMO_ASSERT(peer != NULL);
1978
1979 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1980
1981 gprs_dump_nsi(nsi);
1982 dump_global(stdout, 0);
1983 dump_peers(stdout, 0, 0, &gbcfg);
1984
1985 printf("--- Establish first LLC connection ---\n\n");
1986
1987 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1988 foreign_tlli1, &rai_unknown, cell_id,
1989 GPRS_SAPI_GMM, bss_nu++,
1990 dtap_attach_req, sizeof(dtap_attach_req));
1991
1992 dump_peers(stdout, 0, 0, &gbcfg);
1993
1994 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1995 foreign_tlli1, 0, NULL, 0,
1996 GPRS_SAPI_GMM, sgsn_nu++,
1997 dtap_identity_req, sizeof(dtap_identity_req));
1998
1999 dump_peers(stdout, 0, 0, &gbcfg);
2000
2001 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2002 foreign_tlli1, &rai_bss, cell_id,
2003 GPRS_SAPI_GMM, bss_nu++,
2004 dtap_identity_resp, sizeof(dtap_identity_resp));
2005
2006 dump_peers(stdout, 0, 0, &gbcfg);
2007
2008 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2009 foreign_tlli1, 1, imsi1, sizeof(imsi1),
2010 GPRS_SAPI_GMM, sgsn_nu++,
2011 dtap_attach_acc, sizeof(dtap_attach_acc));
2012
2013 dump_peers(stdout, 0, 0, &gbcfg);
2014
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002015 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
2016 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2017 OSMO_ASSERT(link_info);
2018 OSMO_ASSERT(link_info == link_info2);
2019 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2020 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
2021 OSMO_ASSERT(!link_info->tlli.bss_validated);
2022 OSMO_ASSERT(!link_info->tlli.net_validated);
2023 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002024
2025 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2026 local_tlli, &rai_bss, cell_id,
2027 GPRS_SAPI_GMM, bss_nu++,
2028 dtap_attach_complete, sizeof(dtap_attach_complete));
2029
2030 dump_peers(stdout, 0, 0, &gbcfg);
2031
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002032 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2033 OSMO_ASSERT(link_info);
2034 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2035 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
2036 OSMO_ASSERT(link_info->tlli.bss_validated);
2037 OSMO_ASSERT(!link_info->tlli.net_validated);
2038 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002039
2040
2041 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2042 local_tlli, 1, imsi1, sizeof(imsi1),
2043 GPRS_SAPI_GMM, sgsn_nu++,
2044 dtap_gmm_information, sizeof(dtap_gmm_information));
2045
2046 dump_peers(stdout, 0, 0, &gbcfg);
2047
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002048 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
2049 OSMO_ASSERT(link_info);
2050 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2051 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002052
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002053 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2054 OSMO_ASSERT(link_info == link_info2);
2055 OSMO_ASSERT(link_info->tlli.assigned == 0);
2056 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2057 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002058
2059 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2060
2061 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2062 foreign_tlli2, &rai_unknown, cell_id,
2063 GPRS_SAPI_GMM, bss_nu++,
2064 dtap_attach_req, sizeof(dtap_attach_req));
2065
2066 dump_peers(stdout, 0, 0, &gbcfg);
2067
2068 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2069 foreign_tlli2, 0, NULL, 0,
2070 GPRS_SAPI_GMM, sgsn_nu++,
2071 dtap_identity_req, sizeof(dtap_identity_req));
2072
2073 dump_peers(stdout, 0, 0, &gbcfg);
2074
2075 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2076 foreign_tlli2, &rai_bss, cell_id,
2077 GPRS_SAPI_GMM, bss_nu++,
2078 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2079
2080 dump_peers(stdout, 0, 0, &gbcfg);
2081
2082 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2083 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2084 GPRS_SAPI_GMM, sgsn_nu++,
2085 dtap_attach_acc, sizeof(dtap_attach_acc));
2086
2087 dump_peers(stdout, 0, 0, &gbcfg);
2088
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002089 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2090 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2091 OSMO_ASSERT(link_info);
2092 OSMO_ASSERT(link_info == link_info2);
2093 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2094 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2095 OSMO_ASSERT(!link_info->tlli.bss_validated);
2096 OSMO_ASSERT(!link_info->tlli.net_validated);
2097 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002098
2099 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2100 local_tlli, &rai_bss, cell_id,
2101 GPRS_SAPI_GMM, bss_nu++,
2102 dtap_attach_complete, sizeof(dtap_attach_complete));
2103
2104 dump_peers(stdout, 0, 0, &gbcfg);
2105
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002106 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2107 OSMO_ASSERT(link_info);
2108 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2109 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2110 OSMO_ASSERT(link_info->tlli.bss_validated);
2111 OSMO_ASSERT(!link_info->tlli.net_validated);
2112 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002113
2114 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2115 local_tlli, 1, imsi2, sizeof(imsi2),
2116 GPRS_SAPI_GMM, sgsn_nu++,
2117 dtap_gmm_information, sizeof(dtap_gmm_information));
2118
2119 dump_peers(stdout, 0, 0, &gbcfg);
2120
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002121 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2122 OSMO_ASSERT(link_info);
2123 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2124 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002125
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002126 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2127 OSMO_ASSERT(link_info == link_info2);
2128 OSMO_ASSERT(link_info->tlli.assigned == 0);
2129 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2130 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002131
2132 dump_global(stdout, 0);
2133
2134 gbprox_reset(&gbcfg);
2135 gprs_ns_destroy(nsi);
2136 nsi = NULL;
2137}
2138
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002139static void test_gbproxy_ptmsi_patching()
2140{
2141 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2142 struct sockaddr_in bss_peer[1] = {{0},};
2143 struct sockaddr_in sgsn_peer= {0};
2144 struct gprs_ra_id rai_bss =
2145 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2146 struct gprs_ra_id rai_sgsn =
2147 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002148 struct gprs_ra_id rai_wrong_mcc_sgsn =
2149 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002150 struct gprs_ra_id rai_unknown =
2151 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2152 uint16_t cell_id = 0x1234;
2153
2154 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002155 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2156 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002157 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002158 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2159 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002160 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002161 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002162
2163 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002164 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2165 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002166 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002167 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2168 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002169 const uint32_t foreign_bss_tlli = 0x8000dead;
2170
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002171
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002172 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002173 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002174 struct gbproxy_peer *peer;
2175 unsigned bss_nu = 0;
2176 unsigned sgsn_nu = 0;
Jacob Erlbeckc37ef6c2014-09-30 13:49:43 +02002177 int old_ctr;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002178
2179 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002180 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2181 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2182 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2183 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2184 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002185
2186 bssgp_nsi = nsi;
2187 gbcfg.nsi = bssgp_nsi;
2188 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2189 gbcfg.core_mcc = 123;
2190 gbcfg.core_mnc = 456;
2191 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2192 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2193 gbcfg.patch_ptmsi = 1;
2194 gbcfg.bss_ptmsi_state = 0;
2195 gbcfg.sgsn_tlli_state = 1;
2196
2197 configure_sgsn_peer(&sgsn_peer);
2198 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2199
2200 printf("=== %s ===\n", __func__);
2201 printf("--- Initialise SGSN ---\n\n");
2202
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002203 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002204
2205 printf("--- Initialise BSS 1 ---\n\n");
2206
2207 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2208 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2209
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002210 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002211 OSMO_ASSERT(peer != NULL);
2212
2213 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2214
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002215 gprs_dump_nsi(nsi);
2216 dump_global(stdout, 0);
2217 dump_peers(stdout, 0, 0, &gbcfg);
2218
2219 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2220
2221 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2222 foreign_bss_tlli, &rai_unknown, cell_id,
2223 GPRS_SAPI_GMM, bss_nu++,
2224 dtap_attach_req, sizeof(dtap_attach_req));
2225
2226 dump_peers(stdout, 0, 0, &gbcfg);
2227
2228 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2229 random_sgsn_tlli, 0, NULL, 0,
2230 GPRS_SAPI_GMM, sgsn_nu++,
2231 dtap_identity_req, sizeof(dtap_identity_req));
2232
2233 dump_peers(stdout, 0, 0, &gbcfg);
2234
2235 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2236 foreign_bss_tlli, &rai_bss, cell_id,
2237 GPRS_SAPI_GMM, bss_nu++,
2238 dtap_identity_resp, sizeof(dtap_identity_resp));
2239
2240 dump_peers(stdout, 0, 0, &gbcfg);
2241
2242 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2243 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2244 GPRS_SAPI_GMM, sgsn_nu++,
2245 dtap_attach_acc, sizeof(dtap_attach_acc));
2246
2247 dump_peers(stdout, 0, 0, &gbcfg);
2248
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002249 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2250 OSMO_ASSERT(link_info);
2251 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2252 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2253 OSMO_ASSERT(!link_info->tlli.bss_validated);
2254 OSMO_ASSERT(!link_info->tlli.net_validated);
2255 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2256 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2257 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2258 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2259 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2260 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002261
2262 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2263 local_bss_tlli, &rai_bss, cell_id,
2264 GPRS_SAPI_GMM, bss_nu++,
2265 dtap_attach_complete, sizeof(dtap_attach_complete));
2266
2267 dump_peers(stdout, 0, 0, &gbcfg);
2268
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002269 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2270 OSMO_ASSERT(link_info);
2271 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2272 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2273 OSMO_ASSERT(link_info->tlli.bss_validated);
2274 OSMO_ASSERT(!link_info->tlli.net_validated);
2275 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2276 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2277 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2278 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002279
2280 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2281 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_gmm_information, sizeof(dtap_gmm_information));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002287 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2288 OSMO_ASSERT(link_info);
2289 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2290 OSMO_ASSERT(link_info->tlli.assigned == 0);
2291 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2292 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002293
Jacob Erlbeck82add782014-09-05 18:08:12 +02002294 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2295 local_bss_tlli, &rai_bss, cell_id,
2296 GPRS_SAPI_GMM, bss_nu++,
2297 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2298
2299 dump_peers(stdout, 0, 0, &gbcfg);
2300
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002301 /* Non-DTAP */
2302 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2303 local_bss_tlli, &rai_bss, cell_id,
2304 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2305
2306 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2307 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2308 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2309
2310 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2311 local_bss_tlli, &rai_bss, cell_id,
2312 llc_ui_ll11_dns_query_ul,
2313 sizeof(llc_ui_ll11_dns_query_ul));
2314
2315 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2316 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2317 llc_ui_ll11_dns_resp_dl,
2318 sizeof(llc_ui_ll11_dns_resp_dl));
2319
2320 dump_peers(stdout, 0, 0, &gbcfg);
2321
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002322 /* Repeated RA Update Requests */
2323 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2324 local_bss_tlli, &rai_bss, 0x7080,
2325 GPRS_SAPI_GMM, bss_nu++,
2326 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2327
2328 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2329 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2330 GPRS_SAPI_GMM, sgsn_nu++,
2331 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2332
2333 dump_peers(stdout, 0, 0, &gbcfg);
2334
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002335 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2336 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2337 OSMO_ASSERT(link_info);
2338 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2339 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2340 OSMO_ASSERT(!link_info->tlli.bss_validated);
2341 OSMO_ASSERT(!link_info->tlli.net_validated);
2342 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2343 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2344 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2345 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2346 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2347 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002348
2349 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2350 local_bss_tlli2, &rai_bss, 0x7080,
2351 GPRS_SAPI_GMM, bss_nu++,
2352 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2353
2354 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2355 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2356 GPRS_SAPI_GMM, sgsn_nu++,
2357 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2358
2359 dump_peers(stdout, 0, 0, &gbcfg);
2360
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002361 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2362 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2363 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2364 OSMO_ASSERT(link_info);
2365 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2366 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2367 OSMO_ASSERT(!link_info->tlli.bss_validated);
2368 OSMO_ASSERT(!link_info->tlli.net_validated);
2369 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2370 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2371 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2372 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2373 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2374 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002375
2376 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2377 local_bss_tlli3, &rai_bss, 0x7080,
2378 GPRS_SAPI_GMM, bss_nu++,
2379 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2380
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002381 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002382
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002383 OSMO_ASSERT(link_info);
2384 OSMO_ASSERT(link_info->tlli.bss_validated);
2385 OSMO_ASSERT(!link_info->tlli.net_validated);
2386 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2387 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002388
2389 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2390 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2391 GPRS_SAPI_GMM, sgsn_nu++,
2392 dtap_gmm_information, sizeof(dtap_gmm_information));
2393
2394 dump_peers(stdout, 0, 0, &gbcfg);
2395
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002396 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2397 OSMO_ASSERT(link_info);
2398 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2399 OSMO_ASSERT(link_info->tlli.assigned == 0);
2400 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2401 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002402
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002403 /* Other messages */
2404 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002405 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002406
2407 dump_peers(stdout, 0, 0, &gbcfg);
2408
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002409 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002410
2411 dump_peers(stdout, 0, 0, &gbcfg);
2412
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002413 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002414
2415 dump_peers(stdout, 0, 0, &gbcfg);
2416
Jacob Erlbeckc37ef6c2014-09-30 13:49:43 +02002417 old_ctr = peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current;
2418
2419 send_bssgp_paging(nsi, &sgsn_peer, imsi, sizeof(imsi), &rai_bss, sgsn_ptmsi3);
2420
2421 dump_peers(stdout, 0, 0, &gbcfg);
2422
2423 OSMO_ASSERT(old_ctr + 1 ==
2424 peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current);
2425
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002426 /* Bad case: Invalid BVCI */
2427 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002428 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002429 dump_global(stdout, 0);
2430
2431 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002432 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002433
2434 dump_global(stdout, 0);
2435
2436 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002437 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002438 &rai_wrong_mcc_sgsn);
2439
2440 dump_global(stdout, 0);
2441
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002442 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2443 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2444 unknown_sgsn_tlli, 1, NULL, 0,
2445 GPRS_SAPI_GMM, 2,
2446 dtap_gmm_information, sizeof(dtap_gmm_information));
2447
2448 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2449 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2450 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2451 GPRS_SAPI_GMM, 3,
2452 dtap_gmm_information, sizeof(dtap_gmm_information));
2453
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002454 /* Detach */
2455 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002456 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002457 GPRS_SAPI_GMM, bss_nu++,
2458 dtap_detach_req, sizeof(dtap_detach_req));
2459
2460 dump_peers(stdout, 0, 0, &gbcfg);
2461
2462 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002463 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002464 GPRS_SAPI_GMM, sgsn_nu++,
2465 dtap_detach_acc, sizeof(dtap_detach_acc));
2466
2467 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002468
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002469 dump_global(stdout, 0);
2470
2471 gbprox_reset(&gbcfg);
2472 gprs_ns_destroy(nsi);
2473 nsi = NULL;
2474}
2475
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002476static void test_gbproxy_ptmsi_patching_bad_cases()
2477{
2478 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2479 struct sockaddr_in bss_peer[1] = {{0},};
2480 struct sockaddr_in sgsn_peer= {0};
2481 struct gprs_ra_id rai_bss =
2482 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2483 struct gprs_ra_id rai_unknown =
2484 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2485 uint16_t cell_id = 0x1234;
2486
2487 const uint32_t sgsn_ptmsi = 0xefe2b700;
2488 const uint32_t local_sgsn_tlli = 0xefe2b700;
2489 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2490
2491 const uint32_t bss_ptmsi = 0xc00f7304;
2492 const uint32_t local_bss_tlli = 0xc00f7304;
2493 const uint32_t foreign_bss_tlli = 0x8000dead;
2494
2495
2496 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2497 struct gbproxy_link_info *link_info;
2498 struct gbproxy_peer *peer;
2499 unsigned bss_nu = 0;
2500 unsigned sgsn_nu = 0;
2501
2502 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2503 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2504
2505 bssgp_nsi = nsi;
2506 gbcfg.nsi = bssgp_nsi;
2507 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2508 gbcfg.core_mcc = 123;
2509 gbcfg.core_mnc = 456;
2510 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2511 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2512 gbcfg.patch_ptmsi = 1;
2513 gbcfg.bss_ptmsi_state = 0;
2514 gbcfg.sgsn_tlli_state = 1;
2515
2516 configure_sgsn_peer(&sgsn_peer);
2517 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2518
2519 printf("=== %s ===\n", __func__);
2520 printf("--- Initialise SGSN ---\n\n");
2521
2522 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2523
2524 printf("--- Initialise BSS 1 ---\n\n");
2525
2526 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2527 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2528
2529 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2530 OSMO_ASSERT(peer != NULL);
2531
2532 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2533
2534 gprs_dump_nsi(nsi);
2535 dump_global(stdout, 0);
2536 dump_peers(stdout, 0, 0, &gbcfg);
2537
2538 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2539
2540 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2541 foreign_bss_tlli, &rai_unknown, cell_id,
2542 GPRS_SAPI_GMM, bss_nu++,
2543 dtap_attach_req, sizeof(dtap_attach_req));
2544
2545 dump_peers(stdout, 0, 0, &gbcfg);
2546
2547 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2548 random_sgsn_tlli, 0, NULL, 0,
2549 GPRS_SAPI_GMM, sgsn_nu++,
2550 dtap_identity_req, sizeof(dtap_identity_req));
2551
2552 dump_peers(stdout, 0, 0, &gbcfg);
2553
2554 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2555 foreign_bss_tlli, &rai_bss, cell_id,
2556 GPRS_SAPI_GMM, bss_nu++,
2557 dtap_identity_resp, sizeof(dtap_identity_resp));
2558
2559 dump_peers(stdout, 0, 0, &gbcfg);
2560
2561 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2562 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2563 GPRS_SAPI_GMM, sgsn_nu++,
2564 dtap_attach_acc, sizeof(dtap_attach_acc));
2565
2566 dump_peers(stdout, 0, 0, &gbcfg);
2567
2568 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2569 OSMO_ASSERT(link_info);
2570 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2571 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2572 OSMO_ASSERT(!link_info->tlli.bss_validated);
2573 OSMO_ASSERT(!link_info->tlli.net_validated);
2574 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2575 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2576 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2577 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2578 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2579 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2580
2581 send_llc_dl_ui(nsi, "ATTACH ACCEPT (duplicated)", &sgsn_peer, 0x1002,
2582 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2583 GPRS_SAPI_GMM, sgsn_nu++,
2584 dtap_attach_acc, sizeof(dtap_attach_acc));
2585
2586 dump_peers(stdout, 0, 0, &gbcfg);
2587
2588 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2589 OSMO_ASSERT(link_info);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002590 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002591 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2592 OSMO_ASSERT(!link_info->tlli.bss_validated);
2593 OSMO_ASSERT(!link_info->tlli.net_validated);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002594 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002595 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2596 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2597 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2598 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2599 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2600
2601 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2602 local_bss_tlli, &rai_bss, cell_id,
2603 GPRS_SAPI_GMM, bss_nu++,
2604 dtap_attach_complete, sizeof(dtap_attach_complete));
2605
2606 dump_peers(stdout, 0, 0, &gbcfg);
2607
2608 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2609 OSMO_ASSERT(link_info);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002610 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002611 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002612 OSMO_ASSERT(link_info->tlli.bss_validated);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002613 OSMO_ASSERT(!link_info->tlli.net_validated);
2614 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2615 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002616 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002617 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2618
2619 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2620 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2621 GPRS_SAPI_GMM, sgsn_nu++,
2622 dtap_gmm_information, sizeof(dtap_gmm_information));
2623
2624 dump_peers(stdout, 0, 0, &gbcfg);
2625
2626 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2627 OSMO_ASSERT(link_info);
Jacob Erlbeck91e9f552014-10-20 16:30:06 +02002628 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2629 OSMO_ASSERT(link_info->tlli.assigned == 0);
2630 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2631 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002632
2633 /* Detach */
2634 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2635 local_bss_tlli, &rai_bss, cell_id,
2636 GPRS_SAPI_GMM, bss_nu++,
2637 dtap_detach_req, sizeof(dtap_detach_req));
2638
2639 dump_peers(stdout, 0, 0, &gbcfg);
2640
2641 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2642 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2643 GPRS_SAPI_GMM, sgsn_nu++,
2644 dtap_detach_acc, sizeof(dtap_detach_acc));
2645
2646 dump_peers(stdout, 0, 0, &gbcfg);
2647
2648 dump_global(stdout, 0);
2649
2650 gbprox_reset(&gbcfg);
2651 gprs_ns_destroy(nsi);
2652 nsi = NULL;
2653}
2654
2655
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002656static void test_gbproxy_imsi_acquisition()
2657{
2658 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2659 struct sockaddr_in bss_peer[1] = {{0},};
2660 struct sockaddr_in sgsn_peer= {0};
2661 struct gprs_ra_id rai_bss =
2662 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2663 struct gprs_ra_id rai_sgsn =
2664 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2665 struct gprs_ra_id rai_wrong_mcc_sgsn =
2666 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2667 struct gprs_ra_id rai_unknown =
2668 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2669 uint16_t cell_id = 0x1234;
2670
2671 const uint32_t sgsn_ptmsi = 0xefe2b700;
2672 const uint32_t local_sgsn_tlli = 0xefe2b700;
2673 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002674 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002675
2676 const uint32_t bss_ptmsi = 0xc00f7304;
2677 const uint32_t local_bss_tlli = 0xc00f7304;
2678 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002679 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002680
2681 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002682 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002683 struct gbproxy_peer *peer;
2684 unsigned bss_nu = 0;
2685 unsigned sgsn_nu = 0;
2686
2687 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2688
2689 bssgp_nsi = nsi;
2690 gbcfg.nsi = bssgp_nsi;
2691 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2692 gbcfg.core_mcc = 123;
2693 gbcfg.core_mnc = 456;
2694 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2695 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2696 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002697 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002698 gbcfg.bss_ptmsi_state = 0;
2699 gbcfg.sgsn_tlli_state = 1;
2700
2701 configure_sgsn_peer(&sgsn_peer);
2702 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2703
2704 printf("=== %s ===\n", __func__);
2705 printf("--- Initialise SGSN ---\n\n");
2706
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002707 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002708
2709 printf("--- Initialise BSS 1 ---\n\n");
2710
2711 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2712 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2713
2714 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2715 OSMO_ASSERT(peer != NULL);
2716
2717 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2718
2719 gprs_dump_nsi(nsi);
2720 dump_global(stdout, 0);
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
2723 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2724
2725 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002726 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002727 GPRS_SAPI_GMM, bss_nu++,
2728 dtap_attach_req, sizeof(dtap_attach_req));
2729
2730 dump_peers(stdout, 0, 0, &gbcfg);
2731
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002732 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2733 foreign_bss_tlli, &rai_bss, cell_id,
2734 GPRS_SAPI_GMM, bss_nu++,
2735 dtap_identity_resp, sizeof(dtap_identity_resp));
2736
2737 dump_peers(stdout, 0, 0, &gbcfg);
2738
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002739 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2740 random_sgsn_tlli, 0, NULL, 0,
2741 GPRS_SAPI_GMM, sgsn_nu++,
2742 dtap_identity_req, sizeof(dtap_identity_req));
2743
2744 dump_peers(stdout, 0, 0, &gbcfg);
2745
2746 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2747 foreign_bss_tlli, &rai_bss, cell_id,
2748 GPRS_SAPI_GMM, bss_nu++,
2749 dtap_identity_resp, sizeof(dtap_identity_resp));
2750
2751 dump_peers(stdout, 0, 0, &gbcfg);
2752
2753 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2754 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2755 GPRS_SAPI_GMM, sgsn_nu++,
2756 dtap_attach_acc, sizeof(dtap_attach_acc));
2757
2758 dump_peers(stdout, 0, 0, &gbcfg);
2759
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002760 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2761 OSMO_ASSERT(link_info);
2762 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2763 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2764 OSMO_ASSERT(!link_info->tlli.bss_validated);
2765 OSMO_ASSERT(!link_info->tlli.net_validated);
2766 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2767 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2768 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2769 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2770 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2771 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002772
2773 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2774 local_bss_tlli, &rai_bss, cell_id,
2775 GPRS_SAPI_GMM, bss_nu++,
2776 dtap_attach_complete, sizeof(dtap_attach_complete));
2777
2778 dump_peers(stdout, 0, 0, &gbcfg);
2779
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002780 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2781 OSMO_ASSERT(link_info);
2782 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2783 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2784 OSMO_ASSERT(link_info->tlli.bss_validated);
2785 OSMO_ASSERT(!link_info->tlli.net_validated);
2786 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2787 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2788 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2789 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002790
2791 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2792 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2793 GPRS_SAPI_GMM, sgsn_nu++,
2794 dtap_gmm_information, sizeof(dtap_gmm_information));
2795
2796 dump_peers(stdout, 0, 0, &gbcfg);
2797
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002798 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2799 OSMO_ASSERT(link_info);
2800 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2801 OSMO_ASSERT(link_info->tlli.assigned == 0);
2802 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2803 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002804
2805 /* Non-DTAP */
2806 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2807 local_bss_tlli, &rai_bss, cell_id,
2808 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2809
2810 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2811 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2812 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2813
2814 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2815 local_bss_tlli, &rai_bss, cell_id,
2816 llc_ui_ll11_dns_query_ul,
2817 sizeof(llc_ui_ll11_dns_query_ul));
2818
2819 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2820 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2821 llc_ui_ll11_dns_resp_dl,
2822 sizeof(llc_ui_ll11_dns_resp_dl));
2823
2824 dump_peers(stdout, 0, 0, &gbcfg);
2825
2826 /* Other messages */
2827 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2828 local_bss_tlli, 1, 12);
2829
2830 dump_peers(stdout, 0, 0, &gbcfg);
2831
2832 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2833 local_sgsn_tlli, 1, 12);
2834
2835 dump_peers(stdout, 0, 0, &gbcfg);
2836
2837 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2838
2839 dump_peers(stdout, 0, 0, &gbcfg);
2840
2841 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2842
2843 dump_peers(stdout, 0, 0, &gbcfg);
2844
2845 /* Bad case: Invalid BVCI */
2846 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2847 local_bss_tlli, 1, 12);
2848 dump_global(stdout, 0);
2849
2850 /* Bad case: Invalid RAI */
2851 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2852
2853 dump_global(stdout, 0);
2854
2855 /* Bad case: Invalid MCC (LAC ok) */
2856 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2857 &rai_wrong_mcc_sgsn);
2858
2859 dump_global(stdout, 0);
2860
2861 /* Detach */
2862 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2863 local_bss_tlli, &rai_bss, cell_id,
2864 GPRS_SAPI_GMM, bss_nu++,
2865 dtap_detach_req, sizeof(dtap_detach_req));
2866
2867 dump_peers(stdout, 0, 0, &gbcfg);
2868
2869 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2870 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2871 GPRS_SAPI_GMM, sgsn_nu++,
2872 dtap_detach_acc, sizeof(dtap_detach_acc));
2873
2874 dump_peers(stdout, 0, 0, &gbcfg);
2875
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002876 /* RA Update request */
2877
2878 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2879 foreign_bss_tlli, &rai_unknown, 0x7080,
2880 GPRS_SAPI_GMM, bss_nu++,
2881 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2882
2883 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2884 foreign_bss_tlli, &rai_bss, cell_id,
2885 GPRS_SAPI_GMM, bss_nu++,
2886 dtap_identity_resp, sizeof(dtap_identity_resp));
2887
2888 dump_peers(stdout, 0, 0, &gbcfg);
2889
2890 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2891 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2892 GPRS_SAPI_GMM, sgsn_nu++,
2893 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2894
2895 dump_peers(stdout, 0, 0, &gbcfg);
2896
2897 /* Detach */
2898
2899 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2900 local_bss_tlli, &rai_bss, cell_id,
2901 GPRS_SAPI_GMM, bss_nu++,
2902 dtap_detach_req, sizeof(dtap_detach_req));
2903
2904 dump_peers(stdout, 0, 0, &gbcfg);
2905
2906 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2907 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2908 GPRS_SAPI_GMM, sgsn_nu++,
2909 dtap_detach_acc, sizeof(dtap_detach_acc));
2910
2911 dump_peers(stdout, 0, 0, &gbcfg);
2912
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002913 /* Special case: Repeated Attach Requests */
2914
2915 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2916 foreign_bss_tlli, &rai_unknown, cell_id,
2917 GPRS_SAPI_GMM, bss_nu++,
2918 dtap_attach_req, sizeof(dtap_attach_req));
2919
2920 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2921 foreign_bss_tlli, &rai_unknown, cell_id,
2922 GPRS_SAPI_GMM, bss_nu++,
2923 dtap_attach_req, sizeof(dtap_attach_req));
2924
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002925 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2926 foreign_bss_tlli, &rai_bss, cell_id,
2927 GPRS_SAPI_GMM, bss_nu++,
2928 dtap_detach_req, sizeof(dtap_detach_req));
2929
2930 dump_peers(stdout, 0, 0, &gbcfg);
2931
2932 /* Special case: Detach from an unknown TLLI */
2933
2934 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2935 other_bss_tlli, &rai_bss, cell_id,
2936 GPRS_SAPI_GMM, bss_nu++,
2937 dtap_detach_req, sizeof(dtap_detach_req));
2938
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002939 dump_peers(stdout, 0, 0, &gbcfg);
2940
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002941 /* Special case: Repeated RA Update Requests */
2942
2943 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2944 foreign_bss_tlli, &rai_unknown, 0x7080,
2945 GPRS_SAPI_GMM, bss_nu++,
2946 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2947
2948 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2949 foreign_bss_tlli, &rai_unknown, 0x7080,
2950 GPRS_SAPI_GMM, bss_nu++,
2951 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2952
2953 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2954 foreign_bss_tlli, &rai_bss, cell_id,
2955 GPRS_SAPI_GMM, bss_nu++,
2956 dtap_detach_req, sizeof(dtap_detach_req));
2957
2958 dump_peers(stdout, 0, 0, &gbcfg);
2959
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002960 dump_global(stdout, 0);
2961
2962 gbprox_reset(&gbcfg);
2963 gprs_ns_destroy(nsi);
2964 nsi = NULL;
2965}
2966
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002967static void test_gbproxy_secondary_sgsn()
2968{
2969 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2970 struct sockaddr_in bss_peer[1] = {{0},};
2971 struct sockaddr_in sgsn_peer[2]= {{0},};
2972 struct gprs_ra_id rai_bss =
2973 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2974 struct gprs_ra_id rai_sgsn =
2975 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2976 struct gprs_ra_id rai_unknown =
2977 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2978 uint16_t cell_id = 0x1234;
2979
2980 const uint32_t sgsn_ptmsi = 0xefe2b700;
2981 const uint32_t local_sgsn_tlli = 0xefe2b700;
2982 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2983
2984 const uint32_t bss_ptmsi = 0xc00f7304;
2985 const uint32_t local_bss_tlli = 0xc00f7304;
2986 const uint32_t foreign_bss_tlli = 0x8000dead;
2987
2988 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2989 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2990 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2991 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2992 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2993 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2994
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002995 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002996 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002997 const uint32_t local_bss_tlli3 = 0xead4775a;
2998 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2999
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003000 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
3001 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003002 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003003 struct gbproxy_link_info *link_info;
3004 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003005 struct gbproxy_peer *peer;
3006 unsigned bss_nu = 0;
3007 unsigned sgsn_nu = 0;
3008
3009 const char *err_msg = NULL;
3010 const char *filter_re = "999999";
3011
3012 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
3013 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
3014
3015 bssgp_nsi = nsi;
3016 gbcfg.nsi = bssgp_nsi;
3017 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3018 gbcfg.core_mcc = 123;
3019 gbcfg.core_mnc = 456;
3020 gbcfg.core_apn = talloc_zero_size(NULL, 100);
3021 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
3022 gbcfg.patch_ptmsi = 1;
3023 gbcfg.acquire_imsi = 1;
3024 gbcfg.bss_ptmsi_state = 0;
3025 gbcfg.sgsn_tlli_state = 1;
3026 gbcfg.route_to_sgsn2 = 1;
3027 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
3028
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003029 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02003030 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003031 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3032 err_msg);
3033 OSMO_ASSERT(err_msg == NULL);
3034 }
3035
3036 configure_sgsn_peer(&sgsn_peer[0]);
3037 configure_sgsn2_peer(&sgsn_peer[1]);
3038 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3039
3040 printf("=== %s ===\n", __func__);
3041 printf("--- Initialise SGSN 1 ---\n\n");
3042
3043 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
3044
3045 printf("--- Initialise SGSN 2 ---\n\n");
3046
3047 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
3048
3049 printf("--- Initialise BSS 1 ---\n\n");
3050
3051 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3052 setup_bssgp(nsi, &bss_peer[0], 0x0);
3053 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
3054 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3055 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
3056 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
3057
3058 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3059 OSMO_ASSERT(peer != NULL);
3060
3061 gprs_dump_nsi(nsi);
3062 dump_global(stdout, 0);
3063 dump_peers(stdout, 0, 0, &gbcfg);
3064
3065 printf("--- Flow control ---\n\n");
3066
3067 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
3068 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
3069 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
3070
3071 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
3072
3073 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3074 foreign_bss_tlli, &rai_unknown, cell_id,
3075 GPRS_SAPI_GMM, bss_nu++,
3076 dtap_attach_req, sizeof(dtap_attach_req));
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
3080 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3081 foreign_bss_tlli, &rai_bss, cell_id,
3082 GPRS_SAPI_GMM, bss_nu++,
3083 dtap_identity_resp, sizeof(dtap_identity_resp));
3084
3085 dump_peers(stdout, 0, 0, &gbcfg);
3086
3087 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
3088 random_sgsn_tlli, 0, NULL, 0,
3089 GPRS_SAPI_GMM, sgsn_nu++,
3090 dtap_identity_req, sizeof(dtap_identity_req));
3091
3092 dump_peers(stdout, 0, 0, &gbcfg);
3093
3094 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3095 foreign_bss_tlli, &rai_bss, cell_id,
3096 GPRS_SAPI_GMM, bss_nu++,
3097 dtap_identity_resp, sizeof(dtap_identity_resp));
3098
3099 dump_peers(stdout, 0, 0, &gbcfg);
3100
3101 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
3102 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3103 GPRS_SAPI_GMM, sgsn_nu++,
3104 dtap_attach_acc, sizeof(dtap_attach_acc));
3105
3106 dump_peers(stdout, 0, 0, &gbcfg);
3107
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003108 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3109 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
3110 OSMO_ASSERT(link_info);
3111 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3112 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3113 OSMO_ASSERT(!link_info->tlli.bss_validated);
3114 OSMO_ASSERT(!link_info->tlli.net_validated);
3115 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
3116 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3117 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3118 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3119 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3120 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003121
3122 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3123 local_bss_tlli, &rai_bss, cell_id,
3124 GPRS_SAPI_GMM, bss_nu++,
3125 dtap_attach_complete, sizeof(dtap_attach_complete));
3126
3127 dump_peers(stdout, 0, 0, &gbcfg);
3128
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003129 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3130 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3131 OSMO_ASSERT(link_info);
3132 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3133 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3134 OSMO_ASSERT(link_info->tlli.bss_validated);
3135 OSMO_ASSERT(!link_info->tlli.net_validated);
3136 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3137 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3138 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3139 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003140
3141 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
3142 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3143 GPRS_SAPI_GMM, sgsn_nu++,
3144 dtap_gmm_information, sizeof(dtap_gmm_information));
3145
3146 dump_peers(stdout, 0, 0, &gbcfg);
3147
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003148 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3149 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3150 OSMO_ASSERT(link_info);
3151 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
3152 OSMO_ASSERT(link_info->tlli.assigned == 0);
3153 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3154 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003155
3156 /* Non-DTAP */
3157 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3158 local_bss_tlli, &rai_bss, cell_id,
3159 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3160
3161 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
3162 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3163 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3164
3165 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3166 local_bss_tlli, &rai_bss, cell_id,
3167 llc_ui_ll11_dns_query_ul,
3168 sizeof(llc_ui_ll11_dns_query_ul));
3169
3170 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
3171 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3172 llc_ui_ll11_dns_resp_dl,
3173 sizeof(llc_ui_ll11_dns_resp_dl));
3174
3175 dump_peers(stdout, 0, 0, &gbcfg);
3176
3177 /* Other messages */
3178 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3179 local_bss_tlli, 1, 12);
3180
3181 dump_peers(stdout, 0, 0, &gbcfg);
3182
3183 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
3184 local_sgsn_tlli, 1, 12);
3185
3186 dump_peers(stdout, 0, 0, &gbcfg);
3187
3188 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
3189
3190 dump_peers(stdout, 0, 0, &gbcfg);
3191
3192 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
3193
3194 dump_peers(stdout, 0, 0, &gbcfg);
3195
3196 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
3197
3198 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3199 foreign_bss_tlli2, &rai_unknown, cell_id,
3200 GPRS_SAPI_GMM, bss_nu++,
3201 dtap_attach_req, sizeof(dtap_attach_req));
3202
3203 dump_peers(stdout, 0, 0, &gbcfg);
3204
3205 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3206 foreign_bss_tlli2, &rai_bss, cell_id,
3207 GPRS_SAPI_GMM, bss_nu++,
3208 dtap_identity2_resp, sizeof(dtap_identity2_resp));
3209
3210 dump_peers(stdout, 0, 0, &gbcfg);
3211
3212 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3213 random_sgsn_tlli2, 0, NULL, 0,
3214 GPRS_SAPI_GMM, sgsn_nu++,
3215 dtap_identity_req, sizeof(dtap_identity_req));
3216
3217 dump_peers(stdout, 0, 0, &gbcfg);
3218
3219 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3220 foreign_bss_tlli2, &rai_bss, cell_id,
3221 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02003222 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003223
3224 dump_peers(stdout, 0, 0, &gbcfg);
3225
3226 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
3227 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3228 GPRS_SAPI_GMM, sgsn_nu++,
3229 dtap_attach_acc2, sizeof(dtap_attach_acc2));
3230
3231 dump_peers(stdout, 0, 0, &gbcfg);
3232
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003233 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
3234 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
3235 OSMO_ASSERT(link_info);
3236 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3237 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3238 OSMO_ASSERT(!link_info->tlli.bss_validated);
3239 OSMO_ASSERT(!link_info->tlli.net_validated);
3240 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3241 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3242 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3243 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3244 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3245 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003246
3247 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3248 local_bss_tlli2, &rai_bss, cell_id,
3249 GPRS_SAPI_GMM, bss_nu++,
3250 dtap_attach_complete, sizeof(dtap_attach_complete));
3251
3252 dump_peers(stdout, 0, 0, &gbcfg);
3253
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003254 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3255 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3256 OSMO_ASSERT(link_info);
3257 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3258 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3259 OSMO_ASSERT(link_info->tlli.bss_validated);
3260 OSMO_ASSERT(!link_info->tlli.net_validated);
3261 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3262 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3263 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3264 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003265
3266 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3267 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3268 GPRS_SAPI_GMM, sgsn_nu++,
3269 dtap_gmm_information, sizeof(dtap_gmm_information));
3270
3271 dump_peers(stdout, 0, 0, &gbcfg);
3272
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003273 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3274 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3275 OSMO_ASSERT(link_info);
3276 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3277 OSMO_ASSERT(link_info->tlli.assigned == 0);
3278 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3279 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003280
3281 /* Non-DTAP */
3282 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3283 local_bss_tlli2, &rai_bss, cell_id,
3284 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3285
3286 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3287 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3288 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3289
3290 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3291 local_bss_tlli2, &rai_bss, cell_id,
3292 llc_ui_ll11_dns_query_ul,
3293 sizeof(llc_ui_ll11_dns_query_ul));
3294
3295 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3296 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3297 llc_ui_ll11_dns_resp_dl,
3298 sizeof(llc_ui_ll11_dns_resp_dl));
3299
3300 dump_peers(stdout, 0, 0, &gbcfg);
3301
3302 /* Other messages */
3303 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3304 local_bss_tlli2, 1, 12);
3305
3306 dump_peers(stdout, 0, 0, &gbcfg);
3307
3308 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3309 local_sgsn_tlli2, 1, 12);
3310
3311 dump_peers(stdout, 0, 0, &gbcfg);
3312
3313 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3314
3315 dump_peers(stdout, 0, 0, &gbcfg);
3316
3317 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3318
3319 dump_peers(stdout, 0, 0, &gbcfg);
3320
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003321 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3322
3323 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3324 foreign_bss_tlli3, &rai_unknown, cell_id,
3325 GPRS_SAPI_GMM, bss_nu++,
3326 dtap_attach_req, sizeof(dtap_attach_req));
3327
3328 dump_peers(stdout, 0, 0, &gbcfg);
3329
3330 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3331 foreign_bss_tlli3, &rai_bss, cell_id,
3332 GPRS_SAPI_GMM, bss_nu++,
3333 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3334
3335 dump_peers(stdout, 0, 0, &gbcfg);
3336
3337 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3338 random_sgsn_tlli3, 0, NULL, 0,
3339 GPRS_SAPI_GMM, sgsn_nu++,
3340 dtap_identity_req, sizeof(dtap_identity_req));
3341
3342 dump_peers(stdout, 0, 0, &gbcfg);
3343
3344 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3345 foreign_bss_tlli3, &rai_bss, cell_id,
3346 GPRS_SAPI_GMM, bss_nu++,
3347 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3348
3349 dump_peers(stdout, 0, 0, &gbcfg);
3350
3351 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3352 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3353 GPRS_SAPI_GMM, sgsn_nu++,
3354 dtap_attach_acc, sizeof(dtap_attach_acc));
3355
3356 dump_peers(stdout, 0, 0, &gbcfg);
3357
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003358 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3359 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3360 OSMO_ASSERT(link_info);
3361 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3362 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3363 OSMO_ASSERT(!link_info->tlli.bss_validated);
3364 OSMO_ASSERT(!link_info->tlli.net_validated);
3365 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3366 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3367 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3368 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3369 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3370 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003371
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003372 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3373 local_bss_tlli3, &rai_bss, cell_id,
3374 GPRS_SAPI_GMM, bss_nu++,
3375 dtap_attach_complete, sizeof(dtap_attach_complete));
3376
3377 dump_peers(stdout, 0, 0, &gbcfg);
3378
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003379 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003380 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003381 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3382 OSMO_ASSERT(link_info);
3383 OSMO_ASSERT(link_info != other_info);
3384 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3385 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3386 OSMO_ASSERT(link_info->tlli.bss_validated);
3387 OSMO_ASSERT(!link_info->tlli.net_validated);
3388 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3389 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3390 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3391 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003392
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003393 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3394 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3395 GPRS_SAPI_GMM, sgsn_nu++,
3396 dtap_gmm_information, sizeof(dtap_gmm_information));
3397
3398 dump_peers(stdout, 0, 0, &gbcfg);
3399
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003400 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003401 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003402 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3403 OSMO_ASSERT(link_info);
3404 OSMO_ASSERT(link_info != other_info);
3405 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3406 OSMO_ASSERT(link_info->tlli.assigned == 0);
3407 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3408 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003409
3410
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003411 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3412
3413 /* Detach */
3414 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3415 local_bss_tlli, &rai_bss, cell_id,
3416 GPRS_SAPI_GMM, bss_nu++,
3417 dtap_detach_req, sizeof(dtap_detach_req));
3418
3419 dump_peers(stdout, 0, 0, &gbcfg);
3420
3421 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3422 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3423 GPRS_SAPI_GMM, sgsn_nu++,
3424 dtap_detach_acc, sizeof(dtap_detach_acc));
3425
3426 dump_peers(stdout, 0, 0, &gbcfg);
3427
3428 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3429
3430 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3431 local_bss_tlli2, &rai_bss, cell_id,
3432 GPRS_SAPI_GMM, bss_nu++,
3433 dtap_detach_req, sizeof(dtap_detach_req));
3434
3435 dump_peers(stdout, 0, 0, &gbcfg);
3436
3437 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3438 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3439 GPRS_SAPI_GMM, sgsn_nu++,
3440 dtap_detach_acc, sizeof(dtap_detach_acc));
3441
3442 dump_peers(stdout, 0, 0, &gbcfg);
3443
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003444 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3445
3446 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3447 local_bss_tlli3, &rai_bss, cell_id,
3448 GPRS_SAPI_GMM, bss_nu++,
3449 dtap_detach_req, sizeof(dtap_detach_req));
3450
3451 dump_peers(stdout, 0, 0, &gbcfg);
3452
3453 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3454 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3455 GPRS_SAPI_GMM, sgsn_nu++,
3456 dtap_detach_acc, sizeof(dtap_detach_acc));
3457
3458 dump_peers(stdout, 0, 0, &gbcfg);
3459
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003460 dump_global(stdout, 0);
3461
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003462 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003463 gbprox_reset(&gbcfg);
3464 gprs_ns_destroy(nsi);
3465 nsi = NULL;
3466}
3467
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003468static void test_gbproxy_keep_info()
3469{
3470 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3471 struct sockaddr_in bss_peer[1] = {{0},};
3472 struct sockaddr_in sgsn_peer= {0};
3473 struct gprs_ra_id rai_bss =
3474 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3475 uint16_t cell_id = 0x1234;
3476
3477 const uint32_t ptmsi = 0xefe2b700;
3478 const uint32_t local_tlli = 0xefe2b700;
3479 const uint32_t foreign_tlli = 0xafe2b700;
3480
3481 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003482 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003483 struct gbproxy_peer *peer;
3484 unsigned bss_nu = 0;
3485 unsigned sgsn_nu = 0;
3486
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003487 LLIST_HEAD(rcv_list);
3488
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003489 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3490
3491 bssgp_nsi = nsi;
3492 gbcfg.nsi = bssgp_nsi;
3493 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3494 gbcfg.patch_ptmsi = 0;
3495 gbcfg.acquire_imsi = 1;
3496 gbcfg.bss_ptmsi_state = 0;
3497 gbcfg.sgsn_tlli_state = 1;
3498 gbcfg.core_mcc = 0;
3499 gbcfg.core_mnc = 0;
3500 gbcfg.core_apn = NULL;
3501 gbcfg.core_apn_size = 0;
3502 gbcfg.route_to_sgsn2 = 0;
3503 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003504 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003505
3506 configure_sgsn_peer(&sgsn_peer);
3507 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3508
3509 printf("=== %s ===\n", __func__);
3510 printf("--- Initialise SGSN ---\n\n");
3511
3512 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3513
3514 printf("--- Initialise BSS 1 ---\n\n");
3515
3516 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3517 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3518
3519 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3520 OSMO_ASSERT(peer != NULL);
3521
3522 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3523
3524 gprs_dump_nsi(nsi);
3525 dump_global(stdout, 0);
3526 dump_peers(stdout, 0, 0, &gbcfg);
3527
3528 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3529
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003530 received_messages = &rcv_list;
3531
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003532 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
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003537 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3538
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003539 dump_peers(stdout, 0, 0, &gbcfg);
3540
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003541 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3542 OSMO_ASSERT(link_info);
3543 OSMO_ASSERT(link_info->imsi_len == 0);
3544 OSMO_ASSERT(!link_info->is_deregistered);
3545 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003546
3547 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
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003552 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3553
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003554 dump_peers(stdout, 0, 0, &gbcfg);
3555
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003556 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3557 OSMO_ASSERT(link_info);
3558 OSMO_ASSERT(link_info->imsi_len > 0);
3559 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003560
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003561 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3562 foreign_tlli, 0, NULL, 0,
3563 GPRS_SAPI_GMM, sgsn_nu++,
3564 dtap_identity_req, sizeof(dtap_identity_req));
3565
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003566 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3567
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003568 dump_peers(stdout, 0, 0, &gbcfg);
3569
3570 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3571 foreign_tlli, &rai_bss, cell_id,
3572 GPRS_SAPI_GMM, bss_nu++,
3573 dtap_identity_resp, sizeof(dtap_identity_resp));
3574
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003575 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
3576
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003577 dump_peers(stdout, 0, 0, &gbcfg);
3578
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003579 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3580 OSMO_ASSERT(link_info);
3581 OSMO_ASSERT(link_info->imsi_len > 0);
3582 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003583
3584 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3585 foreign_tlli, 1, imsi, sizeof(imsi),
3586 GPRS_SAPI_GMM, sgsn_nu++,
3587 dtap_attach_acc, sizeof(dtap_attach_acc));
3588
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003589 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3590
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003591 dump_peers(stdout, 0, 0, &gbcfg);
3592
3593 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3594 local_tlli, &rai_bss, cell_id,
3595 GPRS_SAPI_GMM, bss_nu++,
3596 dtap_attach_complete, sizeof(dtap_attach_complete));
3597
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003598 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3599
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003600 dump_peers(stdout, 0, 0, &gbcfg);
3601
3602 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3603 local_tlli, 1, imsi, sizeof(imsi),
3604 GPRS_SAPI_GMM, sgsn_nu++,
3605 dtap_gmm_information, sizeof(dtap_gmm_information));
3606
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003607 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
3608
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003609 dump_peers(stdout, 0, 0, &gbcfg);
3610
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003611 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3612 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003613
3614 /* Detach (MO) */
3615 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3616 local_tlli, &rai_bss, cell_id,
3617 GPRS_SAPI_GMM, bss_nu++,
3618 dtap_detach_req, sizeof(dtap_detach_req));
3619
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003620 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3621
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003622 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3623 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003624
3625 dump_peers(stdout, 0, 0, &gbcfg);
3626
3627 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3628 local_tlli, 1, imsi, sizeof(imsi),
3629 GPRS_SAPI_GMM, sgsn_nu++,
3630 dtap_detach_acc, sizeof(dtap_detach_acc));
3631
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003632 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3633
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003634 dump_peers(stdout, 0, 0, &gbcfg);
3635
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003636 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3637 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3638 OSMO_ASSERT(link_info);
3639 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003640
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003641 OSMO_ASSERT(!expect_msg());
3642
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003643 /* Re-Attach */
3644 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3645 foreign_tlli, &rai_bss, cell_id,
3646 GPRS_SAPI_GMM, bss_nu++,
3647 dtap_attach_req3, sizeof(dtap_attach_req3));
3648
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003649 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3650
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003651 dump_peers(stdout, 0, 0, &gbcfg);
3652
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003653 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3654 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3655 OSMO_ASSERT(link_info);
3656 OSMO_ASSERT(link_info == link_info2);
3657 OSMO_ASSERT(link_info->imsi_len != 0);
3658 OSMO_ASSERT(!link_info->is_deregistered);
3659 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003660
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003661 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3662 foreign_tlli, 1, imsi, sizeof(imsi),
3663 GPRS_SAPI_GMM, sgsn_nu++,
3664 dtap_attach_acc, sizeof(dtap_attach_acc));
3665
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003666 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3667
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003668 dump_peers(stdout, 0, 0, &gbcfg);
3669
3670 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3671 local_tlli, &rai_bss, cell_id,
3672 GPRS_SAPI_GMM, bss_nu++,
3673 dtap_attach_complete, sizeof(dtap_attach_complete));
3674
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003675 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3676
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003677 dump_peers(stdout, 0, 0, &gbcfg);
3678
3679 /* Detach (MT) */
3680 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3681 local_tlli, 1, imsi, sizeof(imsi),
3682 GPRS_SAPI_GMM, sgsn_nu++,
3683 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3684
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003685 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3686
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003687 dump_peers(stdout, 0, 0, &gbcfg);
3688
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003689 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3690 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003691
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003692 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003693 local_tlli, &rai_bss, cell_id,
3694 GPRS_SAPI_GMM, bss_nu++,
3695 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3696
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003697 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3698 OSMO_ASSERT(!expect_msg());
3699
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003700 dump_peers(stdout, 0, 0, &gbcfg);
3701
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003702 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3703 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3704 OSMO_ASSERT(link_info);
3705 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003706
3707 /* Re-Attach */
3708 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3709 foreign_tlli, &rai_bss, cell_id,
3710 GPRS_SAPI_GMM, bss_nu++,
3711 dtap_attach_req3, sizeof(dtap_attach_req3));
3712
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003713 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3714
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003715 dump_peers(stdout, 0, 0, &gbcfg);
3716
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003717 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3718 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3719 OSMO_ASSERT(link_info);
3720 OSMO_ASSERT(link_info == link_info2);
3721 OSMO_ASSERT(link_info->imsi_len != 0);
3722 OSMO_ASSERT(!link_info->is_deregistered);
3723 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003724
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003725 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3726 foreign_tlli, 1, imsi, sizeof(imsi),
3727 GPRS_SAPI_GMM, sgsn_nu++,
3728 dtap_attach_acc, sizeof(dtap_attach_acc));
3729
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003730 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3731
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003732 dump_peers(stdout, 0, 0, &gbcfg);
3733
3734 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3735 local_tlli, &rai_bss, cell_id,
3736 GPRS_SAPI_GMM, bss_nu++,
3737 dtap_attach_complete, sizeof(dtap_attach_complete));
3738
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003739 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3740
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003741 dump_peers(stdout, 0, 0, &gbcfg);
3742
3743 /* Detach (MT) */
3744 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3745 local_tlli, 1, imsi, sizeof(imsi),
3746 GPRS_SAPI_GMM, sgsn_nu++,
3747 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3748
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003749 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3750
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003751 dump_peers(stdout, 0, 0, &gbcfg);
3752
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003753 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3754 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003755
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003756 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003757 local_tlli, &rai_bss, cell_id,
3758 GPRS_SAPI_GMM, bss_nu++,
3759 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3760
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003761 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3762 OSMO_ASSERT(!expect_msg());
3763
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003764 dump_peers(stdout, 0, 0, &gbcfg);
3765
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003766 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3767 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3768 OSMO_ASSERT(link_info);
3769 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003770
3771 /* Re-Attach */
3772 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3773 foreign_tlli, &rai_bss, cell_id,
3774 GPRS_SAPI_GMM, bss_nu++,
3775 dtap_attach_req3, sizeof(dtap_attach_req3));
3776
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003777 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3778
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003779 dump_peers(stdout, 0, 0, &gbcfg);
3780
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003781 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3782 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3783 OSMO_ASSERT(link_info);
3784 OSMO_ASSERT(link_info == link_info2);
3785 OSMO_ASSERT(link_info->imsi_len != 0);
3786 OSMO_ASSERT(!link_info->is_deregistered);
3787 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003788
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003789 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3790 foreign_tlli, 1, imsi, sizeof(imsi),
3791 GPRS_SAPI_GMM, sgsn_nu++,
3792 dtap_attach_acc, sizeof(dtap_attach_acc));
3793
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003794 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3795
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003796 dump_peers(stdout, 0, 0, &gbcfg);
3797
3798 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3799 local_tlli, &rai_bss, cell_id,
3800 GPRS_SAPI_GMM, bss_nu++,
3801 dtap_attach_complete, sizeof(dtap_attach_complete));
3802
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003803 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3804
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003805 dump_peers(stdout, 0, 0, &gbcfg);
3806
3807 /* RA update procedure (reject -> Detach) */
3808 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3809 local_tlli, &rai_bss, 0x7080,
3810 GPRS_SAPI_GMM, bss_nu++,
3811 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3812
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003813 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
3814
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003815 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3816 local_tlli, 1, imsi, sizeof(imsi),
3817 GPRS_SAPI_GMM, sgsn_nu++,
3818 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3819
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003820 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ));
3821 OSMO_ASSERT(!expect_msg());
3822
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003823 dump_peers(stdout, 0, 0, &gbcfg);
3824
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003825 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3826 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3827 OSMO_ASSERT(link_info);
3828 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003829
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003830 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3831 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3832 foreign_tlli, &rai_bss, cell_id,
3833 GPRS_SAPI_GMM, bss_nu++,
3834 dtap_attach_req, sizeof(dtap_attach_req));
3835
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003836 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3837
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003838 dump_peers(stdout, 0, 0, &gbcfg);
3839
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003840 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3841 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3842 OSMO_ASSERT(link_info);
3843 OSMO_ASSERT(link_info != link_info2);
3844 OSMO_ASSERT(link_info->imsi_len == 0);
3845 OSMO_ASSERT(!link_info->is_deregistered);
3846 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003847
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003848 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3849 foreign_tlli, &rai_bss, cell_id,
3850 GPRS_SAPI_GMM, bss_nu++,
3851 dtap_identity_resp, sizeof(dtap_identity_resp));
3852
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003853 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3854
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003855 dump_peers(stdout, 0, 0, &gbcfg);
3856
3857 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3858 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3859 OSMO_ASSERT(link_info);
3860 OSMO_ASSERT(link_info == link_info2);
3861 OSMO_ASSERT(link_info->imsi_len != 0);
3862 OSMO_ASSERT(!link_info->is_deregistered);
3863 OSMO_ASSERT(!link_info->imsi_acq_pending);
3864
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003865 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3866 foreign_tlli, 1, imsi, sizeof(imsi),
3867 GPRS_SAPI_GMM, sgsn_nu++,
3868 dtap_attach_acc, sizeof(dtap_attach_acc));
3869
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003870 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3871
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003872 dump_peers(stdout, 0, 0, &gbcfg);
3873
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003874 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3875 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3876 OSMO_ASSERT(link_info);
3877 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003878 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003879
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003880 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3881 local_tlli, &rai_bss, cell_id,
3882 GPRS_SAPI_GMM, bss_nu++,
3883 dtap_attach_complete, sizeof(dtap_attach_complete));
3884
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003885 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3886
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003887 dump_peers(stdout, 0, 0, &gbcfg);
3888
3889 /* Detach (MT) */
3890 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3891 local_tlli, 1, imsi, sizeof(imsi),
3892 GPRS_SAPI_GMM, sgsn_nu++,
3893 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3894
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003895 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3896
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003897 dump_peers(stdout, 0, 0, &gbcfg);
3898
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003899 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3900 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003901
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003902 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003903 local_tlli, &rai_bss, cell_id,
3904 GPRS_SAPI_GMM, bss_nu++,
3905 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3906
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003907 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3908
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003909 dump_peers(stdout, 0, 0, &gbcfg);
3910
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003911 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3912 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3913 OSMO_ASSERT(link_info);
3914 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003915
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003916 OSMO_ASSERT(!expect_msg());
3917
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003918 /* Attach rejected */
3919
3920 gbproxy_delete_link_infos(peer);
3921
3922 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3923 foreign_tlli, &rai_bss, cell_id,
3924 GPRS_SAPI_GMM, bss_nu++,
3925 dtap_attach_req, sizeof(dtap_attach_req));
3926
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003927 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3928
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003929 dump_peers(stdout, 0, 0, &gbcfg);
3930
3931 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3932 OSMO_ASSERT(link_info);
3933 OSMO_ASSERT(link_info->imsi_len == 0);
3934 OSMO_ASSERT(!link_info->is_deregistered);
3935 OSMO_ASSERT(link_info->imsi_acq_pending);
3936
3937 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3938 foreign_tlli, &rai_bss, cell_id,
3939 GPRS_SAPI_GMM, bss_nu++,
3940 dtap_identity_resp, sizeof(dtap_identity_resp));
3941
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003942 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3943
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003944 dump_peers(stdout, 0, 0, &gbcfg);
3945
3946 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3947 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3948 OSMO_ASSERT(link_info);
3949 OSMO_ASSERT(link_info == link_info2);
3950 OSMO_ASSERT(link_info->imsi_len != 0);
3951 OSMO_ASSERT(!link_info->is_deregistered);
3952 OSMO_ASSERT(!link_info->imsi_acq_pending);
3953
3954 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3955 foreign_tlli, 1, imsi, sizeof(imsi),
3956 GPRS_SAPI_GMM, sgsn_nu++,
3957 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3958
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003959 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ));
3960
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003961 dump_peers(stdout, 0, 0, &gbcfg);
3962
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003963 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3964
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003965 OSMO_ASSERT(!expect_msg());
3966
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003967 /* Attach (incomplete) and Detach (MO) */
3968
3969 gbproxy_delete_link_infos(peer);
3970
3971 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3972 foreign_tlli, &rai_bss, cell_id,
3973 GPRS_SAPI_GMM, bss_nu++,
3974 dtap_attach_req, sizeof(dtap_attach_req));
3975
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003976 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3977
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003978 dump_peers(stdout, 0, 0, &gbcfg);
3979
3980 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3981 OSMO_ASSERT(link_info);
3982 OSMO_ASSERT(link_info->imsi_len == 0);
3983 OSMO_ASSERT(!link_info->is_deregistered);
3984 OSMO_ASSERT(link_info->imsi_acq_pending);
3985
3986 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3987 foreign_tlli, &rai_bss, cell_id,
3988 GPRS_SAPI_GMM, bss_nu++,
3989 dtap_detach_req, sizeof(dtap_detach_req));
3990
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003991 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3992
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003993 dump_peers(stdout, 0, 0, &gbcfg);
3994
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003995 OSMO_ASSERT(!expect_msg());
3996
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003997 /* Attach (incomplete) and Detach (MT) */
3998
3999 gbproxy_delete_link_infos(peer);
4000
4001 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4002 foreign_tlli, &rai_bss, cell_id,
4003 GPRS_SAPI_GMM, bss_nu++,
4004 dtap_attach_req, sizeof(dtap_attach_req));
4005
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02004006 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
4007
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02004008 dump_peers(stdout, 0, 0, &gbcfg);
4009
4010 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4011 OSMO_ASSERT(link_info);
4012 OSMO_ASSERT(link_info->imsi_len == 0);
4013 OSMO_ASSERT(!link_info->is_deregistered);
4014 OSMO_ASSERT(link_info->imsi_acq_pending);
4015
4016 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
4017 foreign_tlli, 1, imsi, sizeof(imsi),
4018 GPRS_SAPI_GMM, sgsn_nu++,
4019 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
4020
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02004021 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4022
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02004023 dump_peers(stdout, 0, 0, &gbcfg);
4024
4025 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4026 OSMO_ASSERT(link_info);
4027
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02004028 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02004029 foreign_tlli, &rai_bss, cell_id,
4030 GPRS_SAPI_GMM, bss_nu++,
4031 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4032
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02004033 /* TODO: The stored messaged should be cleaned when receiving a Detach
4034 * Ack. Remove the first OSMO_ASSERT when this is fixed. */
4035 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4036 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4037
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02004038 dump_peers(stdout, 0, 0, &gbcfg);
4039
4040 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
4041 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4042 OSMO_ASSERT(link_info);
4043 OSMO_ASSERT(link_info->is_deregistered);
4044
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02004045 OSMO_ASSERT(!expect_msg());
4046 received_messages = NULL;
4047
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004048 dump_global(stdout, 0);
4049
4050 gbprox_reset(&gbcfg);
4051 gprs_ns_destroy(nsi);
4052 nsi = NULL;
4053}
4054
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004055/* TODO: Move tlv testing to libosmocore */
4056int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
4057int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
4058 uint8_t **value);
4059int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
4060 size_t *value_len);
4061int lv_shift(uint8_t **data, size_t *data_len,
4062 uint8_t **value, size_t *value_len);
4063
4064static void check_tlv_match(uint8_t **data, size_t *data_len,
4065 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
4066{
4067 uint8_t *value;
4068 size_t value_len;
4069 int rc;
4070
4071 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
4072 OSMO_ASSERT(rc == 0);
4073
4074 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004075 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004076 OSMO_ASSERT(value_len == exp_len);
4077 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
4078}
4079
4080static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
4081 uint8_t tag, size_t len, const uint8_t *exp_val)
4082{
4083 uint8_t *value;
4084 int rc;
4085
4086 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
4087 OSMO_ASSERT(rc == 0);
4088
4089 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004090 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004091 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
4092}
4093
4094static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
4095 size_t len, const uint8_t *exp_val)
4096{
4097 uint8_t *value;
4098 int rc;
4099
4100 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004101 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004102 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
4103}
4104
4105static void check_lv_shift(uint8_t **data, size_t *data_len,
4106 size_t exp_len, const uint8_t *exp_val)
4107{
4108 uint8_t *value;
4109 size_t value_len;
4110 int rc;
4111
4112 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004113 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004114 OSMO_ASSERT(value_len == exp_len);
4115 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
4116}
4117
4118static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
4119 const uint8_t *test_data)
4120{
4121 uint8_t buf[300] = {0};
4122
4123 uint8_t *unchanged_ptr = buf - 1;
4124 size_t unchanged_len = 0xdead;
4125 size_t tmp_data_len = data_len;
4126 uint8_t *value = unchanged_ptr;
4127 size_t value_len = unchanged_len;
4128 uint8_t *data = buf;
4129
4130 OSMO_ASSERT(data_len <= sizeof(buf));
4131
4132 tlv_put(data, tag, len, test_data);
4133 if (data_len < len + 2) {
4134 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
4135 tag, &value, &value_len));
4136 OSMO_ASSERT(tmp_data_len == 0);
4137 OSMO_ASSERT(data == buf + data_len);
4138 OSMO_ASSERT(value == unchanged_ptr);
4139 OSMO_ASSERT(value_len == unchanged_len);
4140 } else {
4141 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
4142 tag, &value, &value_len));
4143 OSMO_ASSERT(value != unchanged_ptr);
4144 OSMO_ASSERT(value_len != unchanged_len);
4145 }
4146}
4147
4148static void check_tv_fixed_match_data_len(size_t data_len,
4149 uint8_t tag, size_t len,
4150 const uint8_t *test_data)
4151{
4152 uint8_t buf[300] = {0};
4153
4154 uint8_t *unchanged_ptr = buf - 1;
4155 size_t tmp_data_len = data_len;
4156 uint8_t *value = unchanged_ptr;
4157 uint8_t *data = buf;
4158
4159 OSMO_ASSERT(data_len <= sizeof(buf));
4160
4161 tv_fixed_put(data, tag, len, test_data);
4162
4163 if (data_len < len + 1) {
4164 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
4165 tag, len, &value));
4166 OSMO_ASSERT(tmp_data_len == 0);
4167 OSMO_ASSERT(data == buf + data_len);
4168 OSMO_ASSERT(value == unchanged_ptr);
4169 } else {
4170 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
4171 tag, len, &value));
4172 OSMO_ASSERT(value != unchanged_ptr);
4173 }
4174}
4175
4176static void check_v_fixed_shift_data_len(size_t data_len,
4177 size_t len, const uint8_t *test_data)
4178{
4179 uint8_t buf[300] = {0};
4180
4181 uint8_t *unchanged_ptr = buf - 1;
4182 size_t tmp_data_len = data_len;
4183 uint8_t *value = unchanged_ptr;
4184 uint8_t *data = buf;
4185
4186 OSMO_ASSERT(data_len <= sizeof(buf));
4187
4188 memcpy(data, test_data, len);
4189
4190 if (data_len < len) {
4191 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
4192 len, &value));
4193 OSMO_ASSERT(tmp_data_len == 0);
4194 OSMO_ASSERT(data == buf + data_len);
4195 OSMO_ASSERT(value == unchanged_ptr);
4196 } else {
4197 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
4198 len, &value));
4199 OSMO_ASSERT(value != unchanged_ptr);
4200 }
4201}
4202
4203static void check_lv_shift_data_len(size_t data_len,
4204 size_t len, const uint8_t *test_data)
4205{
4206 uint8_t buf[300] = {0};
4207
4208 uint8_t *unchanged_ptr = buf - 1;
4209 size_t unchanged_len = 0xdead;
4210 size_t tmp_data_len = data_len;
4211 uint8_t *value = unchanged_ptr;
4212 size_t value_len = unchanged_len;
4213 uint8_t *data = buf;
4214
4215 lv_put(data, len, test_data);
4216 if (data_len < len + 1) {
4217 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
4218 &value, &value_len));
4219 OSMO_ASSERT(tmp_data_len == 0);
4220 OSMO_ASSERT(data == buf + data_len);
4221 OSMO_ASSERT(value == unchanged_ptr);
4222 OSMO_ASSERT(value_len == unchanged_len);
4223 } else {
4224 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
4225 &value, &value_len));
4226 OSMO_ASSERT(value != unchanged_ptr);
4227 OSMO_ASSERT(value_len != unchanged_len);
4228 }
4229}
4230
4231static void test_tlv_shift_functions()
4232{
4233 uint8_t test_data[1024];
4234 uint8_t buf[1024];
4235 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004236 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004237 uint8_t *data;
4238 size_t data_len;
4239 const uint8_t tag = 0x1a;
4240
4241 printf("Test shift functions\n");
4242
4243 for (i = 0; i < ARRAY_SIZE(test_data); i++)
4244 test_data[i] = (uint8_t)i;
4245
4246 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004247 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004248
4249 memset(buf, 0xee, sizeof(buf));
4250 data_end = data = buf;
4251
4252 for (i = 0; i < iterations; i++) {
4253 data_end = tlv_put(data_end, tag, len, test_data);
4254 data_end = tv_fixed_put(data_end, tag, len, test_data);
4255 /* v_fixed_put */
4256 memcpy(data_end, test_data, len);
4257 data_end += len;
4258 data_end = lv_put(data_end, len, test_data);
4259 }
4260
4261 data_len = data_end - data;
4262 OSMO_ASSERT(data_len <= sizeof(buf));
4263
4264 for (i = 0; i < iterations; i++) {
4265 check_tlv_match(&data, &data_len, tag, len, test_data);
4266 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
4267 check_v_fixed_shift(&data, &data_len, len, test_data);
4268 check_lv_shift(&data, &data_len, len, test_data);
4269 }
4270
4271 OSMO_ASSERT(data == data_end);
4272
4273 /* Test at end of data */
4274
4275 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
4276 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
4277 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
4278 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
4279
4280 /* Test invalid data_len */
4281 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
4282 check_tlv_match_data_len(data_len, tag, len, test_data);
4283 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
4284 check_v_fixed_shift_data_len(data_len, len, test_data);
4285 check_lv_shift_data_len(data_len, len, test_data);
4286 }
4287 }
4288}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004289
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004290struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004291 struct gbproxy_peer *peer, uint32_t tlli,
4292 const uint8_t *imsi, size_t imsi_len, time_t now)
4293{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004294 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004295 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004296 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004297 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004298
4299 /* Check, whether the IMSI matches */
4300 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004301 imsi_matches = gbproxy_check_imsi(
4302 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004303 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004304 return NULL;
4305 }
4306
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004307 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004308
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004309 if (!link_info) {
4310 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004311
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004312 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004313 /* TLLI has changed somehow, adjust it */
4314 LOGP(DGPRS, LOGL_INFO,
4315 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004316 link_info->tlli.current, tlli);
4317 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004318 }
4319 }
4320
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004321 if (!link_info) {
4322 link_info = gbproxy_link_info_alloc(peer);
4323 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004324 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004325 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004326 tlli_already_known = 1;
4327 }
4328
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004329 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004330
4331 if (!tlli_already_known)
4332 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
4333
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004334 gbproxy_attach_link_info(peer, now, link_info);
4335 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004336
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004337 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004338 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004339
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004340 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004341}
4342
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004343static void test_gbproxy_tlli_expire(void)
4344{
4345 struct gbproxy_config cfg = {0};
4346 struct gbproxy_peer *peer;
4347 const char *err_msg = NULL;
4348 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4349 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004350 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004351 const uint32_t tlli1 = 1234 | 0xc0000000;
4352 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004353 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004354 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004355 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004356
4357 printf("Test TLLI info expiry\n\n");
4358
4359 gbproxy_init_config(&cfg);
4360
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004361 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4362 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004363 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4364 err_msg);
4365 OSMO_ASSERT(err_msg == NULL);
4366 }
4367
4368 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004369 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004370
4371 printf("Test TLLI replacement:\n");
4372
4373 cfg.tlli_max_len = 0;
4374 cfg.tlli_max_age = 0;
4375 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004376 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004377
4378 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004379 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004380 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004381 OSMO_ASSERT(link_info);
4382 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004383 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004384
4385 /* replace the old entry */
4386 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004387 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004388 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004389 OSMO_ASSERT(link_info);
4390 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004391 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004392
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004393 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004394
4395 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004396 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4397 OSMO_ASSERT(link_info);
4398 OSMO_ASSERT(link_info->tlli.current == tlli2);
4399 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4400 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004401
4402 printf("\n");
4403
4404 gbproxy_peer_free(peer);
4405 }
4406
4407 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004408 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004409
4410 printf("Test IMSI replacement:\n");
4411
4412 cfg.tlli_max_len = 0;
4413 cfg.tlli_max_age = 0;
4414 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004415 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004416
4417 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004418 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004419 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004420 OSMO_ASSERT(link_info);
4421 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004422 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004423
4424 /* try to replace the old entry */
4425 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004426 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004427 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004428 OSMO_ASSERT(link_info);
4429 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004430 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004431
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004432 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004433
4434 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004435 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4436 OSMO_ASSERT(!link_info);
4437 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4438 OSMO_ASSERT(link_info);
4439 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004440
4441 printf("\n");
4442
4443 gbproxy_peer_free(peer);
4444 }
4445
4446 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004447 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004448 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004449
4450 printf("Test TLLI expiry, max_len == 1:\n");
4451
4452 cfg.tlli_max_len = 1;
4453 cfg.tlli_max_age = 0;
4454 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004455 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004456
4457 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004458 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004459 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004460
4461 /* replace the old entry */
4462 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004463 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004464 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004465
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004466 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004467 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004468 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004469
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004470 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004471
4472 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004473 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4474 OSMO_ASSERT(!link_info);
4475 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4476 OSMO_ASSERT(link_info);
4477 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004478
4479 printf("\n");
4480
4481 gbproxy_peer_free(peer);
4482 }
4483
4484 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004485 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004486 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004487
4488 printf("Test TLLI expiry, max_age == 1:\n");
4489
4490 cfg.tlli_max_len = 0;
4491 cfg.tlli_max_age = 1;
4492 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004493 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004494
4495 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004496 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004497 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004498
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004499 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004500 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004501 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004502 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004503
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004504 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004505 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004506 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004507
4508 dump_peers(stdout, 2, now + 2, &cfg);
4509
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004510 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004511 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4512 OSMO_ASSERT(!link_info);
4513 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4514 OSMO_ASSERT(link_info);
4515 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004516
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004517 printf("\n");
4518
4519 gbproxy_peer_free(peer);
4520 }
4521
4522 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004523 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004524 int num_removed;
4525
4526 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4527
4528 cfg.tlli_max_len = 0;
4529 cfg.tlli_max_age = 1;
4530 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004531 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004532
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004533 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004534 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004535 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004536
4537 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004538 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004539 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004540 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004541
4542 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004543 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004544 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004545 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004546
4547 dump_peers(stdout, 2, now + 2, &cfg);
4548
4549 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004550 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004551 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004552 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004553
4554 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004555
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004556 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004557 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4558 OSMO_ASSERT(!link_info);
4559 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4560 OSMO_ASSERT(!link_info);
4561 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4562 OSMO_ASSERT(link_info);
4563 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004564
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004565 printf("\n");
4566
4567 gbproxy_peer_free(peer);
4568 }
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004569 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4570 gbprox_reset(&cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004571}
4572
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004573static void test_gbproxy_imsi_matching(void)
4574{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004575 const char *err_msg = NULL;
4576 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4577 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4578 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4579 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4580 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4581 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4582 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4583 const char *filter_re1 = ".*";
4584 const char *filter_re2 = "^1234";
4585 const char *filter_re3 = "^4321";
4586 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004587 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004588
4589 printf("=== Test IMSI/TMSI matching ===\n\n");
4590
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004591 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004592
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004593 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4594 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004595
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004596 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4597 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004598
4599 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004600 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004601 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004602 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004603
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004604 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4605 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004606
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004607 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4608 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004609
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004610 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4611 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004612
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004613 gbproxy_clear_patch_filter(&match);
4614 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004615
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004616 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4617 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004618
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004619 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4620 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004621 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004622 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004623 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004624 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4625 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4626 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4627 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4628 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004629
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004630 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4631 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004632
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004633 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4634 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4635 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4636 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4637 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4638 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4639 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004640
4641 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004642
4643 gbproxy_clear_patch_filter(&match);
4644 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004645}
4646
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004647static struct log_info_cat gprs_categories[] = {
4648 [DGPRS] = {
4649 .name = "DGPRS",
4650 .description = "GPRS Packet Service",
4651 .enabled = 1, .loglevel = LOGL_DEBUG,
4652 },
4653 [DNS] = {
4654 .name = "DNS",
4655 .description = "GPRS Network Service (NS)",
4656 .enabled = 1, .loglevel = LOGL_INFO,
4657 },
4658 [DBSSGP] = {
4659 .name = "DBSSGP",
4660 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4661 .enabled = 1, .loglevel = LOGL_DEBUG,
4662 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004663};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004664
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004665static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004666 .cat = gprs_categories,
4667 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004668};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004669
4670int main(int argc, char **argv)
4671{
4672 osmo_init_logging(&info);
4673 log_set_use_color(osmo_stderr_target, 0);
4674 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02004675 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004676
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004677 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004678 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4679 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004680
4681 rate_ctr_init(NULL);
4682
4683 setlinebuf(stdout);
4684
4685 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004686 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004687 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004688 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004689 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004690 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004691 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004692 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004693 test_gbproxy_ptmsi_patching();
Jacob Erlbecke99c3332014-10-20 16:25:01 +02004694 test_gbproxy_ptmsi_patching_bad_cases();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004695 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004696 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004697 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004698 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004699 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004700
4701 exit(EXIT_SUCCESS);
4702}