blob: f99924c559b1bcbcecbad47a48dc99a1162d196a [file] [log] [blame]
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001/* test routines for gbproxy
2 * send NS messages to the gbproxy and dumps what happens
3 * (C) 2013 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 */
6
7#undef _GNU_SOURCE
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <getopt.h>
15#include <dlfcn.h>
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020017#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <osmocom/core/msgb.h>
21#include <osmocom/core/application.h>
22#include <osmocom/core/utils.h>
23#include <osmocom/core/logging.h>
24#include <osmocom/core/talloc.h>
25#include <osmocom/core/signal.h>
26#include <osmocom/core/rate_ctr.h>
Jacob Erlbeckb1381062014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck59748e62014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020029#include <osmocom/gprs/gprs_msgb.h>
30#include <osmocom/gprs/gprs_ns.h>
31#include <osmocom/gprs/gprs_bssgp.h>
32
33#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +020035#include <openbsc/gprs_llc.h>
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020036#include <openbsc/gprs_gb_parse.h>
37#include <openbsc/gsm_04_08_gprs.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020038#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020039
40#define REMOTE_BSS_ADDR 0x01020304
41#define REMOTE_SGSN_ADDR 0x05060708
42
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020043#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020044
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020045#define REMOTE_SGSN2_ADDR 0x15161718
46#define SGSN2_NSEI 0x0102
47
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020048#define MATCH_ANY (-1)
49
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020050struct gbproxy_config gbcfg = {0};
51
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020052struct llist_head *received_messages = NULL;
53
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020054static int dump_global(FILE *stream, int indent)
55{
56 unsigned int i;
57 const struct rate_ctr_group_desc *desc;
58 int rc;
59
60 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
61 if (rc < 0)
62 return rc;
63
64 desc = gbcfg.ctrg->desc;
65
66 for (i = 0; i < desc->num_ctr; i++) {
67 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
68 if (ctr->current) {
69 rc = fprintf(stream, "%*s %s: %llu\n",
70 indent, "",
71 desc->ctr_desc[i].description,
72 (long long)ctr->current);
73
74 if (rc < 0)
75 return rc;
76 }
77 }
78
79 return 0;
80}
81
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020082static int dump_peers(FILE *stream, int indent, time_t now,
83 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020085 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020086 struct gprs_ra_id raid;
87 unsigned int i;
88 const struct rate_ctr_group_desc *desc;
89 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020090
91 rc = fprintf(stream, "%*sPeers:\n", indent, "");
92 if (rc < 0)
93 return rc;
94
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020095 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +020096 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020097 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020098 gsm48_parse_ra(&raid, peer->ra);
99
100 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
101 "RAI %u-%u-%u-%u\n",
102 indent, "",
103 peer->nsei, peer->bvci,
104 peer->blocked ? "" : "not ",
105 raid.mcc, raid.mnc, raid.lac, raid.rac);
106
107 if (rc < 0)
108 return rc;
109
110 desc = peer->ctrg->desc;
111
112 for (i = 0; i < desc->num_ctr; i++) {
113 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
114 if (ctr->current) {
115 rc = fprintf(stream, "%*s %s: %llu\n",
116 indent, "",
117 desc->ctr_desc[i].description,
118 (long long)ctr->current);
119
120 if (rc < 0)
121 return rc;
122 }
123 }
124
125 fprintf(stream, "%*s TLLI-Cache: %d\n",
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200126 indent, "", state->logical_link_count);
127 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200128 char mi_buf[200];
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200129 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200130 int stored_msgs = 0;
131 struct llist_head *iter;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200132 enum gbproxy_match_id match_id;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200133 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200134 stored_msgs++;
135
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200136 if (link_info->imsi_len > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200137 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
138 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200139 link_info->imsi,
140 link_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200141 } else {
142 snprintf(mi_buf, sizeof(mi_buf), "(none)");
143 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200144 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200145 indent, "", link_info->tlli.current);
146 if (link_info->tlli.assigned)
147 fprintf(stream, "/%08x", link_info->tlli.assigned);
148 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200149 fprintf(stream, " -> %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200150 link_info->sgsn_tlli.current);
151 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200152 fprintf(stream, "/%08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200153 link_info->sgsn_tlli.assigned);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200154 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200155 fprintf(stream, ", IMSI %s, AGE %d",
156 mi_buf, (int)age);
157
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200158 if (stored_msgs)
159 fprintf(stream, ", STORED %d", stored_msgs);
160
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200161 for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches);
162 ++match_id) {
163 if (cfg->matches[match_id].enable &&
164 link_info->is_matching[match_id]) {
165 fprintf(stream, ", IMSI matches");
166 break;
167 }
168 }
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200169
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200170 if (link_info->imsi_acq_pending)
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200171 fprintf(stream, ", IMSI acquisition in progress");
172
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200173 if (cfg->route_to_sgsn2)
174 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200175 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200176
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200177 if (link_info->is_deregistered)
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200178 fprintf(stream, ", DE-REGISTERED");
179
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200180 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200181 if (rc < 0)
182 return rc;
183 }
184 }
185
186 return 0;
187}
188
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200189const uint8_t *convert_ra(struct gprs_ra_id *raid)
190{
191 static uint8_t buf[6];
192 gsm48_construct_ra(buf, raid);
193 return buf;
194}
195
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200196/* DTAP - Attach Request */
197static const unsigned char dtap_attach_req[] = {
198 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
199 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
200 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
201 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
202 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
203 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200204};
205
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200206/* DTAP - Attach Request (invalid RAI) */
207static const unsigned char dtap_attach_req2[] = {
208 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
209 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
210 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
211 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
212 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
213 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
214};
215
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200216/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
217static const unsigned char dtap_attach_req3[] = {
218 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
219 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
220 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
221 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
222 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
223 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
224};
225
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200226/* DTAP - Identity Request */
227static const unsigned char dtap_identity_req[] = {
228 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200229};
230
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200231/* DTAP - Identity Response */
232static const unsigned char dtap_identity_resp[] = {
233 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
234 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200235};
236
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200237/* DTAP - Identity Response, IMSI 2 */
238static const unsigned char dtap_identity2_resp[] = {
239 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
240 0x16, 0x17, 0x18
241};
242
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200243/* DTAP - Identity Response, IMSI 3 */
244static const unsigned char dtap_identity3_resp[] = {
245 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
246 0x26, 0x27, 0x28
247};
248
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200249/* DTAP - Attach Accept */
250static const unsigned char dtap_attach_acc[] = {
251 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
252 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
253 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200254};
255
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200256/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200257static const unsigned char dtap_attach_acc2[] = {
258 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
259 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
260 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
261};
262
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200263/* DTAP - Attach Complete */
264static const unsigned char dtap_attach_complete[] = {
265 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200266};
267
Jacob Erlbeck2bf32612014-09-22 11:26:58 +0200268/* DTAP - Attach Reject (GPRS services not allowed) */
269static const unsigned char dtap_attach_rej7[] = {
270 0x08, 0x04, 0x07
271};
272
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200273/* DTAP - GMM Information */
274static const unsigned char dtap_gmm_information[] = {
275 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200276};
277
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200278/* DTAP - Routing Area Update Request */
279static const unsigned char dtap_ra_upd_req[] = {
280 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
281 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
282 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
283 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
284 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
285 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
286 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200287};
288
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200289/* DTAP - Routing Area Update Accept */
290static const unsigned char dtap_ra_upd_acc[] = {
291 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
292 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
293 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200294};
295
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200296/* DTAP - Routing Area Update Accept, P-TMSI 2 */
297static const unsigned char dtap_ra_upd_acc2[] = {
298 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
299 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
300 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
301};
302
303/* DTAP - Routing Area Update Accept, P-TMSI 3 */
304static const unsigned char dtap_ra_upd_acc3[] = {
305 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
306 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
307 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
308};
309
310/* DTAP - Routing Area Update Complete */
311static const unsigned char dtap_ra_upd_complete[] = {
312 0x08, 0x0a
313};
314
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200315/* DTAP - Routing Area Update Reject */
316/* cause = 10 ("Implicitly detached"), force_standby = 0 */
317static const unsigned char dtap_ra_upd_rej[] = {
318 0x08, 0x0b, 0x0a, 0x00,
319};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200321/* DTAP - Activate PDP Context Request */
322static const unsigned char dtap_act_pdp_ctx_req[] = {
323 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200324 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
326 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
327 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
328 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200329 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200330};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200331
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200332/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200333/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200334static const unsigned char dtap_detach_po_req[] = {
335 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
336 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200337};
338
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200339/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200340/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200341static const unsigned char dtap_detach_req[] = {
342 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
343 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200344};
345
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200346/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200347static const unsigned char dtap_detach_acc[] = {
348 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200349};
350
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200351/* DTAP - Detach Request (MT) */
352/* normal detach, reattach required, implicitly detached */
353static const unsigned char dtap_mt_detach_rea_req[] = {
354 0x08, 0x05, 0x01, 0x25, 0x0a
355};
356
357/* DTAP - Detach Request (MT) */
358/* normal detach, reattach not required, implicitly detached */
359static const unsigned char dtap_mt_detach_req[] = {
360 0x08, 0x05, 0x02, 0x25, 0x0a
361};
362
363/* DTAP - Detach Accept (MT) */
364static const unsigned char dtap_mt_detach_acc[] = {
365 0x08, 0x06
366};
367
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200368/* GPRS-LLC - SAPI: LLGMM, U, XID */
369static const unsigned char llc_u_xid_ul[] = {
370 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
371 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
372};
373
374/* GPRS-LLC - SAPI: LLGMM, U, XID */
375static const unsigned char llc_u_xid_dl[] = {
376 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
377 0xe4, 0xa9, 0x1a, 0x9e
378};
379
380/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
381static const unsigned char llc_ui_ll11_dns_query_ul[] = {
382 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
383 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
384 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
385 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
386 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
387 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
388 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
389 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
390 0x8f, 0x07
391};
392
393/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
394static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
395 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
396 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
397 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
398 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
399 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
400 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
401 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
402 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
403 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
404 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
405 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
406 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
407 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
408 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
409 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
410 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
411 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
412 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
413 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
414 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
415 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
416 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
417 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
418 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
419 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
420 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
421};
422
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200423static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
424 struct sockaddr_in *peer, const unsigned char* data,
425 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200426
427static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
428 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
429{
430 /* GPRS Network Service, PDU type: NS_RESET,
431 */
432 unsigned char msg[12] = {
433 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
434 0x04, 0x82, 0x11, 0x22
435 };
436
437 msg[3] = cause;
438 msg[6] = nsvci / 256;
439 msg[7] = nsvci % 256;
440 msg[10] = nsei / 256;
441 msg[11] = nsei % 256;
442
443 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
444}
445
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200446static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
447 uint16_t nsvci, uint16_t nsei)
448{
449 /* GPRS Network Service, PDU type: NS_RESET_ACK,
450 */
451 unsigned char msg[9] = {
452 0x03, 0x01, 0x82, 0x11, 0x22,
453 0x04, 0x82, 0x11, 0x22
454 };
455
456 msg[3] = nsvci / 256;
457 msg[4] = nsvci % 256;
458 msg[7] = nsei / 256;
459 msg[8] = nsei % 256;
460
461 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
462}
463
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200464static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
465{
466 /* GPRS Network Service, PDU type: NS_ALIVE */
467 unsigned char msg[1] = {
468 0x0a
469 };
470
471 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
472}
473
474static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
475{
476 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
477 unsigned char msg[1] = {
478 0x0b
479 };
480
481 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
482}
483
484static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
485{
486 /* GPRS Network Service, PDU type: NS_UNBLOCK */
487 unsigned char msg[1] = {
488 0x06
489 };
490
491 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
492}
493
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200494static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
495{
496 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
497 unsigned char msg[1] = {
498 0x07
499 };
500
501 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
502}
503
504static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
505 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200506 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
507{
508 /* GPRS Network Service, PDU type: NS_UNITDATA */
509 unsigned char msg[4096] = {
510 0x00, 0x00, 0x00, 0x00
511 };
512
513 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
514
515 msg[2] = nsbvci / 256;
516 msg[3] = nsbvci % 256;
517 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
518
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200519 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200520}
521
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200522static void send_bssgp_ul_unitdata(
523 struct gprs_ns_inst *nsi, const char *text,
524 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
525 struct gprs_ra_id *raid, uint16_t cell_id,
526 const uint8_t *llc_msg, size_t llc_msg_size)
527{
528 /* GPRS Network Service, PDU type: NS_UNITDATA */
529 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
530 unsigned char msg[4096] = {
531 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
532 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
533 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
534 };
535
536 size_t bssgp_msg_size = 23 + llc_msg_size;
537
538 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
539
540 gsm48_construct_ra(msg + 10, raid);
541 msg[1] = (uint8_t)(tlli >> 24);
542 msg[2] = (uint8_t)(tlli >> 16);
543 msg[3] = (uint8_t)(tlli >> 8);
544 msg[4] = (uint8_t)(tlli >> 0);
545 msg[16] = cell_id / 256;
546 msg[17] = cell_id % 256;
547 msg[21] = llc_msg_size / 256;
548 msg[22] = llc_msg_size % 256;
549 memcpy(msg + 23, llc_msg, llc_msg_size);
550
551 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
552 src_addr, nsbvci, msg, bssgp_msg_size);
553}
554
555static void send_bssgp_dl_unitdata(
556 struct gprs_ns_inst *nsi, const char *text,
557 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
558 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
559 const uint8_t *llc_msg, size_t llc_msg_size)
560{
561 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
562 unsigned char msg[4096] = {
563 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
564 0x16, 0x82, 0x02, 0x58,
565 };
566 unsigned char racap_drx[] = {
567 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
568 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
569 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
570 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
571 };
572
573 size_t bssgp_msg_size = 0;
574
575 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
576
577 msg[1] = (uint8_t)(tlli >> 24);
578 msg[2] = (uint8_t)(tlli >> 16);
579 msg[3] = (uint8_t)(tlli >> 8);
580 msg[4] = (uint8_t)(tlli >> 0);
581
582 bssgp_msg_size = 12;
583
584 if (with_racap_drx) {
585 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
586 bssgp_msg_size += sizeof(racap_drx);
587 }
588
589 if (imsi) {
590 OSMO_ASSERT(imsi_size <= 127);
591 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
592 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
593 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
594 bssgp_msg_size += 2 + imsi_size;
595 }
596
597 if ((bssgp_msg_size % 4) != 0) {
598 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
599 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
600 msg[bssgp_msg_size + 1] = 0x80 | abytes;
601 memset(msg + bssgp_msg_size + 2, 0, abytes);
602 bssgp_msg_size += 2 + abytes;
603 }
604
605 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
606 if (llc_msg_size < 128) {
607 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
608 bssgp_msg_size += 2;
609 } else {
610 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
611 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
612 bssgp_msg_size += 3;
613 }
614 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
615 bssgp_msg_size += llc_msg_size;
616
617
618 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
619 src_addr, nsbvci, msg, bssgp_msg_size);
620}
621
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200622static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
623 uint16_t bvci)
624{
625 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
626 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200627 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200628 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200629 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
630 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200631 };
632
633 msg[3] = bvci / 256;
634 msg[4] = bvci % 256;
635
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200636 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
637}
638
639static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
640 struct sockaddr_in *src_addr, uint16_t bvci)
641{
642 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
643 * BSSGP RESET_ACK */
644 static unsigned char msg[5] = {
645 0x23, 0x04, 0x82, 0x00,
646 0x00
647 };
648
649 msg[3] = bvci / 256;
650 msg[4] = bvci % 256;
651
652 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200653}
654
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200655static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
656 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200657 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200658 struct gprs_ra_id *raid)
659{
660 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
661 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200662 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
663 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200664 };
665
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200666 msg[3] = (uint8_t)(tlli >> 24);
667 msg[4] = (uint8_t)(tlli >> 16);
668 msg[5] = (uint8_t)(tlli >> 8);
669 msg[6] = (uint8_t)(tlli >> 0);
670
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200671 gsm48_construct_ra(msg + 9, raid);
672
673 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
674}
675
676static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
677 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200678 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200679 struct gprs_ra_id *raid)
680{
681 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
682 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200683 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
684 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200685 0x81, 0x01
686 };
687
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200688 msg[3] = (uint8_t)(tlli >> 24);
689 msg[4] = (uint8_t)(tlli >> 16);
690 msg[5] = (uint8_t)(tlli >> 8);
691 msg[6] = (uint8_t)(tlli >> 0);
692
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200693 gsm48_construct_ra(msg + 9, raid);
694
695 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
696}
697
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200698static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
699 struct sockaddr_in *src_addr,
700 uint16_t bvci, uint32_t tlli,
701 unsigned n_frames, unsigned n_octets)
702{
703 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
704 unsigned char msg[] = {
705 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
706 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
707 /* n octets */ 0xff, 0xff, 0xff
708 };
709
710 msg[3] = (uint8_t)(tlli >> 24);
711 msg[4] = (uint8_t)(tlli >> 16);
712 msg[5] = (uint8_t)(tlli >> 8);
713 msg[6] = (uint8_t)(tlli >> 0);
714 msg[9] = (uint8_t)(n_frames);
715 msg[12] = (uint8_t)(bvci >> 8);
716 msg[13] = (uint8_t)(bvci >> 0);
717 msg[16] = (uint8_t)(n_octets >> 16);
718 msg[17] = (uint8_t)(n_octets >> 8);
719 msg[18] = (uint8_t)(n_octets >> 0);
720
721 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
722}
723
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200724static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
725 struct sockaddr_in *src_addr,
726 uint16_t bvci, uint8_t tag)
727{
728 /* GPRS Network Service, PDU type: NS_UNITDATA,
729 * BSSGP FLOW_CONTROL_BVC */
730 unsigned char msg[] = {
731 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
732 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
733 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
734 };
735
736 msg[3] = tag;
737
738 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
739 msg, sizeof(msg));
740}
741
742static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
743 struct sockaddr_in *src_addr,
744 uint16_t bvci, uint8_t tag)
745{
746 /* GPRS Network Service, PDU type: NS_UNITDATA,
747 * BSSGP FLOW_CONTROL_BVC_ACK */
748 unsigned char msg[] = {
749 0x27, 0x1e, 0x81, /* Tag */ 0xce
750 };
751
752 msg[3] = tag;
753
754 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
755 msg, sizeof(msg));
756}
757
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200758static void send_llc_ul_ui(
759 struct gprs_ns_inst *nsi, const char *text,
760 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
761 struct gprs_ra_id *raid, uint16_t cell_id,
762 unsigned sapi, unsigned nu,
763 const uint8_t *msg, size_t msg_size)
764{
765 unsigned char llc_msg[4096] = {
766 0x00, 0xc0, 0x01
767 };
768
769 size_t llc_msg_size = 3 + msg_size + 3;
770 uint8_t e_bit = 0;
771 uint8_t pm_bit = 1;
772 unsigned fcs;
773
774 nu &= 0x01ff;
775
776 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
777
778 llc_msg[0] = (sapi & 0x0f);
779 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
780 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
781
782 memcpy(llc_msg + 3, msg, msg_size);
783
784 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
785 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
786 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
787 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
788
789 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
790 src_addr, nsbvci, tlli, raid, cell_id,
791 llc_msg, llc_msg_size);
792}
793
794static void send_llc_dl_ui(
795 struct gprs_ns_inst *nsi, const char *text,
796 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
797 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
798 unsigned sapi, unsigned nu,
799 const uint8_t *msg, size_t msg_size)
800{
801 /* GPRS Network Service, PDU type: NS_UNITDATA */
802 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
803 unsigned char llc_msg[4096] = {
804 0x00, 0x00, 0x01
805 };
806
807 size_t llc_msg_size = 3 + msg_size + 3;
808 uint8_t e_bit = 0;
809 uint8_t pm_bit = 1;
810 unsigned fcs;
811
812 nu &= 0x01ff;
813
814 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
815
816 llc_msg[0] = 0x40 | (sapi & 0x0f);
817 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
818 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
819
820 memcpy(llc_msg + 3, msg, msg_size);
821
822 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
823 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
824 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
825 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
826
827 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
828 src_addr, nsbvci, tlli,
829 with_racap_drx, imsi, imsi_size,
830 llc_msg, llc_msg_size);
831}
832
833
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200834static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
835 uint16_t nsvci, uint16_t nsei)
836{
837 printf("Setup NS-VC: remote 0x%08x:%d, "
838 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
839 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
840 nsvci, nsvci, nsei, nsei);
841
842 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
843 send_ns_alive(nsi, src_addr);
844 send_ns_unblock(nsi, src_addr);
845 send_ns_alive_ack(nsi, src_addr);
846}
847
848static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
849 uint16_t bvci)
850{
851 printf("Setup BSSGP: remote 0x%08x:%d, "
852 "BVCI 0x%04x(%d)\n\n",
853 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
854 bvci, bvci);
855
856 send_bssgp_reset(nsi, src_addr, bvci);
857}
858
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200859static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
860 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200861{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200862 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
863 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200864 send_ns_alive_ack(nsi, sgsn_peer);
865 send_ns_unblock_ack(nsi, sgsn_peer);
866 send_ns_alive(nsi, sgsn_peer);
867}
868
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200869static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
870{
871 sgsn_peer->sin_family = AF_INET;
872 sgsn_peer->sin_port = htons(32000);
873 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
874}
875
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200876static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
877{
878 sgsn_peer->sin_family = AF_INET;
879 sgsn_peer->sin_port = htons(32001);
880 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
881}
882
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200883static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
884{
885 size_t i;
886
887 for (i = 0; i < size; ++i) {
888 bss_peers[i].sin_family = AF_INET;
889 bss_peers[i].sin_port = htons((i + 1) * 1111);
890 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
891 }
892}
893
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200894int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
895 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
896
897/* override */
898int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
899 struct msgb *msg, uint16_t bvci)
900{
901 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
902 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200903 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200904
905 switch (event) {
906 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200907 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200908 default:
909 break;
910 }
911 return 0;
912}
913
914/* override */
915ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
916 const struct sockaddr *dest_addr, socklen_t addrlen)
917{
918 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
919 const struct sockaddr *, socklen_t);
920 static sendto_t real_sendto = NULL;
921 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200922 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200923
924 if (!real_sendto)
925 real_sendto = dlsym(RTLD_NEXT, "sendto");
926
927 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200928 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
929 dest_host, dest_port,
930 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200931 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200932 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
933 dest_host, dest_port,
934 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200935 else if (dest_host == REMOTE_SGSN2_ADDR)
936 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
937 dest_host, dest_port,
938 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200939 else
940 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
941
942 return len;
943}
944
945/* override */
946int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
947{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200948 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
949 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200950 uint16_t bvci = msgb_bvci(msg);
951 uint16_t nsei = msgb_nsei(msg);
952
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200953 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200954
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200955 if (!real_gprs_ns_sendmsg)
956 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
957
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200958 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200959 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
960 "msg length %d (%s)\n",
961 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200962 else if (nsei == SGSN2_NSEI)
963 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
964 "msg length %d (%s)\n",
965 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200966 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200967 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
968 "msg length %d (%s)\n",
969 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200970
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200971 if (received_messages) {
972 struct msgb *msg_copy;
973 msg_copy = gprs_msgb_copy(msg, "received_messages");
974 llist_add_tail(&msg_copy->list, received_messages);
975 }
976
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200977 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978}
979
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200980/* Get the next message from the receive FIFO
981 *
982 * \returns a pointer to the message which will be invalidated at the next call
983 * to expect_msg. Returns NULL, if there is no message left.
984 */
985static struct msgb *expect_msg(void)
986{
987 static struct msgb *msg = NULL;
988
989 msgb_free(msg);
990 msg = NULL;
991
992 if (!received_messages)
993 return NULL;
994
995 if (llist_empty(received_messages))
996 return NULL;
997
998 msg = llist_entry(received_messages->next, struct msgb, list);
999 llist_del(&msg->list);
1000
1001 return msg;
1002}
1003
1004struct expect_result {
1005 struct msgb *msg;
1006 struct gprs_gb_parse_context parse_ctx;
1007};
1008
1009static struct expect_result *expect_bssgp_msg(
1010 int match_nsei, int match_bvci, int match_pdu_type)
1011{
1012 static struct expect_result result;
1013 static const struct expect_result empty_result = {0,};
1014 static struct msgb *msg;
1015 uint16_t nsei;
1016 int rc;
1017
1018 memcpy(&result, &empty_result, sizeof(result));
1019
1020 msg = expect_msg();
1021 if (!msg)
1022 return NULL;
1023
1024 nsei = msgb_nsei(msg);
1025
1026 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1027 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1028 __func__, match_nsei, nsei);
1029 return NULL;
1030 }
1031
1032 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1033 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1034 __func__, match_bvci, msgb_bvci(msg));
1035 return NULL;
1036 }
1037
1038 result.msg = msg;
1039
1040 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1041 result.parse_ctx.peer_nsei = nsei;
1042
1043 if (!msgb_bssgph(msg)) {
1044 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1045 return NULL;
1046 }
1047
1048 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1049 &result.parse_ctx);
1050
1051 if (!rc) {
1052 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1053 return NULL;
1054 }
1055
1056 if (match_pdu_type != MATCH_ANY &&
1057 match_pdu_type != result.parse_ctx.pdu_type) {
1058 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1059 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1060 return NULL;
1061 }
1062
1063 return &result;
1064}
1065
1066static struct expect_result *expect_llc_msg(
1067 int match_nsei, int match_bvci, int match_sapi, int match_type)
1068{
1069 static struct expect_result *result;
1070
1071 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1072 if (!result)
1073 return NULL;
1074
1075 if (!result->parse_ctx.llc) {
1076 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1077 return NULL;
1078 }
1079
1080 if (match_sapi != MATCH_ANY &&
1081 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1082 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1083 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1084 return NULL;
1085 }
1086
1087 if (match_type != MATCH_ANY &&
1088 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1089 fprintf(stderr,
1090 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1091 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1092 return NULL;
1093 }
1094
1095 return result;
1096}
1097
1098static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1099 int match_type)
1100{
1101 static struct expect_result *result;
1102
1103 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1104 if (!result)
1105 return NULL;
1106
1107 if (!result->parse_ctx.g48_hdr) {
1108 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1109 return NULL;
1110 }
1111
1112 if (match_type != MATCH_ANY &&
1113 match_type != result->parse_ctx.g48_hdr->msg_type) {
1114 fprintf(stderr,
1115 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1116 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1117 return NULL;
1118 }
1119
1120 return result;
1121}
1122
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001123static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1124 struct rate_ctr_group *ctrg)
1125{
1126 unsigned int i;
1127
1128 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1129 struct rate_ctr *ctr = &ctrg->ctr[i];
1130 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1131 fprintf(stream, " %s%s: %llu%s",
1132 prefix, ctrg->desc->ctr_desc[i].description,
1133 (long long)ctr->current,
1134 "\n");
1135 };
1136}
1137
1138/* Signal handler for signals from NS layer */
1139static int test_signal(unsigned int subsys, unsigned int signal,
1140 void *handler_data, void *signal_data)
1141{
1142 struct ns_signal_data *nssd = signal_data;
1143 int rc;
1144
1145 if (subsys != SS_L_NS)
1146 return 0;
1147
1148 switch (signal) {
1149 case S_NS_RESET:
1150 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1151 nssd->nsvc->nsvci,
1152 gprs_ns_ll_str(nssd->nsvc));
1153 break;
1154
1155 case S_NS_ALIVE_EXP:
1156 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1157 nssd->nsvc->nsvci,
1158 gprs_ns_ll_str(nssd->nsvc));
1159 break;
1160
1161 case S_NS_BLOCK:
1162 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1163 nssd->nsvc->nsvci,
1164 gprs_ns_ll_str(nssd->nsvc));
1165 break;
1166
1167 case S_NS_UNBLOCK:
1168 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1169 nssd->nsvc->nsvci,
1170 gprs_ns_ll_str(nssd->nsvc));
1171 break;
1172
1173 case S_NS_REPLACED:
1174 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1175 nssd->nsvc->nsvci,
1176 gprs_ns_ll_str(nssd->nsvc));
1177 printf(" -> 0x%04x/%s\n",
1178 nssd->old_nsvc->nsvci,
1179 gprs_ns_ll_str(nssd->old_nsvc));
1180 break;
1181
1182 default:
1183 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1184 nssd->nsvc->nsvci,
1185 gprs_ns_ll_str(nssd->nsvc));
1186 break;
1187 }
1188 printf("\n");
1189 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1190 return rc;
1191}
1192
1193static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1194{
1195 struct msgb *msg;
1196 int ret;
1197 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1198 fprintf(stderr, "message too long: %d\n", data_len);
1199 return -1;
1200 }
1201
1202 msg = gprs_ns_msgb_alloc();
1203 memmove(msg->data, data, data_len);
1204 msg->l2h = msg->data;
1205 msgb_put(msg, data_len);
1206
1207 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1208 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1209 osmo_hexdump(data, data_len));
1210
1211 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1212
1213 printf("result (%s) = %d\n\n", text, ret);
1214
1215 msgb_free(msg);
1216
1217 return ret;
1218}
1219
1220static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1221{
1222 struct gprs_nsvc *nsvc;
1223
1224 printf("Current NS-VCIs:\n");
1225 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1226 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001227 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001228 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001229 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1230 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1231 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001232 );
1233 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1234 }
1235 printf("\n");
1236}
1237
1238static void test_gbproxy()
1239{
1240 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1241 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001242 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001243
1244 bssgp_nsi = nsi;
1245 gbcfg.nsi = bssgp_nsi;
1246 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1247
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001248 configure_sgsn_peer(&sgsn_peer);
1249 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001250
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001251 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001252 printf("--- Initialise SGSN ---\n\n");
1253
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001254 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001255 gprs_dump_nsi(nsi);
1256
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001257 printf("--- Initialise BSS 1 ---\n\n");
1258
1259 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1260 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1261 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001262 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001263
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001264 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1265
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001266 printf("--- Initialise BSS 2 ---\n\n");
1267
1268 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1269 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1270 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001271 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001272
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001273 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1274
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001275 printf("--- Move BSS 1 to new port ---\n\n");
1276
1277 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1278 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001279 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001280
1281 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1282
1283 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1284 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001285 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001286
1287 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1288
1289 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1290 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001291 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001292
1293 printf("--- Move BSS 2 to new port ---\n\n");
1294
1295 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1296 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001297 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001298
1299 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1300
1301 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1302 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001304
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001305 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1306
1307 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1308 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001309 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001310
1311 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1312
1313 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1314 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001315 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001316
1317 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1318
1319 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1320
1321 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1322 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001323 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001324
1325 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1326
1327 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1328
1329 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1330 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001331 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001332
1333 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1334
1335 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1336
1337 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1338
1339 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1340
1341 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1342
1343 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1344
1345 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1346
1347 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1348
1349 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1350
1351 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1352
1353 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1354
1355 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1356
1357 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1358
1359 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1360
1361 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1362 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001363 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001364
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001365 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001366
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001367 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1368
1369 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1370
1371 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1372
1373 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1374
1375 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1376
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001377 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1378
1379 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1380
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001381 /* Find peer */
1382 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1383 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1384 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1385 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1386 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1387 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1388
1389
1390 /* Cleanup */
1391 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1392 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1393 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1394 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1395 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1396
1397 dump_peers(stdout, 0, 0, &gbcfg);
1398
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001399 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001400
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001401 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001402 gprs_ns_destroy(nsi);
1403 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001404}
1405
1406static void test_gbproxy_ident_changes()
1407{
1408 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1409 struct sockaddr_in bss_peer[1] = {{0},};
1410 struct sockaddr_in sgsn_peer= {0};
1411 uint16_t nsei[2] = {0x1000, 0x2000};
1412 uint16_t nsvci[2] = {0x1001, 0x2001};
1413 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1414
1415 bssgp_nsi = nsi;
1416 gbcfg.nsi = bssgp_nsi;
1417 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1418
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001419 configure_sgsn_peer(&sgsn_peer);
1420 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001421
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001422 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001423 printf("--- Initialise SGSN ---\n\n");
1424
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001425 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001426 gprs_dump_nsi(nsi);
1427
1428 printf("--- Initialise BSS 1 ---\n\n");
1429
1430 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1431 gprs_dump_nsi(nsi);
1432
1433 printf("--- Setup BVCI 1 ---\n\n");
1434
1435 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1436 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001437 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001438
1439 printf("--- Setup BVCI 2 ---\n\n");
1440
1441 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1442 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001443 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001444
1445 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1446
1447 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1448 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1449
1450 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1451
1452 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1453 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1454
1455 printf("--- Change NSEI ---\n\n");
1456
1457 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1458 gprs_dump_nsi(nsi);
1459
1460 printf("--- Setup BVCI 1 ---\n\n");
1461
1462 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1463 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001464 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001465
1466 printf("--- Setup BVCI 3 ---\n\n");
1467
1468 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1469 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001470 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001471
1472 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1473
1474 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1475 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1476
1477 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1478 " (should fail) ---\n\n");
1479
1480 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001481 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001482 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001483 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001484
1485 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1486
1487 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1488 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1489
1490 printf("--- Change NSVCI ---\n\n");
1491
1492 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1493 gprs_dump_nsi(nsi);
1494
1495 printf("--- Setup BVCI 1 ---\n\n");
1496
1497 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1498 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001499 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001500
1501 printf("--- Setup BVCI 4 ---\n\n");
1502
1503 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1504 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001505 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001506
1507 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1508
1509 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1510 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1511
1512 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1513 " (should fail) ---\n\n");
1514
1515 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001516 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001517 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001518 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001519
1520 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1521
1522 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1523 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1524
1525 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1526
1527 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1528 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1529
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001530 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001531 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001532
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001533 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001534 gprs_ns_destroy(nsi);
1535 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001536}
1537
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001538static void test_gbproxy_ra_patching()
1539{
1540 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1541 struct sockaddr_in bss_peer[1] = {{0},};
1542 struct sockaddr_in sgsn_peer= {0};
1543 struct gprs_ra_id rai_bss =
1544 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1545 struct gprs_ra_id rai_sgsn =
1546 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1547 struct gprs_ra_id rai_unknown =
1548 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001549 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001550 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001551 const uint32_t ptmsi = 0xefe2b700;
1552 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001554 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001555 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001556 const char *patch_re = "^9898|^121314";
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001557 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001558 struct gbproxy_peer *peer;
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001559 LLIST_HEAD(rcv_list);
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001560 struct expect_result *expect_res;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001561
1562 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001563
1564 bssgp_nsi = nsi;
1565 gbcfg.nsi = bssgp_nsi;
1566 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001567 gbcfg.core_mcc = 123;
1568 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001569 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001570 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001571 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001572
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001573 configure_sgsn_peer(&sgsn_peer);
1574 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001575
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001576 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
1577 patch_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001578 fprintf(stderr, "Failed to compile RE '%s': %s\n",
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001579 patch_re, err_msg);
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001580 exit(1);
1581 }
1582
1583
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001584 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001585 printf("--- Initialise SGSN ---\n\n");
1586
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001587 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001588 gprs_dump_nsi(nsi);
1589
1590 printf("--- Initialise BSS 1 ---\n\n");
1591
1592 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001593
1594 received_messages = &rcv_list;
1595
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001596 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1597 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001598 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001599
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001600 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001601 OSMO_ASSERT(peer != NULL);
1602
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001603 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1604
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001605 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1606
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001607 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1608
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001609 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001610
1611 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1612
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001613 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001614
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001615 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1616
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001617 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001618 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001619
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001620 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1621 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1622
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001623 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1624
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001625 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1626 foreign_tlli, &rai_bss, cell_id,
1627 GPRS_SAPI_GMM, 0,
1628 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001629
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001630 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001631 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001632
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001633 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1634 foreign_tlli, 0, NULL, 0,
1635 GPRS_SAPI_GMM, 0,
1636 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001637
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001638 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1639
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001640 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1641 foreign_tlli, &rai_bss, cell_id,
1642 GPRS_SAPI_GMM, 3,
1643 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001644
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001645 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1646
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001647 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1648 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1649
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001650 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1651 foreign_tlli, 1, imsi, sizeof(imsi),
1652 GPRS_SAPI_GMM, 1,
1653 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001654
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001655 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1656
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001657 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1658
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001659 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1660 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1661 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1662
1663 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1664 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1665 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1666
1667 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1668 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1669 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1670
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001671 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1672 OSMO_ASSERT(link_info);
1673 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1674 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1675 OSMO_ASSERT(!link_info->tlli.bss_validated);
1676 OSMO_ASSERT(!link_info->tlli.net_validated);
1677 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1678 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1679 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1680 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001681
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001682 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1683 local_tlli, &rai_bss, cell_id,
1684 GPRS_SAPI_GMM, 4,
1685 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001686
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001687 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1688
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001689 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1690
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001691 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1692 OSMO_ASSERT(link_info);
1693 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1694 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1695 OSMO_ASSERT(link_info->tlli.bss_validated);
1696 OSMO_ASSERT(!link_info->tlli.net_validated);
1697 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1698 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1699 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1700 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001701
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001702 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001703 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1704 local_tlli, &rai_bss, cell_id,
1705 GPRS_SAPI_GMM, 3,
1706 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001707
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001708 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1709
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001710 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1711
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001712 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1713 OSMO_ASSERT(link_info);
1714 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1715 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1716 OSMO_ASSERT(link_info->tlli.bss_validated);
1717 OSMO_ASSERT(!link_info->tlli.net_validated);
1718 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1719 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1720 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1721 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001722
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001723 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1724 local_tlli, 1, imsi, sizeof(imsi),
1725 GPRS_SAPI_GMM, 2,
1726 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001727
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001728 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1729
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001730 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1731
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001732 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1733 OSMO_ASSERT(link_info);
1734 OSMO_ASSERT(link_info->tlli.assigned == 0);
1735 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1736 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1737 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001738
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001739 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001740 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1741 local_tlli, &rai_bss, cell_id,
1742 GPRS_SAPI_GMM, 3,
1743 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001744
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001745 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1746 OSMO_ASSERT(expect_res != NULL);
1747 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001748
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001749 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1750
Jacob Erlbeck73685282014-05-23 20:48:07 +02001751 gbcfg.core_apn[0] = 0;
1752 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001753
1754 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001755 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1756 local_tlli, &rai_bss, cell_id,
1757 GPRS_SAPI_GMM, 3,
1758 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001759
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001760 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1761 OSMO_ASSERT(expect_res != NULL);
1762 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001763
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001764 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1765
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001766 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001767
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001768 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001769 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1770 local_tlli, &rai_bss, cell_id,
1771 GPRS_SAPI_GMM, 6,
1772 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001773
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001774 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1775
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001776 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1777 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1778
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001779 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1780 local_tlli, 1, imsi, sizeof(imsi),
1781 GPRS_SAPI_GMM, 5,
1782 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001783
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001784 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1785
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001786 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001787
1788 printf("--- RA update ---\n\n");
1789
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001790 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1791 foreign_tlli, &rai_bss, 0x7080,
1792 GPRS_SAPI_GMM, 5,
1793 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001794
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001795 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1796
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001797 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1798
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001799 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1800 foreign_tlli, 1, imsi, sizeof(imsi),
1801 GPRS_SAPI_GMM, 6,
1802 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001803
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001804 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1805
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001806 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1807
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001808 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001809 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1810 local_tlli, &rai_bss, cell_id,
1811 GPRS_SAPI_GMM, 3,
1812 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001813
Jacob Erlbeckc79beec2014-10-10 09:48:12 +02001814 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1815 OSMO_ASSERT(expect_res != NULL);
1816 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001817
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001818 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1819
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001820 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001821
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001822 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001823 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1824 local_tlli, &rai_bss, cell_id,
1825 GPRS_SAPI_GMM, 6,
1826 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001827
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001828 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1829
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001830 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1831
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001832 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001833 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001834
1835 printf("--- Bad cases ---\n\n");
1836
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001837 /* The RAI in the Attach Request message differs from the RAI in the
1838 * BSSGP message, only patch the latter */
1839
1840 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1841 foreign_tlli2, &rai_bss, cell_id,
1842 GPRS_SAPI_GMM, 0,
1843 dtap_attach_req2, sizeof(dtap_attach_req2));
1844
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001845 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1846
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001847 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1848
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001849 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001850 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1851 local_tlli, &rai_bss, cell_id,
1852 GPRS_SAPI_GMM, 3,
1853 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001854
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001855 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1856
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001857 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001858 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001859
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001860 /* TODO: The following breaks with the current libosmocore, enable it
1861 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1862 * is integrated */
1863 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1864 OSMO_ASSERT(expect_msg());
1865
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001866 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001867 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001868
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001869 OSMO_ASSERT(!expect_msg());
1870 received_messages = NULL;
1871
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02001872 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001873 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001874 gprs_ns_destroy(nsi);
1875 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001876}
1877
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001878static void test_gbproxy_ptmsi_assignment()
1879{
1880 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1881 struct sockaddr_in bss_peer[1] = {{0},};
1882 struct sockaddr_in sgsn_peer= {0};
1883 struct gprs_ra_id rai_bss =
1884 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1885 struct gprs_ra_id rai_unknown =
1886 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1887 uint16_t cell_id = 0x1234;
1888
1889 const uint32_t ptmsi = 0xefe2b700;
1890 const uint32_t local_tlli = 0xefe2b700;
1891
1892 const uint32_t foreign_tlli1 = 0x8000dead;
1893 const uint32_t foreign_tlli2 = 0x8000beef;
1894
1895 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1896 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1897
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001898 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001899 struct gbproxy_peer *peer;
1900 unsigned bss_nu = 0;
1901 unsigned sgsn_nu = 0;
1902
1903 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1904
1905 bssgp_nsi = nsi;
1906 gbcfg.nsi = bssgp_nsi;
1907 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1908 gbcfg.core_mcc = 0;
1909 gbcfg.core_mnc = 0;
1910 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1911 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1912 gbcfg.patch_ptmsi = 0;
1913 gbcfg.bss_ptmsi_state = 0;
1914 gbcfg.sgsn_tlli_state = 1;
1915
1916 configure_sgsn_peer(&sgsn_peer);
1917 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1918
1919 printf("=== %s ===\n", __func__);
1920 printf("--- Initialise SGSN ---\n\n");
1921
1922 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1923
1924 printf("--- Initialise BSS 1 ---\n\n");
1925
1926 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1927 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1928
1929 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1930 OSMO_ASSERT(peer != NULL);
1931
1932 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1933
1934 gprs_dump_nsi(nsi);
1935 dump_global(stdout, 0);
1936 dump_peers(stdout, 0, 0, &gbcfg);
1937
1938 printf("--- Establish first LLC connection ---\n\n");
1939
1940 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1941 foreign_tlli1, &rai_unknown, cell_id,
1942 GPRS_SAPI_GMM, bss_nu++,
1943 dtap_attach_req, sizeof(dtap_attach_req));
1944
1945 dump_peers(stdout, 0, 0, &gbcfg);
1946
1947 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1948 foreign_tlli1, 0, NULL, 0,
1949 GPRS_SAPI_GMM, sgsn_nu++,
1950 dtap_identity_req, sizeof(dtap_identity_req));
1951
1952 dump_peers(stdout, 0, 0, &gbcfg);
1953
1954 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1955 foreign_tlli1, &rai_bss, cell_id,
1956 GPRS_SAPI_GMM, bss_nu++,
1957 dtap_identity_resp, sizeof(dtap_identity_resp));
1958
1959 dump_peers(stdout, 0, 0, &gbcfg);
1960
1961 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1962 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1963 GPRS_SAPI_GMM, sgsn_nu++,
1964 dtap_attach_acc, sizeof(dtap_attach_acc));
1965
1966 dump_peers(stdout, 0, 0, &gbcfg);
1967
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001968 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1969 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1970 OSMO_ASSERT(link_info);
1971 OSMO_ASSERT(link_info == link_info2);
1972 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1973 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1974 OSMO_ASSERT(!link_info->tlli.bss_validated);
1975 OSMO_ASSERT(!link_info->tlli.net_validated);
1976 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001977
1978 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1979 local_tlli, &rai_bss, cell_id,
1980 GPRS_SAPI_GMM, bss_nu++,
1981 dtap_attach_complete, sizeof(dtap_attach_complete));
1982
1983 dump_peers(stdout, 0, 0, &gbcfg);
1984
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001985 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1986 OSMO_ASSERT(link_info);
1987 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1988 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1989 OSMO_ASSERT(link_info->tlli.bss_validated);
1990 OSMO_ASSERT(!link_info->tlli.net_validated);
1991 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001992
1993
1994 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1995 local_tlli, 1, imsi1, sizeof(imsi1),
1996 GPRS_SAPI_GMM, sgsn_nu++,
1997 dtap_gmm_information, sizeof(dtap_gmm_information));
1998
1999 dump_peers(stdout, 0, 0, &gbcfg);
2000
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002001 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
2002 OSMO_ASSERT(link_info);
2003 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2004 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002005
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002006 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2007 OSMO_ASSERT(link_info == link_info2);
2008 OSMO_ASSERT(link_info->tlli.assigned == 0);
2009 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2010 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002011
2012 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2013
2014 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2015 foreign_tlli2, &rai_unknown, cell_id,
2016 GPRS_SAPI_GMM, bss_nu++,
2017 dtap_attach_req, sizeof(dtap_attach_req));
2018
2019 dump_peers(stdout, 0, 0, &gbcfg);
2020
2021 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2022 foreign_tlli2, 0, NULL, 0,
2023 GPRS_SAPI_GMM, sgsn_nu++,
2024 dtap_identity_req, sizeof(dtap_identity_req));
2025
2026 dump_peers(stdout, 0, 0, &gbcfg);
2027
2028 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2029 foreign_tlli2, &rai_bss, cell_id,
2030 GPRS_SAPI_GMM, bss_nu++,
2031 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2032
2033 dump_peers(stdout, 0, 0, &gbcfg);
2034
2035 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2036 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2037 GPRS_SAPI_GMM, sgsn_nu++,
2038 dtap_attach_acc, sizeof(dtap_attach_acc));
2039
2040 dump_peers(stdout, 0, 0, &gbcfg);
2041
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002042 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2043 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2044 OSMO_ASSERT(link_info);
2045 OSMO_ASSERT(link_info == link_info2);
2046 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2047 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2048 OSMO_ASSERT(!link_info->tlli.bss_validated);
2049 OSMO_ASSERT(!link_info->tlli.net_validated);
2050 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002051
2052 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2053 local_tlli, &rai_bss, cell_id,
2054 GPRS_SAPI_GMM, bss_nu++,
2055 dtap_attach_complete, sizeof(dtap_attach_complete));
2056
2057 dump_peers(stdout, 0, 0, &gbcfg);
2058
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002059 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2060 OSMO_ASSERT(link_info);
2061 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2062 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2063 OSMO_ASSERT(link_info->tlli.bss_validated);
2064 OSMO_ASSERT(!link_info->tlli.net_validated);
2065 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002066
2067 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2068 local_tlli, 1, imsi2, sizeof(imsi2),
2069 GPRS_SAPI_GMM, sgsn_nu++,
2070 dtap_gmm_information, sizeof(dtap_gmm_information));
2071
2072 dump_peers(stdout, 0, 0, &gbcfg);
2073
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002074 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2075 OSMO_ASSERT(link_info);
2076 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2077 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002078
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002079 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2080 OSMO_ASSERT(link_info == link_info2);
2081 OSMO_ASSERT(link_info->tlli.assigned == 0);
2082 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2083 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002084
2085 dump_global(stdout, 0);
2086
2087 gbprox_reset(&gbcfg);
2088 gprs_ns_destroy(nsi);
2089 nsi = NULL;
2090}
2091
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002092static void test_gbproxy_ptmsi_patching()
2093{
2094 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2095 struct sockaddr_in bss_peer[1] = {{0},};
2096 struct sockaddr_in sgsn_peer= {0};
2097 struct gprs_ra_id rai_bss =
2098 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2099 struct gprs_ra_id rai_sgsn =
2100 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002101 struct gprs_ra_id rai_wrong_mcc_sgsn =
2102 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002103 struct gprs_ra_id rai_unknown =
2104 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2105 uint16_t cell_id = 0x1234;
2106
2107 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002108 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2109 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002110 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002111 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2112 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002113 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002114 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002115
2116 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002117 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2118 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002119 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002120 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2121 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002122 const uint32_t foreign_bss_tlli = 0x8000dead;
2123
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002124
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002125 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002126 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002127 struct gbproxy_peer *peer;
2128 unsigned bss_nu = 0;
2129 unsigned sgsn_nu = 0;
2130
2131 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002132 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2133 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2134 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2135 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2136 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002137
2138 bssgp_nsi = nsi;
2139 gbcfg.nsi = bssgp_nsi;
2140 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2141 gbcfg.core_mcc = 123;
2142 gbcfg.core_mnc = 456;
2143 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2144 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2145 gbcfg.patch_ptmsi = 1;
2146 gbcfg.bss_ptmsi_state = 0;
2147 gbcfg.sgsn_tlli_state = 1;
2148
2149 configure_sgsn_peer(&sgsn_peer);
2150 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2151
2152 printf("=== %s ===\n", __func__);
2153 printf("--- Initialise SGSN ---\n\n");
2154
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002155 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002156
2157 printf("--- Initialise BSS 1 ---\n\n");
2158
2159 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2160 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2161
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002162 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002163 OSMO_ASSERT(peer != NULL);
2164
2165 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2166
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002167 gprs_dump_nsi(nsi);
2168 dump_global(stdout, 0);
2169 dump_peers(stdout, 0, 0, &gbcfg);
2170
2171 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2172
2173 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2174 foreign_bss_tlli, &rai_unknown, cell_id,
2175 GPRS_SAPI_GMM, bss_nu++,
2176 dtap_attach_req, sizeof(dtap_attach_req));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
2180 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2181 random_sgsn_tlli, 0, NULL, 0,
2182 GPRS_SAPI_GMM, sgsn_nu++,
2183 dtap_identity_req, sizeof(dtap_identity_req));
2184
2185 dump_peers(stdout, 0, 0, &gbcfg);
2186
2187 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2188 foreign_bss_tlli, &rai_bss, cell_id,
2189 GPRS_SAPI_GMM, bss_nu++,
2190 dtap_identity_resp, sizeof(dtap_identity_resp));
2191
2192 dump_peers(stdout, 0, 0, &gbcfg);
2193
2194 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2195 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2196 GPRS_SAPI_GMM, sgsn_nu++,
2197 dtap_attach_acc, sizeof(dtap_attach_acc));
2198
2199 dump_peers(stdout, 0, 0, &gbcfg);
2200
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002201 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2202 OSMO_ASSERT(link_info);
2203 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2204 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2205 OSMO_ASSERT(!link_info->tlli.bss_validated);
2206 OSMO_ASSERT(!link_info->tlli.net_validated);
2207 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2208 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2209 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2210 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2211 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2212 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002213
2214 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2215 local_bss_tlli, &rai_bss, cell_id,
2216 GPRS_SAPI_GMM, bss_nu++,
2217 dtap_attach_complete, sizeof(dtap_attach_complete));
2218
2219 dump_peers(stdout, 0, 0, &gbcfg);
2220
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002221 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2222 OSMO_ASSERT(link_info);
2223 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2224 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2225 OSMO_ASSERT(link_info->tlli.bss_validated);
2226 OSMO_ASSERT(!link_info->tlli.net_validated);
2227 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2228 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2229 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2230 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002231
2232 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2233 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2234 GPRS_SAPI_GMM, sgsn_nu++,
2235 dtap_gmm_information, sizeof(dtap_gmm_information));
2236
2237 dump_peers(stdout, 0, 0, &gbcfg);
2238
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002239 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2240 OSMO_ASSERT(link_info);
2241 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2242 OSMO_ASSERT(link_info->tlli.assigned == 0);
2243 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2244 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002245
Jacob Erlbeck82add782014-09-05 18:08:12 +02002246 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2247 local_bss_tlli, &rai_bss, cell_id,
2248 GPRS_SAPI_GMM, bss_nu++,
2249 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2250
2251 dump_peers(stdout, 0, 0, &gbcfg);
2252
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002253 /* Non-DTAP */
2254 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2255 local_bss_tlli, &rai_bss, cell_id,
2256 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2257
2258 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2259 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2260 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2261
2262 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2263 local_bss_tlli, &rai_bss, cell_id,
2264 llc_ui_ll11_dns_query_ul,
2265 sizeof(llc_ui_ll11_dns_query_ul));
2266
2267 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2268 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2269 llc_ui_ll11_dns_resp_dl,
2270 sizeof(llc_ui_ll11_dns_resp_dl));
2271
2272 dump_peers(stdout, 0, 0, &gbcfg);
2273
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002274 /* Repeated RA Update Requests */
2275 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2276 local_bss_tlli, &rai_bss, 0x7080,
2277 GPRS_SAPI_GMM, bss_nu++,
2278 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2279
2280 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2281 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002287 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2288 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2289 OSMO_ASSERT(link_info);
2290 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2291 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2292 OSMO_ASSERT(!link_info->tlli.bss_validated);
2293 OSMO_ASSERT(!link_info->tlli.net_validated);
2294 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2295 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2296 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2297 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2298 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2299 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002300
2301 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2302 local_bss_tlli2, &rai_bss, 0x7080,
2303 GPRS_SAPI_GMM, bss_nu++,
2304 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2305
2306 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2307 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2308 GPRS_SAPI_GMM, sgsn_nu++,
2309 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2310
2311 dump_peers(stdout, 0, 0, &gbcfg);
2312
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002313 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2314 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2315 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2316 OSMO_ASSERT(link_info);
2317 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2318 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2319 OSMO_ASSERT(!link_info->tlli.bss_validated);
2320 OSMO_ASSERT(!link_info->tlli.net_validated);
2321 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2322 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2323 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2324 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2325 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2326 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002327
2328 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2329 local_bss_tlli3, &rai_bss, 0x7080,
2330 GPRS_SAPI_GMM, bss_nu++,
2331 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2332
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002333 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002334
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002335 OSMO_ASSERT(link_info);
2336 OSMO_ASSERT(link_info->tlli.bss_validated);
2337 OSMO_ASSERT(!link_info->tlli.net_validated);
2338 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2339 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002340
2341 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2342 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2343 GPRS_SAPI_GMM, sgsn_nu++,
2344 dtap_gmm_information, sizeof(dtap_gmm_information));
2345
2346 dump_peers(stdout, 0, 0, &gbcfg);
2347
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002348 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2349 OSMO_ASSERT(link_info);
2350 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2351 OSMO_ASSERT(link_info->tlli.assigned == 0);
2352 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2353 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002354
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002355 /* Other messages */
2356 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002357 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002358
2359 dump_peers(stdout, 0, 0, &gbcfg);
2360
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002361 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002362
2363 dump_peers(stdout, 0, 0, &gbcfg);
2364
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002365 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002366
2367 dump_peers(stdout, 0, 0, &gbcfg);
2368
2369 /* Bad case: Invalid BVCI */
2370 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002371 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002372 dump_global(stdout, 0);
2373
2374 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002375 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002376
2377 dump_global(stdout, 0);
2378
2379 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002380 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002381 &rai_wrong_mcc_sgsn);
2382
2383 dump_global(stdout, 0);
2384
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002385 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2386 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2387 unknown_sgsn_tlli, 1, NULL, 0,
2388 GPRS_SAPI_GMM, 2,
2389 dtap_gmm_information, sizeof(dtap_gmm_information));
2390
2391 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2392 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2393 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2394 GPRS_SAPI_GMM, 3,
2395 dtap_gmm_information, sizeof(dtap_gmm_information));
2396
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002397 /* Detach */
2398 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002399 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002400 GPRS_SAPI_GMM, bss_nu++,
2401 dtap_detach_req, sizeof(dtap_detach_req));
2402
2403 dump_peers(stdout, 0, 0, &gbcfg);
2404
2405 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002406 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002407 GPRS_SAPI_GMM, sgsn_nu++,
2408 dtap_detach_acc, sizeof(dtap_detach_acc));
2409
2410 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002411
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002412 dump_global(stdout, 0);
2413
2414 gbprox_reset(&gbcfg);
2415 gprs_ns_destroy(nsi);
2416 nsi = NULL;
2417}
2418
Jacob Erlbecke99c3332014-10-20 16:25:01 +02002419static void test_gbproxy_ptmsi_patching_bad_cases()
2420{
2421 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2422 struct sockaddr_in bss_peer[1] = {{0},};
2423 struct sockaddr_in sgsn_peer= {0};
2424 struct gprs_ra_id rai_bss =
2425 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2426 struct gprs_ra_id rai_unknown =
2427 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2428 uint16_t cell_id = 0x1234;
2429
2430 const uint32_t sgsn_ptmsi = 0xefe2b700;
2431 const uint32_t local_sgsn_tlli = 0xefe2b700;
2432 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2433
2434 const uint32_t bss_ptmsi = 0xc00f7304;
2435 const uint32_t local_bss_tlli = 0xc00f7304;
2436 const uint32_t foreign_bss_tlli = 0x8000dead;
2437
2438
2439 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2440 struct gbproxy_link_info *link_info;
2441 struct gbproxy_peer *peer;
2442 unsigned bss_nu = 0;
2443 unsigned sgsn_nu = 0;
2444
2445 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2446 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2447
2448 bssgp_nsi = nsi;
2449 gbcfg.nsi = bssgp_nsi;
2450 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2451 gbcfg.core_mcc = 123;
2452 gbcfg.core_mnc = 456;
2453 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2454 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2455 gbcfg.patch_ptmsi = 1;
2456 gbcfg.bss_ptmsi_state = 0;
2457 gbcfg.sgsn_tlli_state = 1;
2458
2459 configure_sgsn_peer(&sgsn_peer);
2460 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2461
2462 printf("=== %s ===\n", __func__);
2463 printf("--- Initialise SGSN ---\n\n");
2464
2465 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2466
2467 printf("--- Initialise BSS 1 ---\n\n");
2468
2469 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2470 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2471
2472 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2473 OSMO_ASSERT(peer != NULL);
2474
2475 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2476
2477 gprs_dump_nsi(nsi);
2478 dump_global(stdout, 0);
2479 dump_peers(stdout, 0, 0, &gbcfg);
2480
2481 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2482
2483 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2484 foreign_bss_tlli, &rai_unknown, cell_id,
2485 GPRS_SAPI_GMM, bss_nu++,
2486 dtap_attach_req, sizeof(dtap_attach_req));
2487
2488 dump_peers(stdout, 0, 0, &gbcfg);
2489
2490 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2491 random_sgsn_tlli, 0, NULL, 0,
2492 GPRS_SAPI_GMM, sgsn_nu++,
2493 dtap_identity_req, sizeof(dtap_identity_req));
2494
2495 dump_peers(stdout, 0, 0, &gbcfg);
2496
2497 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2498 foreign_bss_tlli, &rai_bss, cell_id,
2499 GPRS_SAPI_GMM, bss_nu++,
2500 dtap_identity_resp, sizeof(dtap_identity_resp));
2501
2502 dump_peers(stdout, 0, 0, &gbcfg);
2503
2504 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2505 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2506 GPRS_SAPI_GMM, sgsn_nu++,
2507 dtap_attach_acc, sizeof(dtap_attach_acc));
2508
2509 dump_peers(stdout, 0, 0, &gbcfg);
2510
2511 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2512 OSMO_ASSERT(link_info);
2513 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2514 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2515 OSMO_ASSERT(!link_info->tlli.bss_validated);
2516 OSMO_ASSERT(!link_info->tlli.net_validated);
2517 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2518 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2519 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2520 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2521 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2522 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2523
2524 send_llc_dl_ui(nsi, "ATTACH ACCEPT (duplicated)", &sgsn_peer, 0x1002,
2525 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2526 GPRS_SAPI_GMM, sgsn_nu++,
2527 dtap_attach_acc, sizeof(dtap_attach_acc));
2528
2529 dump_peers(stdout, 0, 0, &gbcfg);
2530
2531 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2532 OSMO_ASSERT(link_info);
2533 /* OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); */
2534 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2535 OSMO_ASSERT(!link_info->tlli.bss_validated);
2536 OSMO_ASSERT(!link_info->tlli.net_validated);
2537 /* OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi); */
2538 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2539 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2540 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2541 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2542 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2543
2544 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2545 local_bss_tlli, &rai_bss, cell_id,
2546 GPRS_SAPI_GMM, bss_nu++,
2547 dtap_attach_complete, sizeof(dtap_attach_complete));
2548
2549 dump_peers(stdout, 0, 0, &gbcfg);
2550
2551 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2552 OSMO_ASSERT(link_info);
2553 /* OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli); */
2554 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2555 /* OSMO_ASSERT(link_info->tlli.bss_validated); */
2556 OSMO_ASSERT(!link_info->tlli.net_validated);
2557 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2558 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2559 /* OSMO_ASSERT(link_info->sgsn_tlli.bss_validated); */
2560 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2561
2562 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2563 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2564 GPRS_SAPI_GMM, sgsn_nu++,
2565 dtap_gmm_information, sizeof(dtap_gmm_information));
2566
2567 dump_peers(stdout, 0, 0, &gbcfg);
2568
2569 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2570 OSMO_ASSERT(link_info);
2571 /* OSMO_ASSERT(link_info->tlli.current == local_bss_tlli); */
2572 /* OSMO_ASSERT(link_info->tlli.assigned == 0); */
2573 /* OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli); */
2574 /* OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0); */
2575
2576 /* Detach */
2577 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2578 local_bss_tlli, &rai_bss, cell_id,
2579 GPRS_SAPI_GMM, bss_nu++,
2580 dtap_detach_req, sizeof(dtap_detach_req));
2581
2582 dump_peers(stdout, 0, 0, &gbcfg);
2583
2584 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2585 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2586 GPRS_SAPI_GMM, sgsn_nu++,
2587 dtap_detach_acc, sizeof(dtap_detach_acc));
2588
2589 dump_peers(stdout, 0, 0, &gbcfg);
2590
2591 dump_global(stdout, 0);
2592
2593 gbprox_reset(&gbcfg);
2594 gprs_ns_destroy(nsi);
2595 nsi = NULL;
2596}
2597
2598
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002599static void test_gbproxy_imsi_acquisition()
2600{
2601 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2602 struct sockaddr_in bss_peer[1] = {{0},};
2603 struct sockaddr_in sgsn_peer= {0};
2604 struct gprs_ra_id rai_bss =
2605 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2606 struct gprs_ra_id rai_sgsn =
2607 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2608 struct gprs_ra_id rai_wrong_mcc_sgsn =
2609 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2610 struct gprs_ra_id rai_unknown =
2611 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2612 uint16_t cell_id = 0x1234;
2613
2614 const uint32_t sgsn_ptmsi = 0xefe2b700;
2615 const uint32_t local_sgsn_tlli = 0xefe2b700;
2616 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002617 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002618
2619 const uint32_t bss_ptmsi = 0xc00f7304;
2620 const uint32_t local_bss_tlli = 0xc00f7304;
2621 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002622 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002623
2624 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002625 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002626 struct gbproxy_peer *peer;
2627 unsigned bss_nu = 0;
2628 unsigned sgsn_nu = 0;
2629
2630 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2631
2632 bssgp_nsi = nsi;
2633 gbcfg.nsi = bssgp_nsi;
2634 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2635 gbcfg.core_mcc = 123;
2636 gbcfg.core_mnc = 456;
2637 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2638 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2639 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002640 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002641 gbcfg.bss_ptmsi_state = 0;
2642 gbcfg.sgsn_tlli_state = 1;
2643
2644 configure_sgsn_peer(&sgsn_peer);
2645 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2646
2647 printf("=== %s ===\n", __func__);
2648 printf("--- Initialise SGSN ---\n\n");
2649
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002650 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002651
2652 printf("--- Initialise BSS 1 ---\n\n");
2653
2654 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2655 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2656
2657 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2658 OSMO_ASSERT(peer != NULL);
2659
2660 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2661
2662 gprs_dump_nsi(nsi);
2663 dump_global(stdout, 0);
2664 dump_peers(stdout, 0, 0, &gbcfg);
2665
2666 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2667
2668 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002669 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002670 GPRS_SAPI_GMM, bss_nu++,
2671 dtap_attach_req, sizeof(dtap_attach_req));
2672
2673 dump_peers(stdout, 0, 0, &gbcfg);
2674
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002675 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2676 foreign_bss_tlli, &rai_bss, cell_id,
2677 GPRS_SAPI_GMM, bss_nu++,
2678 dtap_identity_resp, sizeof(dtap_identity_resp));
2679
2680 dump_peers(stdout, 0, 0, &gbcfg);
2681
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002682 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2683 random_sgsn_tlli, 0, NULL, 0,
2684 GPRS_SAPI_GMM, sgsn_nu++,
2685 dtap_identity_req, sizeof(dtap_identity_req));
2686
2687 dump_peers(stdout, 0, 0, &gbcfg);
2688
2689 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2690 foreign_bss_tlli, &rai_bss, cell_id,
2691 GPRS_SAPI_GMM, bss_nu++,
2692 dtap_identity_resp, sizeof(dtap_identity_resp));
2693
2694 dump_peers(stdout, 0, 0, &gbcfg);
2695
2696 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2697 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2698 GPRS_SAPI_GMM, sgsn_nu++,
2699 dtap_attach_acc, sizeof(dtap_attach_acc));
2700
2701 dump_peers(stdout, 0, 0, &gbcfg);
2702
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002703 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2704 OSMO_ASSERT(link_info);
2705 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2706 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2707 OSMO_ASSERT(!link_info->tlli.bss_validated);
2708 OSMO_ASSERT(!link_info->tlli.net_validated);
2709 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2710 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2711 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2712 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2713 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2714 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002715
2716 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2717 local_bss_tlli, &rai_bss, cell_id,
2718 GPRS_SAPI_GMM, bss_nu++,
2719 dtap_attach_complete, sizeof(dtap_attach_complete));
2720
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002723 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2724 OSMO_ASSERT(link_info);
2725 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2726 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2727 OSMO_ASSERT(link_info->tlli.bss_validated);
2728 OSMO_ASSERT(!link_info->tlli.net_validated);
2729 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2730 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2731 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2732 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002733
2734 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2735 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2736 GPRS_SAPI_GMM, sgsn_nu++,
2737 dtap_gmm_information, sizeof(dtap_gmm_information));
2738
2739 dump_peers(stdout, 0, 0, &gbcfg);
2740
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002741 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2742 OSMO_ASSERT(link_info);
2743 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2744 OSMO_ASSERT(link_info->tlli.assigned == 0);
2745 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2746 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002747
2748 /* Non-DTAP */
2749 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2750 local_bss_tlli, &rai_bss, cell_id,
2751 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2752
2753 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2754 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2755 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2756
2757 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2758 local_bss_tlli, &rai_bss, cell_id,
2759 llc_ui_ll11_dns_query_ul,
2760 sizeof(llc_ui_ll11_dns_query_ul));
2761
2762 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2763 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2764 llc_ui_ll11_dns_resp_dl,
2765 sizeof(llc_ui_ll11_dns_resp_dl));
2766
2767 dump_peers(stdout, 0, 0, &gbcfg);
2768
2769 /* Other messages */
2770 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2771 local_bss_tlli, 1, 12);
2772
2773 dump_peers(stdout, 0, 0, &gbcfg);
2774
2775 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2776 local_sgsn_tlli, 1, 12);
2777
2778 dump_peers(stdout, 0, 0, &gbcfg);
2779
2780 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2781
2782 dump_peers(stdout, 0, 0, &gbcfg);
2783
2784 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2785
2786 dump_peers(stdout, 0, 0, &gbcfg);
2787
2788 /* Bad case: Invalid BVCI */
2789 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2790 local_bss_tlli, 1, 12);
2791 dump_global(stdout, 0);
2792
2793 /* Bad case: Invalid RAI */
2794 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2795
2796 dump_global(stdout, 0);
2797
2798 /* Bad case: Invalid MCC (LAC ok) */
2799 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2800 &rai_wrong_mcc_sgsn);
2801
2802 dump_global(stdout, 0);
2803
2804 /* Detach */
2805 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2806 local_bss_tlli, &rai_bss, cell_id,
2807 GPRS_SAPI_GMM, bss_nu++,
2808 dtap_detach_req, sizeof(dtap_detach_req));
2809
2810 dump_peers(stdout, 0, 0, &gbcfg);
2811
2812 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2813 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2814 GPRS_SAPI_GMM, sgsn_nu++,
2815 dtap_detach_acc, sizeof(dtap_detach_acc));
2816
2817 dump_peers(stdout, 0, 0, &gbcfg);
2818
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002819 /* RA Update request */
2820
2821 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2822 foreign_bss_tlli, &rai_unknown, 0x7080,
2823 GPRS_SAPI_GMM, bss_nu++,
2824 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2825
2826 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2827 foreign_bss_tlli, &rai_bss, cell_id,
2828 GPRS_SAPI_GMM, bss_nu++,
2829 dtap_identity_resp, sizeof(dtap_identity_resp));
2830
2831 dump_peers(stdout, 0, 0, &gbcfg);
2832
2833 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2834 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2835 GPRS_SAPI_GMM, sgsn_nu++,
2836 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2837
2838 dump_peers(stdout, 0, 0, &gbcfg);
2839
2840 /* Detach */
2841
2842 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2843 local_bss_tlli, &rai_bss, cell_id,
2844 GPRS_SAPI_GMM, bss_nu++,
2845 dtap_detach_req, sizeof(dtap_detach_req));
2846
2847 dump_peers(stdout, 0, 0, &gbcfg);
2848
2849 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2850 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2851 GPRS_SAPI_GMM, sgsn_nu++,
2852 dtap_detach_acc, sizeof(dtap_detach_acc));
2853
2854 dump_peers(stdout, 0, 0, &gbcfg);
2855
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002856 /* Special case: Repeated Attach Requests */
2857
2858 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2859 foreign_bss_tlli, &rai_unknown, cell_id,
2860 GPRS_SAPI_GMM, bss_nu++,
2861 dtap_attach_req, sizeof(dtap_attach_req));
2862
2863 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2864 foreign_bss_tlli, &rai_unknown, cell_id,
2865 GPRS_SAPI_GMM, bss_nu++,
2866 dtap_attach_req, sizeof(dtap_attach_req));
2867
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002868 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2869 foreign_bss_tlli, &rai_bss, cell_id,
2870 GPRS_SAPI_GMM, bss_nu++,
2871 dtap_detach_req, sizeof(dtap_detach_req));
2872
2873 dump_peers(stdout, 0, 0, &gbcfg);
2874
2875 /* Special case: Detach from an unknown TLLI */
2876
2877 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2878 other_bss_tlli, &rai_bss, cell_id,
2879 GPRS_SAPI_GMM, bss_nu++,
2880 dtap_detach_req, sizeof(dtap_detach_req));
2881
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002882 dump_peers(stdout, 0, 0, &gbcfg);
2883
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002884 /* Special case: Repeated RA Update Requests */
2885
2886 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2887 foreign_bss_tlli, &rai_unknown, 0x7080,
2888 GPRS_SAPI_GMM, bss_nu++,
2889 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2890
2891 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2892 foreign_bss_tlli, &rai_unknown, 0x7080,
2893 GPRS_SAPI_GMM, bss_nu++,
2894 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2895
2896 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2897 foreign_bss_tlli, &rai_bss, cell_id,
2898 GPRS_SAPI_GMM, bss_nu++,
2899 dtap_detach_req, sizeof(dtap_detach_req));
2900
2901 dump_peers(stdout, 0, 0, &gbcfg);
2902
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002903 dump_global(stdout, 0);
2904
2905 gbprox_reset(&gbcfg);
2906 gprs_ns_destroy(nsi);
2907 nsi = NULL;
2908}
2909
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002910static void test_gbproxy_secondary_sgsn()
2911{
2912 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2913 struct sockaddr_in bss_peer[1] = {{0},};
2914 struct sockaddr_in sgsn_peer[2]= {{0},};
2915 struct gprs_ra_id rai_bss =
2916 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2917 struct gprs_ra_id rai_sgsn =
2918 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2919 struct gprs_ra_id rai_unknown =
2920 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2921 uint16_t cell_id = 0x1234;
2922
2923 const uint32_t sgsn_ptmsi = 0xefe2b700;
2924 const uint32_t local_sgsn_tlli = 0xefe2b700;
2925 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2926
2927 const uint32_t bss_ptmsi = 0xc00f7304;
2928 const uint32_t local_bss_tlli = 0xc00f7304;
2929 const uint32_t foreign_bss_tlli = 0x8000dead;
2930
2931 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2932 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2933 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2934 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2935 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2936 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2937
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002938 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002939 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002940 const uint32_t local_bss_tlli3 = 0xead4775a;
2941 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2942
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002943 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2944 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002945 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002946 struct gbproxy_link_info *link_info;
2947 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002948 struct gbproxy_peer *peer;
2949 unsigned bss_nu = 0;
2950 unsigned sgsn_nu = 0;
2951
2952 const char *err_msg = NULL;
2953 const char *filter_re = "999999";
2954
2955 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2956 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2957
2958 bssgp_nsi = nsi;
2959 gbcfg.nsi = bssgp_nsi;
2960 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2961 gbcfg.core_mcc = 123;
2962 gbcfg.core_mnc = 456;
2963 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2964 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2965 gbcfg.patch_ptmsi = 1;
2966 gbcfg.acquire_imsi = 1;
2967 gbcfg.bss_ptmsi_state = 0;
2968 gbcfg.sgsn_tlli_state = 1;
2969 gbcfg.route_to_sgsn2 = 1;
2970 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2971
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02002972 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02002973 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002974 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2975 err_msg);
2976 OSMO_ASSERT(err_msg == NULL);
2977 }
2978
2979 configure_sgsn_peer(&sgsn_peer[0]);
2980 configure_sgsn2_peer(&sgsn_peer[1]);
2981 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2982
2983 printf("=== %s ===\n", __func__);
2984 printf("--- Initialise SGSN 1 ---\n\n");
2985
2986 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2987
2988 printf("--- Initialise SGSN 2 ---\n\n");
2989
2990 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2991
2992 printf("--- Initialise BSS 1 ---\n\n");
2993
2994 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2995 setup_bssgp(nsi, &bss_peer[0], 0x0);
2996 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2997 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2998 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2999 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
3000
3001 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3002 OSMO_ASSERT(peer != NULL);
3003
3004 gprs_dump_nsi(nsi);
3005 dump_global(stdout, 0);
3006 dump_peers(stdout, 0, 0, &gbcfg);
3007
3008 printf("--- Flow control ---\n\n");
3009
3010 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
3011 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
3012 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
3013
3014 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
3015
3016 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3017 foreign_bss_tlli, &rai_unknown, cell_id,
3018 GPRS_SAPI_GMM, bss_nu++,
3019 dtap_attach_req, sizeof(dtap_attach_req));
3020
3021 dump_peers(stdout, 0, 0, &gbcfg);
3022
3023 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3024 foreign_bss_tlli, &rai_bss, cell_id,
3025 GPRS_SAPI_GMM, bss_nu++,
3026 dtap_identity_resp, sizeof(dtap_identity_resp));
3027
3028 dump_peers(stdout, 0, 0, &gbcfg);
3029
3030 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
3031 random_sgsn_tlli, 0, NULL, 0,
3032 GPRS_SAPI_GMM, sgsn_nu++,
3033 dtap_identity_req, sizeof(dtap_identity_req));
3034
3035 dump_peers(stdout, 0, 0, &gbcfg);
3036
3037 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3038 foreign_bss_tlli, &rai_bss, cell_id,
3039 GPRS_SAPI_GMM, bss_nu++,
3040 dtap_identity_resp, sizeof(dtap_identity_resp));
3041
3042 dump_peers(stdout, 0, 0, &gbcfg);
3043
3044 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
3045 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3046 GPRS_SAPI_GMM, sgsn_nu++,
3047 dtap_attach_acc, sizeof(dtap_attach_acc));
3048
3049 dump_peers(stdout, 0, 0, &gbcfg);
3050
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003051 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3052 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
3053 OSMO_ASSERT(link_info);
3054 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3055 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3056 OSMO_ASSERT(!link_info->tlli.bss_validated);
3057 OSMO_ASSERT(!link_info->tlli.net_validated);
3058 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
3059 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3060 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3061 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3062 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3063 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003064
3065 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3066 local_bss_tlli, &rai_bss, cell_id,
3067 GPRS_SAPI_GMM, bss_nu++,
3068 dtap_attach_complete, sizeof(dtap_attach_complete));
3069
3070 dump_peers(stdout, 0, 0, &gbcfg);
3071
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003072 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3073 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3074 OSMO_ASSERT(link_info);
3075 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3076 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3077 OSMO_ASSERT(link_info->tlli.bss_validated);
3078 OSMO_ASSERT(!link_info->tlli.net_validated);
3079 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3080 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3081 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3082 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003083
3084 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
3085 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3086 GPRS_SAPI_GMM, sgsn_nu++,
3087 dtap_gmm_information, sizeof(dtap_gmm_information));
3088
3089 dump_peers(stdout, 0, 0, &gbcfg);
3090
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003091 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3092 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3093 OSMO_ASSERT(link_info);
3094 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
3095 OSMO_ASSERT(link_info->tlli.assigned == 0);
3096 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3097 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003098
3099 /* Non-DTAP */
3100 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3101 local_bss_tlli, &rai_bss, cell_id,
3102 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3103
3104 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
3105 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3106 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3107
3108 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3109 local_bss_tlli, &rai_bss, cell_id,
3110 llc_ui_ll11_dns_query_ul,
3111 sizeof(llc_ui_ll11_dns_query_ul));
3112
3113 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
3114 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3115 llc_ui_ll11_dns_resp_dl,
3116 sizeof(llc_ui_ll11_dns_resp_dl));
3117
3118 dump_peers(stdout, 0, 0, &gbcfg);
3119
3120 /* Other messages */
3121 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3122 local_bss_tlli, 1, 12);
3123
3124 dump_peers(stdout, 0, 0, &gbcfg);
3125
3126 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
3127 local_sgsn_tlli, 1, 12);
3128
3129 dump_peers(stdout, 0, 0, &gbcfg);
3130
3131 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
3132
3133 dump_peers(stdout, 0, 0, &gbcfg);
3134
3135 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
3136
3137 dump_peers(stdout, 0, 0, &gbcfg);
3138
3139 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
3140
3141 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3142 foreign_bss_tlli2, &rai_unknown, cell_id,
3143 GPRS_SAPI_GMM, bss_nu++,
3144 dtap_attach_req, sizeof(dtap_attach_req));
3145
3146 dump_peers(stdout, 0, 0, &gbcfg);
3147
3148 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3149 foreign_bss_tlli2, &rai_bss, cell_id,
3150 GPRS_SAPI_GMM, bss_nu++,
3151 dtap_identity2_resp, sizeof(dtap_identity2_resp));
3152
3153 dump_peers(stdout, 0, 0, &gbcfg);
3154
3155 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3156 random_sgsn_tlli2, 0, NULL, 0,
3157 GPRS_SAPI_GMM, sgsn_nu++,
3158 dtap_identity_req, sizeof(dtap_identity_req));
3159
3160 dump_peers(stdout, 0, 0, &gbcfg);
3161
3162 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3163 foreign_bss_tlli2, &rai_bss, cell_id,
3164 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02003165 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003166
3167 dump_peers(stdout, 0, 0, &gbcfg);
3168
3169 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
3170 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3171 GPRS_SAPI_GMM, sgsn_nu++,
3172 dtap_attach_acc2, sizeof(dtap_attach_acc2));
3173
3174 dump_peers(stdout, 0, 0, &gbcfg);
3175
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003176 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
3177 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
3178 OSMO_ASSERT(link_info);
3179 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3180 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3181 OSMO_ASSERT(!link_info->tlli.bss_validated);
3182 OSMO_ASSERT(!link_info->tlli.net_validated);
3183 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3184 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3185 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3186 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3187 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3188 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003189
3190 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3191 local_bss_tlli2, &rai_bss, cell_id,
3192 GPRS_SAPI_GMM, bss_nu++,
3193 dtap_attach_complete, sizeof(dtap_attach_complete));
3194
3195 dump_peers(stdout, 0, 0, &gbcfg);
3196
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003197 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3198 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3199 OSMO_ASSERT(link_info);
3200 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3201 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3202 OSMO_ASSERT(link_info->tlli.bss_validated);
3203 OSMO_ASSERT(!link_info->tlli.net_validated);
3204 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3205 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3206 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3207 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003208
3209 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3210 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3211 GPRS_SAPI_GMM, sgsn_nu++,
3212 dtap_gmm_information, sizeof(dtap_gmm_information));
3213
3214 dump_peers(stdout, 0, 0, &gbcfg);
3215
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003216 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3217 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3218 OSMO_ASSERT(link_info);
3219 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3220 OSMO_ASSERT(link_info->tlli.assigned == 0);
3221 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3222 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003223
3224 /* Non-DTAP */
3225 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3226 local_bss_tlli2, &rai_bss, cell_id,
3227 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3228
3229 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3230 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3231 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3232
3233 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3234 local_bss_tlli2, &rai_bss, cell_id,
3235 llc_ui_ll11_dns_query_ul,
3236 sizeof(llc_ui_ll11_dns_query_ul));
3237
3238 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3239 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3240 llc_ui_ll11_dns_resp_dl,
3241 sizeof(llc_ui_ll11_dns_resp_dl));
3242
3243 dump_peers(stdout, 0, 0, &gbcfg);
3244
3245 /* Other messages */
3246 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3247 local_bss_tlli2, 1, 12);
3248
3249 dump_peers(stdout, 0, 0, &gbcfg);
3250
3251 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3252 local_sgsn_tlli2, 1, 12);
3253
3254 dump_peers(stdout, 0, 0, &gbcfg);
3255
3256 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3257
3258 dump_peers(stdout, 0, 0, &gbcfg);
3259
3260 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3261
3262 dump_peers(stdout, 0, 0, &gbcfg);
3263
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003264 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3265
3266 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3267 foreign_bss_tlli3, &rai_unknown, cell_id,
3268 GPRS_SAPI_GMM, bss_nu++,
3269 dtap_attach_req, sizeof(dtap_attach_req));
3270
3271 dump_peers(stdout, 0, 0, &gbcfg);
3272
3273 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3274 foreign_bss_tlli3, &rai_bss, cell_id,
3275 GPRS_SAPI_GMM, bss_nu++,
3276 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3277
3278 dump_peers(stdout, 0, 0, &gbcfg);
3279
3280 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3281 random_sgsn_tlli3, 0, NULL, 0,
3282 GPRS_SAPI_GMM, sgsn_nu++,
3283 dtap_identity_req, sizeof(dtap_identity_req));
3284
3285 dump_peers(stdout, 0, 0, &gbcfg);
3286
3287 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3288 foreign_bss_tlli3, &rai_bss, cell_id,
3289 GPRS_SAPI_GMM, bss_nu++,
3290 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3291
3292 dump_peers(stdout, 0, 0, &gbcfg);
3293
3294 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3295 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3296 GPRS_SAPI_GMM, sgsn_nu++,
3297 dtap_attach_acc, sizeof(dtap_attach_acc));
3298
3299 dump_peers(stdout, 0, 0, &gbcfg);
3300
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003301 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3302 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3303 OSMO_ASSERT(link_info);
3304 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3305 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3306 OSMO_ASSERT(!link_info->tlli.bss_validated);
3307 OSMO_ASSERT(!link_info->tlli.net_validated);
3308 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3309 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3310 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3311 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3312 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3313 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003314
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003315 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3316 local_bss_tlli3, &rai_bss, cell_id,
3317 GPRS_SAPI_GMM, bss_nu++,
3318 dtap_attach_complete, sizeof(dtap_attach_complete));
3319
3320 dump_peers(stdout, 0, 0, &gbcfg);
3321
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003322 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003323 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003324 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3325 OSMO_ASSERT(link_info);
3326 OSMO_ASSERT(link_info != other_info);
3327 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3328 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3329 OSMO_ASSERT(link_info->tlli.bss_validated);
3330 OSMO_ASSERT(!link_info->tlli.net_validated);
3331 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3332 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3333 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3334 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003335
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003336 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3337 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3338 GPRS_SAPI_GMM, sgsn_nu++,
3339 dtap_gmm_information, sizeof(dtap_gmm_information));
3340
3341 dump_peers(stdout, 0, 0, &gbcfg);
3342
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003343 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003344 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003345 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3346 OSMO_ASSERT(link_info);
3347 OSMO_ASSERT(link_info != other_info);
3348 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3349 OSMO_ASSERT(link_info->tlli.assigned == 0);
3350 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3351 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003352
3353
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003354 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3355
3356 /* Detach */
3357 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3358 local_bss_tlli, &rai_bss, cell_id,
3359 GPRS_SAPI_GMM, bss_nu++,
3360 dtap_detach_req, sizeof(dtap_detach_req));
3361
3362 dump_peers(stdout, 0, 0, &gbcfg);
3363
3364 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3365 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3366 GPRS_SAPI_GMM, sgsn_nu++,
3367 dtap_detach_acc, sizeof(dtap_detach_acc));
3368
3369 dump_peers(stdout, 0, 0, &gbcfg);
3370
3371 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3372
3373 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3374 local_bss_tlli2, &rai_bss, cell_id,
3375 GPRS_SAPI_GMM, bss_nu++,
3376 dtap_detach_req, sizeof(dtap_detach_req));
3377
3378 dump_peers(stdout, 0, 0, &gbcfg);
3379
3380 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3381 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3382 GPRS_SAPI_GMM, sgsn_nu++,
3383 dtap_detach_acc, sizeof(dtap_detach_acc));
3384
3385 dump_peers(stdout, 0, 0, &gbcfg);
3386
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003387 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3388
3389 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3390 local_bss_tlli3, &rai_bss, cell_id,
3391 GPRS_SAPI_GMM, bss_nu++,
3392 dtap_detach_req, sizeof(dtap_detach_req));
3393
3394 dump_peers(stdout, 0, 0, &gbcfg);
3395
3396 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3397 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3398 GPRS_SAPI_GMM, sgsn_nu++,
3399 dtap_detach_acc, sizeof(dtap_detach_acc));
3400
3401 dump_peers(stdout, 0, 0, &gbcfg);
3402
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003403 dump_global(stdout, 0);
3404
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003405 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003406 gbprox_reset(&gbcfg);
3407 gprs_ns_destroy(nsi);
3408 nsi = NULL;
3409}
3410
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003411static void test_gbproxy_keep_info()
3412{
3413 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3414 struct sockaddr_in bss_peer[1] = {{0},};
3415 struct sockaddr_in sgsn_peer= {0};
3416 struct gprs_ra_id rai_bss =
3417 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3418 uint16_t cell_id = 0x1234;
3419
3420 const uint32_t ptmsi = 0xefe2b700;
3421 const uint32_t local_tlli = 0xefe2b700;
3422 const uint32_t foreign_tlli = 0xafe2b700;
3423
3424 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003425 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003426 struct gbproxy_peer *peer;
3427 unsigned bss_nu = 0;
3428 unsigned sgsn_nu = 0;
3429
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003430 LLIST_HEAD(rcv_list);
3431
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003432 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3433
3434 bssgp_nsi = nsi;
3435 gbcfg.nsi = bssgp_nsi;
3436 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3437 gbcfg.patch_ptmsi = 0;
3438 gbcfg.acquire_imsi = 1;
3439 gbcfg.bss_ptmsi_state = 0;
3440 gbcfg.sgsn_tlli_state = 1;
3441 gbcfg.core_mcc = 0;
3442 gbcfg.core_mnc = 0;
3443 gbcfg.core_apn = NULL;
3444 gbcfg.core_apn_size = 0;
3445 gbcfg.route_to_sgsn2 = 0;
3446 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003447 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003448
3449 configure_sgsn_peer(&sgsn_peer);
3450 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3451
3452 printf("=== %s ===\n", __func__);
3453 printf("--- Initialise SGSN ---\n\n");
3454
3455 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3456
3457 printf("--- Initialise BSS 1 ---\n\n");
3458
3459 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3460 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3461
3462 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3463 OSMO_ASSERT(peer != NULL);
3464
3465 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3466
3467 gprs_dump_nsi(nsi);
3468 dump_global(stdout, 0);
3469 dump_peers(stdout, 0, 0, &gbcfg);
3470
3471 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3472
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003473 received_messages = &rcv_list;
3474
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003475 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3476 foreign_tlli, &rai_bss, cell_id,
3477 GPRS_SAPI_GMM, bss_nu++,
3478 dtap_attach_req, sizeof(dtap_attach_req));
3479
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003480 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3481
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003482 dump_peers(stdout, 0, 0, &gbcfg);
3483
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003484 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3485 OSMO_ASSERT(link_info);
3486 OSMO_ASSERT(link_info->imsi_len == 0);
3487 OSMO_ASSERT(!link_info->is_deregistered);
3488 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003489
3490 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3491 foreign_tlli, &rai_bss, cell_id,
3492 GPRS_SAPI_GMM, bss_nu++,
3493 dtap_identity_resp, sizeof(dtap_identity_resp));
3494
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003495 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3496
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003497 dump_peers(stdout, 0, 0, &gbcfg);
3498
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003499 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3500 OSMO_ASSERT(link_info);
3501 OSMO_ASSERT(link_info->imsi_len > 0);
3502 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003503
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003504 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3505 foreign_tlli, 0, NULL, 0,
3506 GPRS_SAPI_GMM, sgsn_nu++,
3507 dtap_identity_req, sizeof(dtap_identity_req));
3508
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003509 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3510
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003511 dump_peers(stdout, 0, 0, &gbcfg);
3512
3513 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3514 foreign_tlli, &rai_bss, cell_id,
3515 GPRS_SAPI_GMM, bss_nu++,
3516 dtap_identity_resp, sizeof(dtap_identity_resp));
3517
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003518 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
3519
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003520 dump_peers(stdout, 0, 0, &gbcfg);
3521
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003522 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3523 OSMO_ASSERT(link_info);
3524 OSMO_ASSERT(link_info->imsi_len > 0);
3525 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003526
3527 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3528 foreign_tlli, 1, imsi, sizeof(imsi),
3529 GPRS_SAPI_GMM, sgsn_nu++,
3530 dtap_attach_acc, sizeof(dtap_attach_acc));
3531
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003532 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3533
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003534 dump_peers(stdout, 0, 0, &gbcfg);
3535
3536 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3537 local_tlli, &rai_bss, cell_id,
3538 GPRS_SAPI_GMM, bss_nu++,
3539 dtap_attach_complete, sizeof(dtap_attach_complete));
3540
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003541 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3542
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003543 dump_peers(stdout, 0, 0, &gbcfg);
3544
3545 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3546 local_tlli, 1, imsi, sizeof(imsi),
3547 GPRS_SAPI_GMM, sgsn_nu++,
3548 dtap_gmm_information, sizeof(dtap_gmm_information));
3549
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003550 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
3551
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003552 dump_peers(stdout, 0, 0, &gbcfg);
3553
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003554 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3555 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003556
3557 /* Detach (MO) */
3558 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3559 local_tlli, &rai_bss, cell_id,
3560 GPRS_SAPI_GMM, bss_nu++,
3561 dtap_detach_req, sizeof(dtap_detach_req));
3562
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003563 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3564
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003565 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3566 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003567
3568 dump_peers(stdout, 0, 0, &gbcfg);
3569
3570 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3571 local_tlli, 1, imsi, sizeof(imsi),
3572 GPRS_SAPI_GMM, sgsn_nu++,
3573 dtap_detach_acc, sizeof(dtap_detach_acc));
3574
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003575 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3576
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003577 dump_peers(stdout, 0, 0, &gbcfg);
3578
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003579 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3580 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3581 OSMO_ASSERT(link_info);
3582 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003583
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003584 OSMO_ASSERT(!expect_msg());
3585
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003586 /* Re-Attach */
3587 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3588 foreign_tlli, &rai_bss, cell_id,
3589 GPRS_SAPI_GMM, bss_nu++,
3590 dtap_attach_req3, sizeof(dtap_attach_req3));
3591
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003592 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3593
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003594 dump_peers(stdout, 0, 0, &gbcfg);
3595
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003596 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3597 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3598 OSMO_ASSERT(link_info);
3599 OSMO_ASSERT(link_info == link_info2);
3600 OSMO_ASSERT(link_info->imsi_len != 0);
3601 OSMO_ASSERT(!link_info->is_deregistered);
3602 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003603
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003604 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3605 foreign_tlli, 1, imsi, sizeof(imsi),
3606 GPRS_SAPI_GMM, sgsn_nu++,
3607 dtap_attach_acc, sizeof(dtap_attach_acc));
3608
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003609 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3610
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003611 dump_peers(stdout, 0, 0, &gbcfg);
3612
3613 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3614 local_tlli, &rai_bss, cell_id,
3615 GPRS_SAPI_GMM, bss_nu++,
3616 dtap_attach_complete, sizeof(dtap_attach_complete));
3617
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003618 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3619
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003620 dump_peers(stdout, 0, 0, &gbcfg);
3621
3622 /* Detach (MT) */
3623 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3624 local_tlli, 1, imsi, sizeof(imsi),
3625 GPRS_SAPI_GMM, sgsn_nu++,
3626 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3627
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003628 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3629
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003630 dump_peers(stdout, 0, 0, &gbcfg);
3631
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003632 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3633 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003634
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003635 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003636 local_tlli, &rai_bss, cell_id,
3637 GPRS_SAPI_GMM, bss_nu++,
3638 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3639
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003640 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3641 OSMO_ASSERT(!expect_msg());
3642
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003643 dump_peers(stdout, 0, 0, &gbcfg);
3644
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003645 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3646 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3647 OSMO_ASSERT(link_info);
3648 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003649
3650 /* Re-Attach */
3651 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3652 foreign_tlli, &rai_bss, cell_id,
3653 GPRS_SAPI_GMM, bss_nu++,
3654 dtap_attach_req3, sizeof(dtap_attach_req3));
3655
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003656 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3657
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003658 dump_peers(stdout, 0, 0, &gbcfg);
3659
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003660 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3661 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3662 OSMO_ASSERT(link_info);
3663 OSMO_ASSERT(link_info == link_info2);
3664 OSMO_ASSERT(link_info->imsi_len != 0);
3665 OSMO_ASSERT(!link_info->is_deregistered);
3666 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003667
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003668 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3669 foreign_tlli, 1, imsi, sizeof(imsi),
3670 GPRS_SAPI_GMM, sgsn_nu++,
3671 dtap_attach_acc, sizeof(dtap_attach_acc));
3672
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003673 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3674
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003675 dump_peers(stdout, 0, 0, &gbcfg);
3676
3677 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3678 local_tlli, &rai_bss, cell_id,
3679 GPRS_SAPI_GMM, bss_nu++,
3680 dtap_attach_complete, sizeof(dtap_attach_complete));
3681
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003682 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3683
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003684 dump_peers(stdout, 0, 0, &gbcfg);
3685
3686 /* Detach (MT) */
3687 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3688 local_tlli, 1, imsi, sizeof(imsi),
3689 GPRS_SAPI_GMM, sgsn_nu++,
3690 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3691
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003692 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3693
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003694 dump_peers(stdout, 0, 0, &gbcfg);
3695
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003696 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3697 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003698
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003699 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003700 local_tlli, &rai_bss, cell_id,
3701 GPRS_SAPI_GMM, bss_nu++,
3702 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3703
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003704 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3705 OSMO_ASSERT(!expect_msg());
3706
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003707 dump_peers(stdout, 0, 0, &gbcfg);
3708
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003709 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3710 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3711 OSMO_ASSERT(link_info);
3712 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003713
3714 /* Re-Attach */
3715 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3716 foreign_tlli, &rai_bss, cell_id,
3717 GPRS_SAPI_GMM, bss_nu++,
3718 dtap_attach_req3, sizeof(dtap_attach_req3));
3719
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003720 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3721
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003722 dump_peers(stdout, 0, 0, &gbcfg);
3723
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003724 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3725 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3726 OSMO_ASSERT(link_info);
3727 OSMO_ASSERT(link_info == link_info2);
3728 OSMO_ASSERT(link_info->imsi_len != 0);
3729 OSMO_ASSERT(!link_info->is_deregistered);
3730 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003731
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003732 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3733 foreign_tlli, 1, imsi, sizeof(imsi),
3734 GPRS_SAPI_GMM, sgsn_nu++,
3735 dtap_attach_acc, sizeof(dtap_attach_acc));
3736
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003737 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3738
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003739 dump_peers(stdout, 0, 0, &gbcfg);
3740
3741 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3742 local_tlli, &rai_bss, cell_id,
3743 GPRS_SAPI_GMM, bss_nu++,
3744 dtap_attach_complete, sizeof(dtap_attach_complete));
3745
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003746 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3747
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003748 dump_peers(stdout, 0, 0, &gbcfg);
3749
3750 /* RA update procedure (reject -> Detach) */
3751 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3752 local_tlli, &rai_bss, 0x7080,
3753 GPRS_SAPI_GMM, bss_nu++,
3754 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3755
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003756 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
3757
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003758 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3759 local_tlli, 1, imsi, sizeof(imsi),
3760 GPRS_SAPI_GMM, sgsn_nu++,
3761 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3762
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003763 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ));
3764 OSMO_ASSERT(!expect_msg());
3765
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003766 dump_peers(stdout, 0, 0, &gbcfg);
3767
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003768 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3769 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3770 OSMO_ASSERT(link_info);
3771 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003772
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003773 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3774 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3775 foreign_tlli, &rai_bss, cell_id,
3776 GPRS_SAPI_GMM, bss_nu++,
3777 dtap_attach_req, sizeof(dtap_attach_req));
3778
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003779 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3780
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003781 dump_peers(stdout, 0, 0, &gbcfg);
3782
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003783 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3784 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3785 OSMO_ASSERT(link_info);
3786 OSMO_ASSERT(link_info != link_info2);
3787 OSMO_ASSERT(link_info->imsi_len == 0);
3788 OSMO_ASSERT(!link_info->is_deregistered);
3789 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003790
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003791 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3792 foreign_tlli, &rai_bss, cell_id,
3793 GPRS_SAPI_GMM, bss_nu++,
3794 dtap_identity_resp, sizeof(dtap_identity_resp));
3795
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003796 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3797
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003798 dump_peers(stdout, 0, 0, &gbcfg);
3799
3800 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3801 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3802 OSMO_ASSERT(link_info);
3803 OSMO_ASSERT(link_info == link_info2);
3804 OSMO_ASSERT(link_info->imsi_len != 0);
3805 OSMO_ASSERT(!link_info->is_deregistered);
3806 OSMO_ASSERT(!link_info->imsi_acq_pending);
3807
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003808 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3809 foreign_tlli, 1, imsi, sizeof(imsi),
3810 GPRS_SAPI_GMM, sgsn_nu++,
3811 dtap_attach_acc, sizeof(dtap_attach_acc));
3812
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003813 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3814
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003815 dump_peers(stdout, 0, 0, &gbcfg);
3816
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003817 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3818 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3819 OSMO_ASSERT(link_info);
3820 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003821 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003822
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003823 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3824 local_tlli, &rai_bss, cell_id,
3825 GPRS_SAPI_GMM, bss_nu++,
3826 dtap_attach_complete, sizeof(dtap_attach_complete));
3827
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003828 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3829
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003830 dump_peers(stdout, 0, 0, &gbcfg);
3831
3832 /* Detach (MT) */
3833 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3834 local_tlli, 1, imsi, sizeof(imsi),
3835 GPRS_SAPI_GMM, sgsn_nu++,
3836 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3837
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003838 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3839
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003840 dump_peers(stdout, 0, 0, &gbcfg);
3841
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003842 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3843 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003844
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003845 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003846 local_tlli, &rai_bss, cell_id,
3847 GPRS_SAPI_GMM, bss_nu++,
3848 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3849
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003850 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3851
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003852 dump_peers(stdout, 0, 0, &gbcfg);
3853
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003854 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3855 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3856 OSMO_ASSERT(link_info);
3857 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003858
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003859 OSMO_ASSERT(!expect_msg());
3860
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003861 /* Attach rejected */
3862
3863 gbproxy_delete_link_infos(peer);
3864
3865 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3866 foreign_tlli, &rai_bss, cell_id,
3867 GPRS_SAPI_GMM, bss_nu++,
3868 dtap_attach_req, sizeof(dtap_attach_req));
3869
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003870 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3871
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003872 dump_peers(stdout, 0, 0, &gbcfg);
3873
3874 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3875 OSMO_ASSERT(link_info);
3876 OSMO_ASSERT(link_info->imsi_len == 0);
3877 OSMO_ASSERT(!link_info->is_deregistered);
3878 OSMO_ASSERT(link_info->imsi_acq_pending);
3879
3880 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3881 foreign_tlli, &rai_bss, cell_id,
3882 GPRS_SAPI_GMM, bss_nu++,
3883 dtap_identity_resp, sizeof(dtap_identity_resp));
3884
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003885 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3886
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003887 dump_peers(stdout, 0, 0, &gbcfg);
3888
3889 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3890 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3891 OSMO_ASSERT(link_info);
3892 OSMO_ASSERT(link_info == link_info2);
3893 OSMO_ASSERT(link_info->imsi_len != 0);
3894 OSMO_ASSERT(!link_info->is_deregistered);
3895 OSMO_ASSERT(!link_info->imsi_acq_pending);
3896
3897 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3898 foreign_tlli, 1, imsi, sizeof(imsi),
3899 GPRS_SAPI_GMM, sgsn_nu++,
3900 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3901
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003902 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ));
3903
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003904 dump_peers(stdout, 0, 0, &gbcfg);
3905
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003906 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3907
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003908 OSMO_ASSERT(!expect_msg());
3909
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003910 /* Attach (incomplete) and Detach (MO) */
3911
3912 gbproxy_delete_link_infos(peer);
3913
3914 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3915 foreign_tlli, &rai_bss, cell_id,
3916 GPRS_SAPI_GMM, bss_nu++,
3917 dtap_attach_req, sizeof(dtap_attach_req));
3918
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003919 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3920
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003921 dump_peers(stdout, 0, 0, &gbcfg);
3922
3923 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3924 OSMO_ASSERT(link_info);
3925 OSMO_ASSERT(link_info->imsi_len == 0);
3926 OSMO_ASSERT(!link_info->is_deregistered);
3927 OSMO_ASSERT(link_info->imsi_acq_pending);
3928
3929 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3930 foreign_tlli, &rai_bss, cell_id,
3931 GPRS_SAPI_GMM, bss_nu++,
3932 dtap_detach_req, sizeof(dtap_detach_req));
3933
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003934 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3935
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003936 dump_peers(stdout, 0, 0, &gbcfg);
3937
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003938 OSMO_ASSERT(!expect_msg());
3939
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003940 /* Attach (incomplete) and Detach (MT) */
3941
3942 gbproxy_delete_link_infos(peer);
3943
3944 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3945 foreign_tlli, &rai_bss, cell_id,
3946 GPRS_SAPI_GMM, bss_nu++,
3947 dtap_attach_req, sizeof(dtap_attach_req));
3948
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003949 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3950
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003951 dump_peers(stdout, 0, 0, &gbcfg);
3952
3953 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3954 OSMO_ASSERT(link_info);
3955 OSMO_ASSERT(link_info->imsi_len == 0);
3956 OSMO_ASSERT(!link_info->is_deregistered);
3957 OSMO_ASSERT(link_info->imsi_acq_pending);
3958
3959 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3960 foreign_tlli, 1, imsi, sizeof(imsi),
3961 GPRS_SAPI_GMM, sgsn_nu++,
3962 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3963
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003964 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3965
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003966 dump_peers(stdout, 0, 0, &gbcfg);
3967
3968 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3969 OSMO_ASSERT(link_info);
3970
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003971 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003972 foreign_tlli, &rai_bss, cell_id,
3973 GPRS_SAPI_GMM, bss_nu++,
3974 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3975
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003976 /* TODO: The stored messaged should be cleaned when receiving a Detach
3977 * Ack. Remove the first OSMO_ASSERT when this is fixed. */
3978 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3979 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3980
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003981 dump_peers(stdout, 0, 0, &gbcfg);
3982
3983 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3984 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3985 OSMO_ASSERT(link_info);
3986 OSMO_ASSERT(link_info->is_deregistered);
3987
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003988 OSMO_ASSERT(!expect_msg());
3989 received_messages = NULL;
3990
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003991 dump_global(stdout, 0);
3992
3993 gbprox_reset(&gbcfg);
3994 gprs_ns_destroy(nsi);
3995 nsi = NULL;
3996}
3997
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003998/* TODO: Move tlv testing to libosmocore */
3999int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
4000int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
4001 uint8_t **value);
4002int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
4003 size_t *value_len);
4004int lv_shift(uint8_t **data, size_t *data_len,
4005 uint8_t **value, size_t *value_len);
4006
4007static void check_tlv_match(uint8_t **data, size_t *data_len,
4008 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
4009{
4010 uint8_t *value;
4011 size_t value_len;
4012 int rc;
4013
4014 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
4015 OSMO_ASSERT(rc == 0);
4016
4017 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004018 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004019 OSMO_ASSERT(value_len == exp_len);
4020 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
4021}
4022
4023static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
4024 uint8_t tag, size_t len, const uint8_t *exp_val)
4025{
4026 uint8_t *value;
4027 int rc;
4028
4029 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
4030 OSMO_ASSERT(rc == 0);
4031
4032 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004033 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004034 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
4035}
4036
4037static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
4038 size_t len, const uint8_t *exp_val)
4039{
4040 uint8_t *value;
4041 int rc;
4042
4043 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004044 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004045 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
4046}
4047
4048static void check_lv_shift(uint8_t **data, size_t *data_len,
4049 size_t exp_len, const uint8_t *exp_val)
4050{
4051 uint8_t *value;
4052 size_t value_len;
4053 int rc;
4054
4055 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004056 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004057 OSMO_ASSERT(value_len == exp_len);
4058 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
4059}
4060
4061static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
4062 const uint8_t *test_data)
4063{
4064 uint8_t buf[300] = {0};
4065
4066 uint8_t *unchanged_ptr = buf - 1;
4067 size_t unchanged_len = 0xdead;
4068 size_t tmp_data_len = data_len;
4069 uint8_t *value = unchanged_ptr;
4070 size_t value_len = unchanged_len;
4071 uint8_t *data = buf;
4072
4073 OSMO_ASSERT(data_len <= sizeof(buf));
4074
4075 tlv_put(data, tag, len, test_data);
4076 if (data_len < len + 2) {
4077 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
4078 tag, &value, &value_len));
4079 OSMO_ASSERT(tmp_data_len == 0);
4080 OSMO_ASSERT(data == buf + data_len);
4081 OSMO_ASSERT(value == unchanged_ptr);
4082 OSMO_ASSERT(value_len == unchanged_len);
4083 } else {
4084 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
4085 tag, &value, &value_len));
4086 OSMO_ASSERT(value != unchanged_ptr);
4087 OSMO_ASSERT(value_len != unchanged_len);
4088 }
4089}
4090
4091static void check_tv_fixed_match_data_len(size_t data_len,
4092 uint8_t tag, size_t len,
4093 const uint8_t *test_data)
4094{
4095 uint8_t buf[300] = {0};
4096
4097 uint8_t *unchanged_ptr = buf - 1;
4098 size_t tmp_data_len = data_len;
4099 uint8_t *value = unchanged_ptr;
4100 uint8_t *data = buf;
4101
4102 OSMO_ASSERT(data_len <= sizeof(buf));
4103
4104 tv_fixed_put(data, tag, len, test_data);
4105
4106 if (data_len < len + 1) {
4107 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
4108 tag, len, &value));
4109 OSMO_ASSERT(tmp_data_len == 0);
4110 OSMO_ASSERT(data == buf + data_len);
4111 OSMO_ASSERT(value == unchanged_ptr);
4112 } else {
4113 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
4114 tag, len, &value));
4115 OSMO_ASSERT(value != unchanged_ptr);
4116 }
4117}
4118
4119static void check_v_fixed_shift_data_len(size_t data_len,
4120 size_t len, const uint8_t *test_data)
4121{
4122 uint8_t buf[300] = {0};
4123
4124 uint8_t *unchanged_ptr = buf - 1;
4125 size_t tmp_data_len = data_len;
4126 uint8_t *value = unchanged_ptr;
4127 uint8_t *data = buf;
4128
4129 OSMO_ASSERT(data_len <= sizeof(buf));
4130
4131 memcpy(data, test_data, len);
4132
4133 if (data_len < len) {
4134 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
4135 len, &value));
4136 OSMO_ASSERT(tmp_data_len == 0);
4137 OSMO_ASSERT(data == buf + data_len);
4138 OSMO_ASSERT(value == unchanged_ptr);
4139 } else {
4140 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
4141 len, &value));
4142 OSMO_ASSERT(value != unchanged_ptr);
4143 }
4144}
4145
4146static void check_lv_shift_data_len(size_t data_len,
4147 size_t len, const uint8_t *test_data)
4148{
4149 uint8_t buf[300] = {0};
4150
4151 uint8_t *unchanged_ptr = buf - 1;
4152 size_t unchanged_len = 0xdead;
4153 size_t tmp_data_len = data_len;
4154 uint8_t *value = unchanged_ptr;
4155 size_t value_len = unchanged_len;
4156 uint8_t *data = buf;
4157
4158 lv_put(data, len, test_data);
4159 if (data_len < len + 1) {
4160 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
4161 &value, &value_len));
4162 OSMO_ASSERT(tmp_data_len == 0);
4163 OSMO_ASSERT(data == buf + data_len);
4164 OSMO_ASSERT(value == unchanged_ptr);
4165 OSMO_ASSERT(value_len == unchanged_len);
4166 } else {
4167 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
4168 &value, &value_len));
4169 OSMO_ASSERT(value != unchanged_ptr);
4170 OSMO_ASSERT(value_len != unchanged_len);
4171 }
4172}
4173
4174static void test_tlv_shift_functions()
4175{
4176 uint8_t test_data[1024];
4177 uint8_t buf[1024];
4178 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004179 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004180 uint8_t *data;
4181 size_t data_len;
4182 const uint8_t tag = 0x1a;
4183
4184 printf("Test shift functions\n");
4185
4186 for (i = 0; i < ARRAY_SIZE(test_data); i++)
4187 test_data[i] = (uint8_t)i;
4188
4189 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004190 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004191
4192 memset(buf, 0xee, sizeof(buf));
4193 data_end = data = buf;
4194
4195 for (i = 0; i < iterations; i++) {
4196 data_end = tlv_put(data_end, tag, len, test_data);
4197 data_end = tv_fixed_put(data_end, tag, len, test_data);
4198 /* v_fixed_put */
4199 memcpy(data_end, test_data, len);
4200 data_end += len;
4201 data_end = lv_put(data_end, len, test_data);
4202 }
4203
4204 data_len = data_end - data;
4205 OSMO_ASSERT(data_len <= sizeof(buf));
4206
4207 for (i = 0; i < iterations; i++) {
4208 check_tlv_match(&data, &data_len, tag, len, test_data);
4209 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
4210 check_v_fixed_shift(&data, &data_len, len, test_data);
4211 check_lv_shift(&data, &data_len, len, test_data);
4212 }
4213
4214 OSMO_ASSERT(data == data_end);
4215
4216 /* Test at end of data */
4217
4218 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
4219 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
4220 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
4221 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
4222
4223 /* Test invalid data_len */
4224 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
4225 check_tlv_match_data_len(data_len, tag, len, test_data);
4226 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
4227 check_v_fixed_shift_data_len(data_len, len, test_data);
4228 check_lv_shift_data_len(data_len, len, test_data);
4229 }
4230 }
4231}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004232
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004233struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004234 struct gbproxy_peer *peer, uint32_t tlli,
4235 const uint8_t *imsi, size_t imsi_len, time_t now)
4236{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004237 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004238 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004239 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004240 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004241
4242 /* Check, whether the IMSI matches */
4243 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004244 imsi_matches = gbproxy_check_imsi(
4245 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004246 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004247 return NULL;
4248 }
4249
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004250 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004251
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004252 if (!link_info) {
4253 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004254
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004255 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004256 /* TLLI has changed somehow, adjust it */
4257 LOGP(DGPRS, LOGL_INFO,
4258 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004259 link_info->tlli.current, tlli);
4260 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004261 }
4262 }
4263
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004264 if (!link_info) {
4265 link_info = gbproxy_link_info_alloc(peer);
4266 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004267 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004268 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004269 tlli_already_known = 1;
4270 }
4271
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004272 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004273
4274 if (!tlli_already_known)
4275 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
4276
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004277 gbproxy_attach_link_info(peer, now, link_info);
4278 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004279
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004280 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004281 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004282
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004283 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004284}
4285
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004286static void test_gbproxy_tlli_expire(void)
4287{
4288 struct gbproxy_config cfg = {0};
4289 struct gbproxy_peer *peer;
4290 const char *err_msg = NULL;
4291 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4292 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004293 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004294 const uint32_t tlli1 = 1234 | 0xc0000000;
4295 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004296 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004297 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004298 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004299
4300 printf("Test TLLI info expiry\n\n");
4301
4302 gbproxy_init_config(&cfg);
4303
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004304 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4305 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004306 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4307 err_msg);
4308 OSMO_ASSERT(err_msg == NULL);
4309 }
4310
4311 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004312 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004313
4314 printf("Test TLLI replacement:\n");
4315
4316 cfg.tlli_max_len = 0;
4317 cfg.tlli_max_age = 0;
4318 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004319 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004320
4321 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004322 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004323 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004324 OSMO_ASSERT(link_info);
4325 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004326 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004327
4328 /* replace the old entry */
4329 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004330 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004331 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004332 OSMO_ASSERT(link_info);
4333 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004334 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004335
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004336 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004337
4338 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004339 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4340 OSMO_ASSERT(link_info);
4341 OSMO_ASSERT(link_info->tlli.current == tlli2);
4342 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4343 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004344
4345 printf("\n");
4346
4347 gbproxy_peer_free(peer);
4348 }
4349
4350 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004351 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004352
4353 printf("Test IMSI replacement:\n");
4354
4355 cfg.tlli_max_len = 0;
4356 cfg.tlli_max_age = 0;
4357 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004358 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004359
4360 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004361 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004362 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004363 OSMO_ASSERT(link_info);
4364 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004365 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004366
4367 /* try to replace the old entry */
4368 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004369 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004370 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004371 OSMO_ASSERT(link_info);
4372 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004373 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004374
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004375 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004376
4377 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004378 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4379 OSMO_ASSERT(!link_info);
4380 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4381 OSMO_ASSERT(link_info);
4382 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004383
4384 printf("\n");
4385
4386 gbproxy_peer_free(peer);
4387 }
4388
4389 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004390 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004391 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004392
4393 printf("Test TLLI expiry, max_len == 1:\n");
4394
4395 cfg.tlli_max_len = 1;
4396 cfg.tlli_max_age = 0;
4397 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004398 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004399
4400 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004401 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004402 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004403
4404 /* replace the old entry */
4405 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004406 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004407 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004408
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004409 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004410 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004411 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004412
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004413 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004414
4415 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004416 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4417 OSMO_ASSERT(!link_info);
4418 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4419 OSMO_ASSERT(link_info);
4420 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004421
4422 printf("\n");
4423
4424 gbproxy_peer_free(peer);
4425 }
4426
4427 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004428 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004429 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004430
4431 printf("Test TLLI expiry, max_age == 1:\n");
4432
4433 cfg.tlli_max_len = 0;
4434 cfg.tlli_max_age = 1;
4435 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004436 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004437
4438 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004439 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004440 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004441
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004442 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004443 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004444 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004445 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004446
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004447 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004448 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004449 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004450
4451 dump_peers(stdout, 2, now + 2, &cfg);
4452
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004453 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004454 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4455 OSMO_ASSERT(!link_info);
4456 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4457 OSMO_ASSERT(link_info);
4458 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004459
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004460 printf("\n");
4461
4462 gbproxy_peer_free(peer);
4463 }
4464
4465 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004466 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004467 int num_removed;
4468
4469 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4470
4471 cfg.tlli_max_len = 0;
4472 cfg.tlli_max_age = 1;
4473 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004474 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004475
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004476 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004477 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004478 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004479
4480 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004481 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004482 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004483 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004484
4485 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004486 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004487 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004488 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004489
4490 dump_peers(stdout, 2, now + 2, &cfg);
4491
4492 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004493 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004494 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004495 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004496
4497 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004498
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004499 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004500 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4501 OSMO_ASSERT(!link_info);
4502 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4503 OSMO_ASSERT(!link_info);
4504 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4505 OSMO_ASSERT(link_info);
4506 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004507
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004508 printf("\n");
4509
4510 gbproxy_peer_free(peer);
4511 }
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004512 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4513 gbprox_reset(&cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004514}
4515
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004516static void test_gbproxy_imsi_matching(void)
4517{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004518 const char *err_msg = NULL;
4519 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4520 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4521 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4522 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4523 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4524 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4525 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4526 const char *filter_re1 = ".*";
4527 const char *filter_re2 = "^1234";
4528 const char *filter_re3 = "^4321";
4529 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004530 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004531
4532 printf("=== Test IMSI/TMSI matching ===\n\n");
4533
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004534 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004535
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004536 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4537 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004538
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004539 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4540 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004541
4542 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004543 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004544 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004545 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004546
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004547 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4548 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004549
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004550 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4551 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004552
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004553 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4554 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004555
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004556 gbproxy_clear_patch_filter(&match);
4557 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004558
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004559 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4560 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004561
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004562 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4563 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004564 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004565 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004566 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004567 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4568 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4569 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4570 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4571 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004572
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004573 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4574 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004575
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004576 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4577 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4578 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4579 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4580 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4581 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4582 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004583
4584 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004585
4586 gbproxy_clear_patch_filter(&match);
4587 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004588}
4589
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004590static struct log_info_cat gprs_categories[] = {
4591 [DGPRS] = {
4592 .name = "DGPRS",
4593 .description = "GPRS Packet Service",
4594 .enabled = 1, .loglevel = LOGL_DEBUG,
4595 },
4596 [DNS] = {
4597 .name = "DNS",
4598 .description = "GPRS Network Service (NS)",
4599 .enabled = 1, .loglevel = LOGL_INFO,
4600 },
4601 [DBSSGP] = {
4602 .name = "DBSSGP",
4603 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4604 .enabled = 1, .loglevel = LOGL_DEBUG,
4605 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004606};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004607
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004608static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004609 .cat = gprs_categories,
4610 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004611};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004612
4613int main(int argc, char **argv)
4614{
4615 osmo_init_logging(&info);
4616 log_set_use_color(osmo_stderr_target, 0);
4617 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02004618 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004619
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004620 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004621 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4622 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004623
4624 rate_ctr_init(NULL);
4625
4626 setlinebuf(stdout);
4627
4628 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004629 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004630 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004631 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004632 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004633 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004634 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004635 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004636 test_gbproxy_ptmsi_patching();
Jacob Erlbecke99c3332014-10-20 16:25:01 +02004637 test_gbproxy_ptmsi_patching_bad_cases();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004638 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004639 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004640 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004641 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004642 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004643
4644 exit(EXIT_SUCCESS);
4645}