blob: 350c9f0eb68dbcf898c93a8c4757ba391ff9fb7a [file] [log] [blame]
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001/* test routines for gbproxy
2 * send NS messages to the gbproxy and dumps what happens
3 * (C) 2013 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 */
6
7#undef _GNU_SOURCE
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <getopt.h>
15#include <dlfcn.h>
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020017#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <osmocom/core/msgb.h>
21#include <osmocom/core/application.h>
22#include <osmocom/core/utils.h>
23#include <osmocom/core/logging.h>
24#include <osmocom/core/talloc.h>
25#include <osmocom/core/signal.h>
26#include <osmocom/core/rate_ctr.h>
Jacob Erlbeckb1381062014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck59748e62014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020029#include <osmocom/gprs/gprs_msgb.h>
30#include <osmocom/gprs/gprs_ns.h>
31#include <osmocom/gprs/gprs_bssgp.h>
32
33#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +020035#include <openbsc/gprs_llc.h>
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020036#include <openbsc/gprs_gb_parse.h>
37#include <openbsc/gsm_04_08_gprs.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020038#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020039
40#define REMOTE_BSS_ADDR 0x01020304
41#define REMOTE_SGSN_ADDR 0x05060708
42
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020043#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020044
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020045#define REMOTE_SGSN2_ADDR 0x15161718
46#define SGSN2_NSEI 0x0102
47
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020048#define MATCH_ANY (-1)
49
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020050struct gbproxy_config gbcfg = {0};
51
Jacob Erlbeckacfaff32014-09-22 18:54:34 +020052struct llist_head *received_messages = NULL;
53
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020054static int dump_global(FILE *stream, int indent)
55{
56 unsigned int i;
57 const struct rate_ctr_group_desc *desc;
58 int rc;
59
60 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
61 if (rc < 0)
62 return rc;
63
64 desc = gbcfg.ctrg->desc;
65
66 for (i = 0; i < desc->num_ctr; i++) {
67 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
68 if (ctr->current) {
69 rc = fprintf(stream, "%*s %s: %llu\n",
70 indent, "",
71 desc->ctr_desc[i].description,
72 (long long)ctr->current);
73
74 if (rc < 0)
75 return rc;
76 }
77 }
78
79 return 0;
80}
81
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020082static int dump_peers(FILE *stream, int indent, time_t now,
83 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020085 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020086 struct gprs_ra_id raid;
87 unsigned int i;
88 const struct rate_ctr_group_desc *desc;
89 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020090
91 rc = fprintf(stream, "%*sPeers:\n", indent, "");
92 if (rc < 0)
93 return rc;
94
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020095 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +020096 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020097 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020098 gsm48_parse_ra(&raid, peer->ra);
99
100 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
101 "RAI %u-%u-%u-%u\n",
102 indent, "",
103 peer->nsei, peer->bvci,
104 peer->blocked ? "" : "not ",
105 raid.mcc, raid.mnc, raid.lac, raid.rac);
106
107 if (rc < 0)
108 return rc;
109
110 desc = peer->ctrg->desc;
111
112 for (i = 0; i < desc->num_ctr; i++) {
113 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
114 if (ctr->current) {
115 rc = fprintf(stream, "%*s %s: %llu\n",
116 indent, "",
117 desc->ctr_desc[i].description,
118 (long long)ctr->current);
119
120 if (rc < 0)
121 return rc;
122 }
123 }
124
125 fprintf(stream, "%*s TLLI-Cache: %d\n",
Jacob Erlbeckf8562e32014-09-19 16:03:07 +0200126 indent, "", state->logical_link_count);
127 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200128 char mi_buf[200];
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200129 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200130 int stored_msgs = 0;
131 struct llist_head *iter;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200132 enum gbproxy_match_id match_id;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200133 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200134 stored_msgs++;
135
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200136 if (link_info->imsi_len > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200137 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
138 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200139 link_info->imsi,
140 link_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200141 } else {
142 snprintf(mi_buf, sizeof(mi_buf), "(none)");
143 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200144 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200145 indent, "", link_info->tlli.current);
146 if (link_info->tlli.assigned)
147 fprintf(stream, "/%08x", link_info->tlli.assigned);
148 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200149 fprintf(stream, " -> %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200150 link_info->sgsn_tlli.current);
151 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200152 fprintf(stream, "/%08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200153 link_info->sgsn_tlli.assigned);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200154 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200155 fprintf(stream, ", IMSI %s, AGE %d",
156 mi_buf, (int)age);
157
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200158 if (stored_msgs)
159 fprintf(stream, ", STORED %d", stored_msgs);
160
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +0200161 for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches);
162 ++match_id) {
163 if (cfg->matches[match_id].enable &&
164 link_info->is_matching[match_id]) {
165 fprintf(stream, ", IMSI matches");
166 break;
167 }
168 }
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200169
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200170 if (link_info->imsi_acq_pending)
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200171 fprintf(stream, ", IMSI acquisition in progress");
172
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200173 if (cfg->route_to_sgsn2)
174 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200175 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200176
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200177 if (link_info->is_deregistered)
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200178 fprintf(stream, ", DE-REGISTERED");
179
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200180 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200181 if (rc < 0)
182 return rc;
183 }
184 }
185
186 return 0;
187}
188
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200189const uint8_t *convert_ra(struct gprs_ra_id *raid)
190{
191 static uint8_t buf[6];
192 gsm48_construct_ra(buf, raid);
193 return buf;
194}
195
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200196/* DTAP - Attach Request */
197static const unsigned char dtap_attach_req[] = {
198 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
199 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
200 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
201 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
202 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
203 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200204};
205
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200206/* DTAP - Attach Request (invalid RAI) */
207static const unsigned char dtap_attach_req2[] = {
208 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
209 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
210 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
211 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
212 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
213 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
214};
215
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200216/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
217static const unsigned char dtap_attach_req3[] = {
218 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
219 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
220 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
221 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
222 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
223 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
224};
225
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200226/* DTAP - Identity Request */
227static const unsigned char dtap_identity_req[] = {
228 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200229};
230
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200231/* DTAP - Identity Response */
232static const unsigned char dtap_identity_resp[] = {
233 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
234 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200235};
236
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200237/* DTAP - Identity Response, IMSI 2 */
238static const unsigned char dtap_identity2_resp[] = {
239 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
240 0x16, 0x17, 0x18
241};
242
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200243/* DTAP - Identity Response, IMSI 3 */
244static const unsigned char dtap_identity3_resp[] = {
245 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
246 0x26, 0x27, 0x28
247};
248
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200249/* DTAP - Attach Accept */
250static const unsigned char dtap_attach_acc[] = {
251 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
252 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
253 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200254};
255
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200256/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200257static const unsigned char dtap_attach_acc2[] = {
258 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
259 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
260 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
261};
262
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200263/* DTAP - Attach Complete */
264static const unsigned char dtap_attach_complete[] = {
265 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200266};
267
Jacob Erlbeck2bf32612014-09-22 11:26:58 +0200268/* DTAP - Attach Reject (GPRS services not allowed) */
269static const unsigned char dtap_attach_rej7[] = {
270 0x08, 0x04, 0x07
271};
272
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200273/* DTAP - GMM Information */
274static const unsigned char dtap_gmm_information[] = {
275 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200276};
277
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200278/* DTAP - Routing Area Update Request */
279static const unsigned char dtap_ra_upd_req[] = {
280 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
281 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
282 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
283 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
284 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
285 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
286 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200287};
288
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200289/* DTAP - Routing Area Update Accept */
290static const unsigned char dtap_ra_upd_acc[] = {
291 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
292 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
293 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200294};
295
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200296/* DTAP - Routing Area Update Accept, P-TMSI 2 */
297static const unsigned char dtap_ra_upd_acc2[] = {
298 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
299 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
300 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
301};
302
303/* DTAP - Routing Area Update Accept, P-TMSI 3 */
304static const unsigned char dtap_ra_upd_acc3[] = {
305 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
306 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
307 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
308};
309
310/* DTAP - Routing Area Update Complete */
311static const unsigned char dtap_ra_upd_complete[] = {
312 0x08, 0x0a
313};
314
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200315/* DTAP - Routing Area Update Reject */
316/* cause = 10 ("Implicitly detached"), force_standby = 0 */
317static const unsigned char dtap_ra_upd_rej[] = {
318 0x08, 0x0b, 0x0a, 0x00,
319};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200321/* DTAP - Activate PDP Context Request */
322static const unsigned char dtap_act_pdp_ctx_req[] = {
323 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200324 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
326 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
327 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
328 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200329 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200330};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200331
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200332/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200333/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200334static const unsigned char dtap_detach_po_req[] = {
335 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
336 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200337};
338
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200339/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200340/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200341static const unsigned char dtap_detach_req[] = {
342 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
343 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200344};
345
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200346/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200347static const unsigned char dtap_detach_acc[] = {
348 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200349};
350
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200351/* DTAP - Detach Request (MT) */
352/* normal detach, reattach required, implicitly detached */
353static const unsigned char dtap_mt_detach_rea_req[] = {
354 0x08, 0x05, 0x01, 0x25, 0x0a
355};
356
357/* DTAP - Detach Request (MT) */
358/* normal detach, reattach not required, implicitly detached */
359static const unsigned char dtap_mt_detach_req[] = {
360 0x08, 0x05, 0x02, 0x25, 0x0a
361};
362
363/* DTAP - Detach Accept (MT) */
364static const unsigned char dtap_mt_detach_acc[] = {
365 0x08, 0x06
366};
367
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200368/* GPRS-LLC - SAPI: LLGMM, U, XID */
369static const unsigned char llc_u_xid_ul[] = {
370 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
371 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
372};
373
374/* GPRS-LLC - SAPI: LLGMM, U, XID */
375static const unsigned char llc_u_xid_dl[] = {
376 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
377 0xe4, 0xa9, 0x1a, 0x9e
378};
379
380/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
381static const unsigned char llc_ui_ll11_dns_query_ul[] = {
382 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
383 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
384 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
385 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
386 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
387 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
388 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
389 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
390 0x8f, 0x07
391};
392
393/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
394static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
395 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
396 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
397 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
398 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
399 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
400 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
401 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
402 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
403 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
404 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
405 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
406 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
407 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
408 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
409 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
410 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
411 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
412 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
413 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
414 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
415 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
416 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
417 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
418 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
419 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
420 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
421};
422
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200423static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
424 struct sockaddr_in *peer, const unsigned char* data,
425 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200426
427static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
428 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
429{
430 /* GPRS Network Service, PDU type: NS_RESET,
431 */
432 unsigned char msg[12] = {
433 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
434 0x04, 0x82, 0x11, 0x22
435 };
436
437 msg[3] = cause;
438 msg[6] = nsvci / 256;
439 msg[7] = nsvci % 256;
440 msg[10] = nsei / 256;
441 msg[11] = nsei % 256;
442
443 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
444}
445
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200446static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
447 uint16_t nsvci, uint16_t nsei)
448{
449 /* GPRS Network Service, PDU type: NS_RESET_ACK,
450 */
451 unsigned char msg[9] = {
452 0x03, 0x01, 0x82, 0x11, 0x22,
453 0x04, 0x82, 0x11, 0x22
454 };
455
456 msg[3] = nsvci / 256;
457 msg[4] = nsvci % 256;
458 msg[7] = nsei / 256;
459 msg[8] = nsei % 256;
460
461 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
462}
463
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200464static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
465{
466 /* GPRS Network Service, PDU type: NS_ALIVE */
467 unsigned char msg[1] = {
468 0x0a
469 };
470
471 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
472}
473
474static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
475{
476 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
477 unsigned char msg[1] = {
478 0x0b
479 };
480
481 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
482}
483
484static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
485{
486 /* GPRS Network Service, PDU type: NS_UNBLOCK */
487 unsigned char msg[1] = {
488 0x06
489 };
490
491 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
492}
493
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200494static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
495{
496 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
497 unsigned char msg[1] = {
498 0x07
499 };
500
501 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
502}
503
504static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
505 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200506 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
507{
508 /* GPRS Network Service, PDU type: NS_UNITDATA */
509 unsigned char msg[4096] = {
510 0x00, 0x00, 0x00, 0x00
511 };
512
513 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
514
515 msg[2] = nsbvci / 256;
516 msg[3] = nsbvci % 256;
517 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
518
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200519 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200520}
521
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200522static void send_bssgp_ul_unitdata(
523 struct gprs_ns_inst *nsi, const char *text,
524 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
525 struct gprs_ra_id *raid, uint16_t cell_id,
526 const uint8_t *llc_msg, size_t llc_msg_size)
527{
528 /* GPRS Network Service, PDU type: NS_UNITDATA */
529 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
530 unsigned char msg[4096] = {
531 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
532 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
533 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
534 };
535
536 size_t bssgp_msg_size = 23 + llc_msg_size;
537
538 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
539
540 gsm48_construct_ra(msg + 10, raid);
541 msg[1] = (uint8_t)(tlli >> 24);
542 msg[2] = (uint8_t)(tlli >> 16);
543 msg[3] = (uint8_t)(tlli >> 8);
544 msg[4] = (uint8_t)(tlli >> 0);
545 msg[16] = cell_id / 256;
546 msg[17] = cell_id % 256;
547 msg[21] = llc_msg_size / 256;
548 msg[22] = llc_msg_size % 256;
549 memcpy(msg + 23, llc_msg, llc_msg_size);
550
551 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
552 src_addr, nsbvci, msg, bssgp_msg_size);
553}
554
555static void send_bssgp_dl_unitdata(
556 struct gprs_ns_inst *nsi, const char *text,
557 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
558 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
559 const uint8_t *llc_msg, size_t llc_msg_size)
560{
561 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
562 unsigned char msg[4096] = {
563 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
564 0x16, 0x82, 0x02, 0x58,
565 };
566 unsigned char racap_drx[] = {
567 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
568 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
569 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
570 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
571 };
572
573 size_t bssgp_msg_size = 0;
574
575 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
576
577 msg[1] = (uint8_t)(tlli >> 24);
578 msg[2] = (uint8_t)(tlli >> 16);
579 msg[3] = (uint8_t)(tlli >> 8);
580 msg[4] = (uint8_t)(tlli >> 0);
581
582 bssgp_msg_size = 12;
583
584 if (with_racap_drx) {
585 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
586 bssgp_msg_size += sizeof(racap_drx);
587 }
588
589 if (imsi) {
590 OSMO_ASSERT(imsi_size <= 127);
591 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
592 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
593 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
594 bssgp_msg_size += 2 + imsi_size;
595 }
596
597 if ((bssgp_msg_size % 4) != 0) {
598 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
599 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
600 msg[bssgp_msg_size + 1] = 0x80 | abytes;
601 memset(msg + bssgp_msg_size + 2, 0, abytes);
602 bssgp_msg_size += 2 + abytes;
603 }
604
605 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
606 if (llc_msg_size < 128) {
607 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
608 bssgp_msg_size += 2;
609 } else {
610 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
611 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
612 bssgp_msg_size += 3;
613 }
614 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
615 bssgp_msg_size += llc_msg_size;
616
617
618 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
619 src_addr, nsbvci, msg, bssgp_msg_size);
620}
621
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200622static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
623 uint16_t bvci)
624{
625 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
626 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200627 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200628 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200629 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
630 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200631 };
632
633 msg[3] = bvci / 256;
634 msg[4] = bvci % 256;
635
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200636 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
637}
638
639static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
640 struct sockaddr_in *src_addr, uint16_t bvci)
641{
642 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
643 * BSSGP RESET_ACK */
644 static unsigned char msg[5] = {
645 0x23, 0x04, 0x82, 0x00,
646 0x00
647 };
648
649 msg[3] = bvci / 256;
650 msg[4] = bvci % 256;
651
652 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200653}
654
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200655static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
656 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200657 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200658 struct gprs_ra_id *raid)
659{
660 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
661 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200662 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
663 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200664 };
665
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200666 msg[3] = (uint8_t)(tlli >> 24);
667 msg[4] = (uint8_t)(tlli >> 16);
668 msg[5] = (uint8_t)(tlli >> 8);
669 msg[6] = (uint8_t)(tlli >> 0);
670
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200671 gsm48_construct_ra(msg + 9, raid);
672
673 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
674}
675
676static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
677 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200678 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200679 struct gprs_ra_id *raid)
680{
681 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
682 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200683 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
684 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200685 0x81, 0x01
686 };
687
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200688 msg[3] = (uint8_t)(tlli >> 24);
689 msg[4] = (uint8_t)(tlli >> 16);
690 msg[5] = (uint8_t)(tlli >> 8);
691 msg[6] = (uint8_t)(tlli >> 0);
692
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200693 gsm48_construct_ra(msg + 9, raid);
694
695 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
696}
697
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200698static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
699 struct sockaddr_in *src_addr,
700 uint16_t bvci, uint32_t tlli,
701 unsigned n_frames, unsigned n_octets)
702{
703 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
704 unsigned char msg[] = {
705 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
706 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
707 /* n octets */ 0xff, 0xff, 0xff
708 };
709
710 msg[3] = (uint8_t)(tlli >> 24);
711 msg[4] = (uint8_t)(tlli >> 16);
712 msg[5] = (uint8_t)(tlli >> 8);
713 msg[6] = (uint8_t)(tlli >> 0);
714 msg[9] = (uint8_t)(n_frames);
715 msg[12] = (uint8_t)(bvci >> 8);
716 msg[13] = (uint8_t)(bvci >> 0);
717 msg[16] = (uint8_t)(n_octets >> 16);
718 msg[17] = (uint8_t)(n_octets >> 8);
719 msg[18] = (uint8_t)(n_octets >> 0);
720
721 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
722}
723
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200724static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
725 struct sockaddr_in *src_addr,
726 uint16_t bvci, uint8_t tag)
727{
728 /* GPRS Network Service, PDU type: NS_UNITDATA,
729 * BSSGP FLOW_CONTROL_BVC */
730 unsigned char msg[] = {
731 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
732 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
733 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
734 };
735
736 msg[3] = tag;
737
738 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
739 msg, sizeof(msg));
740}
741
742static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
743 struct sockaddr_in *src_addr,
744 uint16_t bvci, uint8_t tag)
745{
746 /* GPRS Network Service, PDU type: NS_UNITDATA,
747 * BSSGP FLOW_CONTROL_BVC_ACK */
748 unsigned char msg[] = {
749 0x27, 0x1e, 0x81, /* Tag */ 0xce
750 };
751
752 msg[3] = tag;
753
754 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
755 msg, sizeof(msg));
756}
757
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200758static void send_llc_ul_ui(
759 struct gprs_ns_inst *nsi, const char *text,
760 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
761 struct gprs_ra_id *raid, uint16_t cell_id,
762 unsigned sapi, unsigned nu,
763 const uint8_t *msg, size_t msg_size)
764{
765 unsigned char llc_msg[4096] = {
766 0x00, 0xc0, 0x01
767 };
768
769 size_t llc_msg_size = 3 + msg_size + 3;
770 uint8_t e_bit = 0;
771 uint8_t pm_bit = 1;
772 unsigned fcs;
773
774 nu &= 0x01ff;
775
776 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
777
778 llc_msg[0] = (sapi & 0x0f);
779 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
780 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
781
782 memcpy(llc_msg + 3, msg, msg_size);
783
784 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
785 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
786 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
787 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
788
789 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
790 src_addr, nsbvci, tlli, raid, cell_id,
791 llc_msg, llc_msg_size);
792}
793
794static void send_llc_dl_ui(
795 struct gprs_ns_inst *nsi, const char *text,
796 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
797 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
798 unsigned sapi, unsigned nu,
799 const uint8_t *msg, size_t msg_size)
800{
801 /* GPRS Network Service, PDU type: NS_UNITDATA */
802 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
803 unsigned char llc_msg[4096] = {
804 0x00, 0x00, 0x01
805 };
806
807 size_t llc_msg_size = 3 + msg_size + 3;
808 uint8_t e_bit = 0;
809 uint8_t pm_bit = 1;
810 unsigned fcs;
811
812 nu &= 0x01ff;
813
814 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
815
816 llc_msg[0] = 0x40 | (sapi & 0x0f);
817 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
818 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
819
820 memcpy(llc_msg + 3, msg, msg_size);
821
822 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
823 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
824 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
825 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
826
827 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
828 src_addr, nsbvci, tlli,
829 with_racap_drx, imsi, imsi_size,
830 llc_msg, llc_msg_size);
831}
832
833
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200834static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
835 uint16_t nsvci, uint16_t nsei)
836{
837 printf("Setup NS-VC: remote 0x%08x:%d, "
838 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
839 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
840 nsvci, nsvci, nsei, nsei);
841
842 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
843 send_ns_alive(nsi, src_addr);
844 send_ns_unblock(nsi, src_addr);
845 send_ns_alive_ack(nsi, src_addr);
846}
847
848static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
849 uint16_t bvci)
850{
851 printf("Setup BSSGP: remote 0x%08x:%d, "
852 "BVCI 0x%04x(%d)\n\n",
853 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
854 bvci, bvci);
855
856 send_bssgp_reset(nsi, src_addr, bvci);
857}
858
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200859static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
860 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200861{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200862 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
863 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200864 send_ns_alive_ack(nsi, sgsn_peer);
865 send_ns_unblock_ack(nsi, sgsn_peer);
866 send_ns_alive(nsi, sgsn_peer);
867}
868
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200869static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
870{
871 sgsn_peer->sin_family = AF_INET;
872 sgsn_peer->sin_port = htons(32000);
873 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
874}
875
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200876static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
877{
878 sgsn_peer->sin_family = AF_INET;
879 sgsn_peer->sin_port = htons(32001);
880 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
881}
882
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200883static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
884{
885 size_t i;
886
887 for (i = 0; i < size; ++i) {
888 bss_peers[i].sin_family = AF_INET;
889 bss_peers[i].sin_port = htons((i + 1) * 1111);
890 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
891 }
892}
893
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200894int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
895 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
896
897/* override */
898int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
899 struct msgb *msg, uint16_t bvci)
900{
901 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
902 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200903 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200904
905 switch (event) {
906 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +0200907 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200908 default:
909 break;
910 }
911 return 0;
912}
913
914/* override */
915ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
916 const struct sockaddr *dest_addr, socklen_t addrlen)
917{
918 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
919 const struct sockaddr *, socklen_t);
920 static sendto_t real_sendto = NULL;
921 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200922 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200923
924 if (!real_sendto)
925 real_sendto = dlsym(RTLD_NEXT, "sendto");
926
927 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200928 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
929 dest_host, dest_port,
930 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200931 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200932 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
933 dest_host, dest_port,
934 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200935 else if (dest_host == REMOTE_SGSN2_ADDR)
936 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
937 dest_host, dest_port,
938 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200939 else
940 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
941
942 return len;
943}
944
945/* override */
946int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
947{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200948 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
949 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200950 uint16_t bvci = msgb_bvci(msg);
951 uint16_t nsei = msgb_nsei(msg);
952
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200953 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200954
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200955 if (!real_gprs_ns_sendmsg)
956 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
957
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200958 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200959 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
960 "msg length %d (%s)\n",
961 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200962 else if (nsei == SGSN2_NSEI)
963 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
964 "msg length %d (%s)\n",
965 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200966 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200967 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
968 "msg length %d (%s)\n",
969 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200970
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200971 if (received_messages) {
972 struct msgb *msg_copy;
973 msg_copy = gprs_msgb_copy(msg, "received_messages");
974 llist_add_tail(&msg_copy->list, received_messages);
975 }
976
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200977 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978}
979
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200980/* Get the next message from the receive FIFO
981 *
982 * \returns a pointer to the message which will be invalidated at the next call
983 * to expect_msg. Returns NULL, if there is no message left.
984 */
985static struct msgb *expect_msg(void)
986{
987 static struct msgb *msg = NULL;
988
989 msgb_free(msg);
990 msg = NULL;
991
992 if (!received_messages)
993 return NULL;
994
995 if (llist_empty(received_messages))
996 return NULL;
997
998 msg = llist_entry(received_messages->next, struct msgb, list);
999 llist_del(&msg->list);
1000
1001 return msg;
1002}
1003
1004struct expect_result {
1005 struct msgb *msg;
1006 struct gprs_gb_parse_context parse_ctx;
1007};
1008
1009static struct expect_result *expect_bssgp_msg(
1010 int match_nsei, int match_bvci, int match_pdu_type)
1011{
1012 static struct expect_result result;
1013 static const struct expect_result empty_result = {0,};
1014 static struct msgb *msg;
1015 uint16_t nsei;
1016 int rc;
1017
1018 memcpy(&result, &empty_result, sizeof(result));
1019
1020 msg = expect_msg();
1021 if (!msg)
1022 return NULL;
1023
1024 nsei = msgb_nsei(msg);
1025
1026 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1027 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1028 __func__, match_nsei, nsei);
1029 return NULL;
1030 }
1031
1032 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1033 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1034 __func__, match_bvci, msgb_bvci(msg));
1035 return NULL;
1036 }
1037
1038 result.msg = msg;
1039
1040 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1041 result.parse_ctx.peer_nsei = nsei;
1042
1043 if (!msgb_bssgph(msg)) {
1044 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1045 return NULL;
1046 }
1047
1048 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1049 &result.parse_ctx);
1050
1051 if (!rc) {
1052 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1053 return NULL;
1054 }
1055
1056 if (match_pdu_type != MATCH_ANY &&
1057 match_pdu_type != result.parse_ctx.pdu_type) {
1058 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1059 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1060 return NULL;
1061 }
1062
1063 return &result;
1064}
1065
1066static struct expect_result *expect_llc_msg(
1067 int match_nsei, int match_bvci, int match_sapi, int match_type)
1068{
1069 static struct expect_result *result;
1070
1071 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1072 if (!result)
1073 return NULL;
1074
1075 if (!result->parse_ctx.llc) {
1076 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1077 return NULL;
1078 }
1079
1080 if (match_sapi != MATCH_ANY &&
1081 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1082 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1083 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1084 return NULL;
1085 }
1086
1087 if (match_type != MATCH_ANY &&
1088 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1089 fprintf(stderr,
1090 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1091 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1092 return NULL;
1093 }
1094
1095 return result;
1096}
1097
1098static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1099 int match_type)
1100{
1101 static struct expect_result *result;
1102
1103 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1104 if (!result)
1105 return NULL;
1106
1107 if (!result->parse_ctx.g48_hdr) {
1108 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1109 return NULL;
1110 }
1111
1112 if (match_type != MATCH_ANY &&
1113 match_type != result->parse_ctx.g48_hdr->msg_type) {
1114 fprintf(stderr,
1115 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1116 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1117 return NULL;
1118 }
1119
1120 return result;
1121}
1122
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001123static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1124 struct rate_ctr_group *ctrg)
1125{
1126 unsigned int i;
1127
1128 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1129 struct rate_ctr *ctr = &ctrg->ctr[i];
1130 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1131 fprintf(stream, " %s%s: %llu%s",
1132 prefix, ctrg->desc->ctr_desc[i].description,
1133 (long long)ctr->current,
1134 "\n");
1135 };
1136}
1137
1138/* Signal handler for signals from NS layer */
1139static int test_signal(unsigned int subsys, unsigned int signal,
1140 void *handler_data, void *signal_data)
1141{
1142 struct ns_signal_data *nssd = signal_data;
1143 int rc;
1144
1145 if (subsys != SS_L_NS)
1146 return 0;
1147
1148 switch (signal) {
1149 case S_NS_RESET:
1150 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1151 nssd->nsvc->nsvci,
1152 gprs_ns_ll_str(nssd->nsvc));
1153 break;
1154
1155 case S_NS_ALIVE_EXP:
1156 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1157 nssd->nsvc->nsvci,
1158 gprs_ns_ll_str(nssd->nsvc));
1159 break;
1160
1161 case S_NS_BLOCK:
1162 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1163 nssd->nsvc->nsvci,
1164 gprs_ns_ll_str(nssd->nsvc));
1165 break;
1166
1167 case S_NS_UNBLOCK:
1168 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1169 nssd->nsvc->nsvci,
1170 gprs_ns_ll_str(nssd->nsvc));
1171 break;
1172
1173 case S_NS_REPLACED:
1174 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1175 nssd->nsvc->nsvci,
1176 gprs_ns_ll_str(nssd->nsvc));
1177 printf(" -> 0x%04x/%s\n",
1178 nssd->old_nsvc->nsvci,
1179 gprs_ns_ll_str(nssd->old_nsvc));
1180 break;
1181
1182 default:
1183 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1184 nssd->nsvc->nsvci,
1185 gprs_ns_ll_str(nssd->nsvc));
1186 break;
1187 }
1188 printf("\n");
1189 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1190 return rc;
1191}
1192
1193static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1194{
1195 struct msgb *msg;
1196 int ret;
1197 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1198 fprintf(stderr, "message too long: %d\n", data_len);
1199 return -1;
1200 }
1201
1202 msg = gprs_ns_msgb_alloc();
1203 memmove(msg->data, data, data_len);
1204 msg->l2h = msg->data;
1205 msgb_put(msg, data_len);
1206
1207 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1208 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1209 osmo_hexdump(data, data_len));
1210
1211 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1212
1213 printf("result (%s) = %d\n\n", text, ret);
1214
1215 msgb_free(msg);
1216
1217 return ret;
1218}
1219
1220static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1221{
1222 struct gprs_nsvc *nsvc;
1223
1224 printf("Current NS-VCIs:\n");
1225 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1226 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001227 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001228 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001229 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1230 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1231 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001232 );
1233 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1234 }
1235 printf("\n");
1236}
1237
1238static void test_gbproxy()
1239{
1240 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1241 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001242 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001243
1244 bssgp_nsi = nsi;
1245 gbcfg.nsi = bssgp_nsi;
1246 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1247
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001248 configure_sgsn_peer(&sgsn_peer);
1249 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001250
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001251 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001252 printf("--- Initialise SGSN ---\n\n");
1253
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001254 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001255 gprs_dump_nsi(nsi);
1256
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001257 printf("--- Initialise BSS 1 ---\n\n");
1258
1259 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1260 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1261 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001262 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001263
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001264 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1265
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001266 printf("--- Initialise BSS 2 ---\n\n");
1267
1268 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1269 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1270 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001271 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001272
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001273 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1274
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001275 printf("--- Move BSS 1 to new port ---\n\n");
1276
1277 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1278 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001279 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001280
1281 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1282
1283 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1284 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001285 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001286
1287 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1288
1289 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1290 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001291 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001292
1293 printf("--- Move BSS 2 to new port ---\n\n");
1294
1295 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1296 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001297 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001298
1299 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1300
1301 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1302 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001303 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001304
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001305 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1306
1307 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1308 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001309 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001310
1311 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1312
1313 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1314 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001315 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001316
1317 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1318
1319 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1320
1321 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1322 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001323 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001324
1325 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1326
1327 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1328
1329 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1330 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001331 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001332
1333 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1334
1335 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1336
1337 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1338
1339 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1340
1341 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1342
1343 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1344
1345 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1346
1347 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1348
1349 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1350
1351 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1352
1353 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1354
1355 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1356
1357 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1358
1359 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1360
1361 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1362 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001363 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001364
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001365 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001366
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001367 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1368
1369 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1370
1371 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1372
1373 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1374
1375 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1376
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001377 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1378
1379 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1380
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001381 /* Find peer */
1382 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1383 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1384 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1385 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1386 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1387 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1388
1389
1390 /* Cleanup */
1391 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1392 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1393 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1394 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1395 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1396
1397 dump_peers(stdout, 0, 0, &gbcfg);
1398
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001399 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001400
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001401 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001402 gprs_ns_destroy(nsi);
1403 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001404}
1405
1406static void test_gbproxy_ident_changes()
1407{
1408 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1409 struct sockaddr_in bss_peer[1] = {{0},};
1410 struct sockaddr_in sgsn_peer= {0};
1411 uint16_t nsei[2] = {0x1000, 0x2000};
1412 uint16_t nsvci[2] = {0x1001, 0x2001};
1413 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1414
1415 bssgp_nsi = nsi;
1416 gbcfg.nsi = bssgp_nsi;
1417 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1418
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001419 configure_sgsn_peer(&sgsn_peer);
1420 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001421
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001422 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001423 printf("--- Initialise SGSN ---\n\n");
1424
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001425 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001426 gprs_dump_nsi(nsi);
1427
1428 printf("--- Initialise BSS 1 ---\n\n");
1429
1430 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1431 gprs_dump_nsi(nsi);
1432
1433 printf("--- Setup BVCI 1 ---\n\n");
1434
1435 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1436 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001437 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001438
1439 printf("--- Setup BVCI 2 ---\n\n");
1440
1441 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1442 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001443 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001444
1445 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1446
1447 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1448 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1449
1450 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1451
1452 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1453 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1454
1455 printf("--- Change NSEI ---\n\n");
1456
1457 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1458 gprs_dump_nsi(nsi);
1459
1460 printf("--- Setup BVCI 1 ---\n\n");
1461
1462 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1463 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001464 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001465
1466 printf("--- Setup BVCI 3 ---\n\n");
1467
1468 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1469 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001470 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001471
1472 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1473
1474 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1475 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1476
1477 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1478 " (should fail) ---\n\n");
1479
1480 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001481 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001482 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001483 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001484
1485 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1486
1487 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1488 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1489
1490 printf("--- Change NSVCI ---\n\n");
1491
1492 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1493 gprs_dump_nsi(nsi);
1494
1495 printf("--- Setup BVCI 1 ---\n\n");
1496
1497 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1498 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001499 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001500
1501 printf("--- Setup BVCI 4 ---\n\n");
1502
1503 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1504 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001505 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001506
1507 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1508
1509 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1510 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1511
1512 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1513 " (should fail) ---\n\n");
1514
1515 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001516 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001517 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001518 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001519
1520 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1521
1522 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1523 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1524
1525 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1526
1527 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1528 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1529
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001530 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001531 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001532
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001533 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001534 gprs_ns_destroy(nsi);
1535 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001536}
1537
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001538static void test_gbproxy_ra_patching()
1539{
1540 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1541 struct sockaddr_in bss_peer[1] = {{0},};
1542 struct sockaddr_in sgsn_peer= {0};
1543 struct gprs_ra_id rai_bss =
1544 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1545 struct gprs_ra_id rai_sgsn =
1546 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1547 struct gprs_ra_id rai_unknown =
1548 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001549 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001550 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001551 const uint32_t ptmsi = 0xefe2b700;
1552 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001553 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001554 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001555 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02001556 const char *patch_re = "^9898|^121314";
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001557 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001558 struct gbproxy_peer *peer;
Jacob Erlbeck55ec2bf2014-09-23 14:56:38 +02001559 LLIST_HEAD(rcv_list);
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 Freythereece62772014-08-04 15:42:36 +02001873 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001874 gprs_ns_destroy(nsi);
1875 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001876}
1877
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001878static void test_gbproxy_ptmsi_assignment()
1879{
1880 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1881 struct sockaddr_in bss_peer[1] = {{0},};
1882 struct sockaddr_in sgsn_peer= {0};
1883 struct gprs_ra_id rai_bss =
1884 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1885 struct gprs_ra_id rai_unknown =
1886 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1887 uint16_t cell_id = 0x1234;
1888
1889 const uint32_t ptmsi = 0xefe2b700;
1890 const uint32_t local_tlli = 0xefe2b700;
1891
1892 const uint32_t foreign_tlli1 = 0x8000dead;
1893 const uint32_t foreign_tlli2 = 0x8000beef;
1894
1895 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1896 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1897
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001898 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001899 struct gbproxy_peer *peer;
1900 unsigned bss_nu = 0;
1901 unsigned sgsn_nu = 0;
1902
1903 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1904
1905 bssgp_nsi = nsi;
1906 gbcfg.nsi = bssgp_nsi;
1907 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1908 gbcfg.core_mcc = 0;
1909 gbcfg.core_mnc = 0;
1910 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1911 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1912 gbcfg.patch_ptmsi = 0;
1913 gbcfg.bss_ptmsi_state = 0;
1914 gbcfg.sgsn_tlli_state = 1;
1915
1916 configure_sgsn_peer(&sgsn_peer);
1917 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1918
1919 printf("=== %s ===\n", __func__);
1920 printf("--- Initialise SGSN ---\n\n");
1921
1922 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1923
1924 printf("--- Initialise BSS 1 ---\n\n");
1925
1926 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1927 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1928
1929 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1930 OSMO_ASSERT(peer != NULL);
1931
1932 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1933
1934 gprs_dump_nsi(nsi);
1935 dump_global(stdout, 0);
1936 dump_peers(stdout, 0, 0, &gbcfg);
1937
1938 printf("--- Establish first LLC connection ---\n\n");
1939
1940 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1941 foreign_tlli1, &rai_unknown, cell_id,
1942 GPRS_SAPI_GMM, bss_nu++,
1943 dtap_attach_req, sizeof(dtap_attach_req));
1944
1945 dump_peers(stdout, 0, 0, &gbcfg);
1946
1947 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1948 foreign_tlli1, 0, NULL, 0,
1949 GPRS_SAPI_GMM, sgsn_nu++,
1950 dtap_identity_req, sizeof(dtap_identity_req));
1951
1952 dump_peers(stdout, 0, 0, &gbcfg);
1953
1954 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1955 foreign_tlli1, &rai_bss, cell_id,
1956 GPRS_SAPI_GMM, bss_nu++,
1957 dtap_identity_resp, sizeof(dtap_identity_resp));
1958
1959 dump_peers(stdout, 0, 0, &gbcfg);
1960
1961 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1962 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1963 GPRS_SAPI_GMM, sgsn_nu++,
1964 dtap_attach_acc, sizeof(dtap_attach_acc));
1965
1966 dump_peers(stdout, 0, 0, &gbcfg);
1967
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001968 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1969 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1970 OSMO_ASSERT(link_info);
1971 OSMO_ASSERT(link_info == link_info2);
1972 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1973 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1974 OSMO_ASSERT(!link_info->tlli.bss_validated);
1975 OSMO_ASSERT(!link_info->tlli.net_validated);
1976 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001977
1978 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1979 local_tlli, &rai_bss, cell_id,
1980 GPRS_SAPI_GMM, bss_nu++,
1981 dtap_attach_complete, sizeof(dtap_attach_complete));
1982
1983 dump_peers(stdout, 0, 0, &gbcfg);
1984
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001985 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1986 OSMO_ASSERT(link_info);
1987 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1988 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1989 OSMO_ASSERT(link_info->tlli.bss_validated);
1990 OSMO_ASSERT(!link_info->tlli.net_validated);
1991 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001992
1993
1994 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1995 local_tlli, 1, imsi1, sizeof(imsi1),
1996 GPRS_SAPI_GMM, sgsn_nu++,
1997 dtap_gmm_information, sizeof(dtap_gmm_information));
1998
1999 dump_peers(stdout, 0, 0, &gbcfg);
2000
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002001 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
2002 OSMO_ASSERT(link_info);
2003 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2004 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002005
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002006 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2007 OSMO_ASSERT(link_info == link_info2);
2008 OSMO_ASSERT(link_info->tlli.assigned == 0);
2009 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2010 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002011
2012 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2013
2014 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2015 foreign_tlli2, &rai_unknown, cell_id,
2016 GPRS_SAPI_GMM, bss_nu++,
2017 dtap_attach_req, sizeof(dtap_attach_req));
2018
2019 dump_peers(stdout, 0, 0, &gbcfg);
2020
2021 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2022 foreign_tlli2, 0, NULL, 0,
2023 GPRS_SAPI_GMM, sgsn_nu++,
2024 dtap_identity_req, sizeof(dtap_identity_req));
2025
2026 dump_peers(stdout, 0, 0, &gbcfg);
2027
2028 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2029 foreign_tlli2, &rai_bss, cell_id,
2030 GPRS_SAPI_GMM, bss_nu++,
2031 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2032
2033 dump_peers(stdout, 0, 0, &gbcfg);
2034
2035 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2036 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2037 GPRS_SAPI_GMM, sgsn_nu++,
2038 dtap_attach_acc, sizeof(dtap_attach_acc));
2039
2040 dump_peers(stdout, 0, 0, &gbcfg);
2041
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002042 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2043 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2044 OSMO_ASSERT(link_info);
2045 OSMO_ASSERT(link_info == link_info2);
2046 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2047 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2048 OSMO_ASSERT(!link_info->tlli.bss_validated);
2049 OSMO_ASSERT(!link_info->tlli.net_validated);
2050 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002051
2052 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2053 local_tlli, &rai_bss, cell_id,
2054 GPRS_SAPI_GMM, bss_nu++,
2055 dtap_attach_complete, sizeof(dtap_attach_complete));
2056
2057 dump_peers(stdout, 0, 0, &gbcfg);
2058
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002059 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2060 OSMO_ASSERT(link_info);
2061 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2062 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2063 OSMO_ASSERT(link_info->tlli.bss_validated);
2064 OSMO_ASSERT(!link_info->tlli.net_validated);
2065 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002066
2067 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2068 local_tlli, 1, imsi2, sizeof(imsi2),
2069 GPRS_SAPI_GMM, sgsn_nu++,
2070 dtap_gmm_information, sizeof(dtap_gmm_information));
2071
2072 dump_peers(stdout, 0, 0, &gbcfg);
2073
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002074 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2075 OSMO_ASSERT(link_info);
2076 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2077 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002078
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002079 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2080 OSMO_ASSERT(link_info == link_info2);
2081 OSMO_ASSERT(link_info->tlli.assigned == 0);
2082 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2083 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002084
2085 dump_global(stdout, 0);
2086
2087 gbprox_reset(&gbcfg);
2088 gprs_ns_destroy(nsi);
2089 nsi = NULL;
2090}
2091
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002092static void test_gbproxy_ptmsi_patching()
2093{
2094 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2095 struct sockaddr_in bss_peer[1] = {{0},};
2096 struct sockaddr_in sgsn_peer= {0};
2097 struct gprs_ra_id rai_bss =
2098 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2099 struct gprs_ra_id rai_sgsn =
2100 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002101 struct gprs_ra_id rai_wrong_mcc_sgsn =
2102 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002103 struct gprs_ra_id rai_unknown =
2104 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2105 uint16_t cell_id = 0x1234;
2106
2107 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002108 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2109 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002110 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002111 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2112 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002113 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002114 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002115
2116 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002117 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2118 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002119 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002120 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2121 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002122 const uint32_t foreign_bss_tlli = 0x8000dead;
2123
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002124
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002125 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002126 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002127 struct gbproxy_peer *peer;
2128 unsigned bss_nu = 0;
2129 unsigned sgsn_nu = 0;
2130
2131 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002132 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2133 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2134 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2135 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2136 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002137
2138 bssgp_nsi = nsi;
2139 gbcfg.nsi = bssgp_nsi;
2140 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2141 gbcfg.core_mcc = 123;
2142 gbcfg.core_mnc = 456;
2143 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2144 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2145 gbcfg.patch_ptmsi = 1;
2146 gbcfg.bss_ptmsi_state = 0;
2147 gbcfg.sgsn_tlli_state = 1;
2148
2149 configure_sgsn_peer(&sgsn_peer);
2150 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2151
2152 printf("=== %s ===\n", __func__);
2153 printf("--- Initialise SGSN ---\n\n");
2154
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002155 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002156
2157 printf("--- Initialise BSS 1 ---\n\n");
2158
2159 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2160 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2161
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002162 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002163 OSMO_ASSERT(peer != NULL);
2164
2165 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2166
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002167 gprs_dump_nsi(nsi);
2168 dump_global(stdout, 0);
2169 dump_peers(stdout, 0, 0, &gbcfg);
2170
2171 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2172
2173 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2174 foreign_bss_tlli, &rai_unknown, cell_id,
2175 GPRS_SAPI_GMM, bss_nu++,
2176 dtap_attach_req, sizeof(dtap_attach_req));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
2180 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2181 random_sgsn_tlli, 0, NULL, 0,
2182 GPRS_SAPI_GMM, sgsn_nu++,
2183 dtap_identity_req, sizeof(dtap_identity_req));
2184
2185 dump_peers(stdout, 0, 0, &gbcfg);
2186
2187 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2188 foreign_bss_tlli, &rai_bss, cell_id,
2189 GPRS_SAPI_GMM, bss_nu++,
2190 dtap_identity_resp, sizeof(dtap_identity_resp));
2191
2192 dump_peers(stdout, 0, 0, &gbcfg);
2193
2194 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2195 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2196 GPRS_SAPI_GMM, sgsn_nu++,
2197 dtap_attach_acc, sizeof(dtap_attach_acc));
2198
2199 dump_peers(stdout, 0, 0, &gbcfg);
2200
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002201 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2202 OSMO_ASSERT(link_info);
2203 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2204 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2205 OSMO_ASSERT(!link_info->tlli.bss_validated);
2206 OSMO_ASSERT(!link_info->tlli.net_validated);
2207 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2208 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2209 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2210 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2211 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2212 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002213
2214 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2215 local_bss_tlli, &rai_bss, cell_id,
2216 GPRS_SAPI_GMM, bss_nu++,
2217 dtap_attach_complete, sizeof(dtap_attach_complete));
2218
2219 dump_peers(stdout, 0, 0, &gbcfg);
2220
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002221 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2222 OSMO_ASSERT(link_info);
2223 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2224 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2225 OSMO_ASSERT(link_info->tlli.bss_validated);
2226 OSMO_ASSERT(!link_info->tlli.net_validated);
2227 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2228 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2229 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2230 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002231
2232 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2233 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2234 GPRS_SAPI_GMM, sgsn_nu++,
2235 dtap_gmm_information, sizeof(dtap_gmm_information));
2236
2237 dump_peers(stdout, 0, 0, &gbcfg);
2238
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002239 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2240 OSMO_ASSERT(link_info);
2241 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2242 OSMO_ASSERT(link_info->tlli.assigned == 0);
2243 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2244 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002245
Jacob Erlbeck82add782014-09-05 18:08:12 +02002246 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2247 local_bss_tlli, &rai_bss, cell_id,
2248 GPRS_SAPI_GMM, bss_nu++,
2249 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2250
2251 dump_peers(stdout, 0, 0, &gbcfg);
2252
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002253 /* Non-DTAP */
2254 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2255 local_bss_tlli, &rai_bss, cell_id,
2256 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2257
2258 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2259 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2260 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2261
2262 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2263 local_bss_tlli, &rai_bss, cell_id,
2264 llc_ui_ll11_dns_query_ul,
2265 sizeof(llc_ui_ll11_dns_query_ul));
2266
2267 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2268 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2269 llc_ui_ll11_dns_resp_dl,
2270 sizeof(llc_ui_ll11_dns_resp_dl));
2271
2272 dump_peers(stdout, 0, 0, &gbcfg);
2273
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002274 /* Repeated RA Update Requests */
2275 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2276 local_bss_tlli, &rai_bss, 0x7080,
2277 GPRS_SAPI_GMM, bss_nu++,
2278 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2279
2280 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2281 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002287 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2288 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2289 OSMO_ASSERT(link_info);
2290 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2291 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2292 OSMO_ASSERT(!link_info->tlli.bss_validated);
2293 OSMO_ASSERT(!link_info->tlli.net_validated);
2294 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2295 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2296 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2297 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2298 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2299 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002300
2301 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2302 local_bss_tlli2, &rai_bss, 0x7080,
2303 GPRS_SAPI_GMM, bss_nu++,
2304 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2305
2306 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2307 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2308 GPRS_SAPI_GMM, sgsn_nu++,
2309 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2310
2311 dump_peers(stdout, 0, 0, &gbcfg);
2312
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002313 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2314 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2315 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2316 OSMO_ASSERT(link_info);
2317 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2318 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2319 OSMO_ASSERT(!link_info->tlli.bss_validated);
2320 OSMO_ASSERT(!link_info->tlli.net_validated);
2321 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2322 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2323 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2324 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2325 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2326 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002327
2328 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2329 local_bss_tlli3, &rai_bss, 0x7080,
2330 GPRS_SAPI_GMM, bss_nu++,
2331 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2332
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002333 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002334
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002335 OSMO_ASSERT(link_info);
2336 OSMO_ASSERT(link_info->tlli.bss_validated);
2337 OSMO_ASSERT(!link_info->tlli.net_validated);
2338 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2339 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002340
2341 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2342 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2343 GPRS_SAPI_GMM, sgsn_nu++,
2344 dtap_gmm_information, sizeof(dtap_gmm_information));
2345
2346 dump_peers(stdout, 0, 0, &gbcfg);
2347
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002348 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2349 OSMO_ASSERT(link_info);
2350 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2351 OSMO_ASSERT(link_info->tlli.assigned == 0);
2352 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2353 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002354
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002355 /* Other messages */
2356 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002357 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002358
2359 dump_peers(stdout, 0, 0, &gbcfg);
2360
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002361 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002362
2363 dump_peers(stdout, 0, 0, &gbcfg);
2364
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002365 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002366
2367 dump_peers(stdout, 0, 0, &gbcfg);
2368
2369 /* Bad case: Invalid BVCI */
2370 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002371 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002372 dump_global(stdout, 0);
2373
2374 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002375 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002376
2377 dump_global(stdout, 0);
2378
2379 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002380 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002381 &rai_wrong_mcc_sgsn);
2382
2383 dump_global(stdout, 0);
2384
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002385 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2386 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2387 unknown_sgsn_tlli, 1, NULL, 0,
2388 GPRS_SAPI_GMM, 2,
2389 dtap_gmm_information, sizeof(dtap_gmm_information));
2390
2391 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2392 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2393 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2394 GPRS_SAPI_GMM, 3,
2395 dtap_gmm_information, sizeof(dtap_gmm_information));
2396
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002397 /* Detach */
2398 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002399 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002400 GPRS_SAPI_GMM, bss_nu++,
2401 dtap_detach_req, sizeof(dtap_detach_req));
2402
2403 dump_peers(stdout, 0, 0, &gbcfg);
2404
2405 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002406 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002407 GPRS_SAPI_GMM, sgsn_nu++,
2408 dtap_detach_acc, sizeof(dtap_detach_acc));
2409
2410 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002411
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002412 dump_global(stdout, 0);
2413
2414 gbprox_reset(&gbcfg);
2415 gprs_ns_destroy(nsi);
2416 nsi = NULL;
2417}
2418
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002419static void test_gbproxy_imsi_acquisition()
2420{
2421 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2422 struct sockaddr_in bss_peer[1] = {{0},};
2423 struct sockaddr_in sgsn_peer= {0};
2424 struct gprs_ra_id rai_bss =
2425 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2426 struct gprs_ra_id rai_sgsn =
2427 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2428 struct gprs_ra_id rai_wrong_mcc_sgsn =
2429 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2430 struct gprs_ra_id rai_unknown =
2431 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2432 uint16_t cell_id = 0x1234;
2433
2434 const uint32_t sgsn_ptmsi = 0xefe2b700;
2435 const uint32_t local_sgsn_tlli = 0xefe2b700;
2436 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002437 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002438
2439 const uint32_t bss_ptmsi = 0xc00f7304;
2440 const uint32_t local_bss_tlli = 0xc00f7304;
2441 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002442 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002443
2444 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002445 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002446 struct gbproxy_peer *peer;
2447 unsigned bss_nu = 0;
2448 unsigned sgsn_nu = 0;
2449
2450 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2451
2452 bssgp_nsi = nsi;
2453 gbcfg.nsi = bssgp_nsi;
2454 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2455 gbcfg.core_mcc = 123;
2456 gbcfg.core_mnc = 456;
2457 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2458 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2459 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002460 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002461 gbcfg.bss_ptmsi_state = 0;
2462 gbcfg.sgsn_tlli_state = 1;
2463
2464 configure_sgsn_peer(&sgsn_peer);
2465 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2466
2467 printf("=== %s ===\n", __func__);
2468 printf("--- Initialise SGSN ---\n\n");
2469
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002470 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002471
2472 printf("--- Initialise BSS 1 ---\n\n");
2473
2474 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2475 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2476
2477 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2478 OSMO_ASSERT(peer != NULL);
2479
2480 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2481
2482 gprs_dump_nsi(nsi);
2483 dump_global(stdout, 0);
2484 dump_peers(stdout, 0, 0, &gbcfg);
2485
2486 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2487
2488 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002489 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002490 GPRS_SAPI_GMM, bss_nu++,
2491 dtap_attach_req, sizeof(dtap_attach_req));
2492
2493 dump_peers(stdout, 0, 0, &gbcfg);
2494
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002495 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2496 foreign_bss_tlli, &rai_bss, cell_id,
2497 GPRS_SAPI_GMM, bss_nu++,
2498 dtap_identity_resp, sizeof(dtap_identity_resp));
2499
2500 dump_peers(stdout, 0, 0, &gbcfg);
2501
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002502 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2503 random_sgsn_tlli, 0, NULL, 0,
2504 GPRS_SAPI_GMM, sgsn_nu++,
2505 dtap_identity_req, sizeof(dtap_identity_req));
2506
2507 dump_peers(stdout, 0, 0, &gbcfg);
2508
2509 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2510 foreign_bss_tlli, &rai_bss, cell_id,
2511 GPRS_SAPI_GMM, bss_nu++,
2512 dtap_identity_resp, sizeof(dtap_identity_resp));
2513
2514 dump_peers(stdout, 0, 0, &gbcfg);
2515
2516 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2517 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2518 GPRS_SAPI_GMM, sgsn_nu++,
2519 dtap_attach_acc, sizeof(dtap_attach_acc));
2520
2521 dump_peers(stdout, 0, 0, &gbcfg);
2522
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002523 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2524 OSMO_ASSERT(link_info);
2525 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2526 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2527 OSMO_ASSERT(!link_info->tlli.bss_validated);
2528 OSMO_ASSERT(!link_info->tlli.net_validated);
2529 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2530 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2531 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2532 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2533 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2534 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002535
2536 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2537 local_bss_tlli, &rai_bss, cell_id,
2538 GPRS_SAPI_GMM, bss_nu++,
2539 dtap_attach_complete, sizeof(dtap_attach_complete));
2540
2541 dump_peers(stdout, 0, 0, &gbcfg);
2542
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002543 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2544 OSMO_ASSERT(link_info);
2545 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2546 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2547 OSMO_ASSERT(link_info->tlli.bss_validated);
2548 OSMO_ASSERT(!link_info->tlli.net_validated);
2549 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2550 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2551 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2552 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002553
2554 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2555 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2556 GPRS_SAPI_GMM, sgsn_nu++,
2557 dtap_gmm_information, sizeof(dtap_gmm_information));
2558
2559 dump_peers(stdout, 0, 0, &gbcfg);
2560
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002561 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2562 OSMO_ASSERT(link_info);
2563 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2564 OSMO_ASSERT(link_info->tlli.assigned == 0);
2565 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2566 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002567
2568 /* Non-DTAP */
2569 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2570 local_bss_tlli, &rai_bss, cell_id,
2571 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2572
2573 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2574 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2575 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2576
2577 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2578 local_bss_tlli, &rai_bss, cell_id,
2579 llc_ui_ll11_dns_query_ul,
2580 sizeof(llc_ui_ll11_dns_query_ul));
2581
2582 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2583 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2584 llc_ui_ll11_dns_resp_dl,
2585 sizeof(llc_ui_ll11_dns_resp_dl));
2586
2587 dump_peers(stdout, 0, 0, &gbcfg);
2588
2589 /* Other messages */
2590 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2591 local_bss_tlli, 1, 12);
2592
2593 dump_peers(stdout, 0, 0, &gbcfg);
2594
2595 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2596 local_sgsn_tlli, 1, 12);
2597
2598 dump_peers(stdout, 0, 0, &gbcfg);
2599
2600 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2601
2602 dump_peers(stdout, 0, 0, &gbcfg);
2603
2604 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2605
2606 dump_peers(stdout, 0, 0, &gbcfg);
2607
2608 /* Bad case: Invalid BVCI */
2609 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2610 local_bss_tlli, 1, 12);
2611 dump_global(stdout, 0);
2612
2613 /* Bad case: Invalid RAI */
2614 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2615
2616 dump_global(stdout, 0);
2617
2618 /* Bad case: Invalid MCC (LAC ok) */
2619 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2620 &rai_wrong_mcc_sgsn);
2621
2622 dump_global(stdout, 0);
2623
2624 /* Detach */
2625 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2626 local_bss_tlli, &rai_bss, cell_id,
2627 GPRS_SAPI_GMM, bss_nu++,
2628 dtap_detach_req, sizeof(dtap_detach_req));
2629
2630 dump_peers(stdout, 0, 0, &gbcfg);
2631
2632 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2633 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2634 GPRS_SAPI_GMM, sgsn_nu++,
2635 dtap_detach_acc, sizeof(dtap_detach_acc));
2636
2637 dump_peers(stdout, 0, 0, &gbcfg);
2638
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002639 /* RA Update request */
2640
2641 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2642 foreign_bss_tlli, &rai_unknown, 0x7080,
2643 GPRS_SAPI_GMM, bss_nu++,
2644 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2645
2646 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2647 foreign_bss_tlli, &rai_bss, cell_id,
2648 GPRS_SAPI_GMM, bss_nu++,
2649 dtap_identity_resp, sizeof(dtap_identity_resp));
2650
2651 dump_peers(stdout, 0, 0, &gbcfg);
2652
2653 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2654 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2655 GPRS_SAPI_GMM, sgsn_nu++,
2656 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2657
2658 dump_peers(stdout, 0, 0, &gbcfg);
2659
2660 /* Detach */
2661
2662 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2663 local_bss_tlli, &rai_bss, cell_id,
2664 GPRS_SAPI_GMM, bss_nu++,
2665 dtap_detach_req, sizeof(dtap_detach_req));
2666
2667 dump_peers(stdout, 0, 0, &gbcfg);
2668
2669 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2670 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2671 GPRS_SAPI_GMM, sgsn_nu++,
2672 dtap_detach_acc, sizeof(dtap_detach_acc));
2673
2674 dump_peers(stdout, 0, 0, &gbcfg);
2675
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002676 /* Special case: Repeated Attach Requests */
2677
2678 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2679 foreign_bss_tlli, &rai_unknown, cell_id,
2680 GPRS_SAPI_GMM, bss_nu++,
2681 dtap_attach_req, sizeof(dtap_attach_req));
2682
2683 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2684 foreign_bss_tlli, &rai_unknown, cell_id,
2685 GPRS_SAPI_GMM, bss_nu++,
2686 dtap_attach_req, sizeof(dtap_attach_req));
2687
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002688 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2689 foreign_bss_tlli, &rai_bss, cell_id,
2690 GPRS_SAPI_GMM, bss_nu++,
2691 dtap_detach_req, sizeof(dtap_detach_req));
2692
2693 dump_peers(stdout, 0, 0, &gbcfg);
2694
2695 /* Special case: Detach from an unknown TLLI */
2696
2697 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2698 other_bss_tlli, &rai_bss, cell_id,
2699 GPRS_SAPI_GMM, bss_nu++,
2700 dtap_detach_req, sizeof(dtap_detach_req));
2701
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002702 dump_peers(stdout, 0, 0, &gbcfg);
2703
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002704 /* Special case: Repeated RA Update Requests */
2705
2706 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2707 foreign_bss_tlli, &rai_unknown, 0x7080,
2708 GPRS_SAPI_GMM, bss_nu++,
2709 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2710
2711 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2712 foreign_bss_tlli, &rai_unknown, 0x7080,
2713 GPRS_SAPI_GMM, bss_nu++,
2714 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2715
2716 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2717 foreign_bss_tlli, &rai_bss, cell_id,
2718 GPRS_SAPI_GMM, bss_nu++,
2719 dtap_detach_req, sizeof(dtap_detach_req));
2720
2721 dump_peers(stdout, 0, 0, &gbcfg);
2722
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002723 dump_global(stdout, 0);
2724
2725 gbprox_reset(&gbcfg);
2726 gprs_ns_destroy(nsi);
2727 nsi = NULL;
2728}
2729
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002730static void test_gbproxy_secondary_sgsn()
2731{
2732 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2733 struct sockaddr_in bss_peer[1] = {{0},};
2734 struct sockaddr_in sgsn_peer[2]= {{0},};
2735 struct gprs_ra_id rai_bss =
2736 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2737 struct gprs_ra_id rai_sgsn =
2738 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2739 struct gprs_ra_id rai_unknown =
2740 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2741 uint16_t cell_id = 0x1234;
2742
2743 const uint32_t sgsn_ptmsi = 0xefe2b700;
2744 const uint32_t local_sgsn_tlli = 0xefe2b700;
2745 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2746
2747 const uint32_t bss_ptmsi = 0xc00f7304;
2748 const uint32_t local_bss_tlli = 0xc00f7304;
2749 const uint32_t foreign_bss_tlli = 0x8000dead;
2750
2751 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2752 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2753 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2754 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2755 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2756 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2757
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002758 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002759 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002760 const uint32_t local_bss_tlli3 = 0xead4775a;
2761 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2762
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002763 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2764 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002765 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002766 struct gbproxy_link_info *link_info;
2767 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002768 struct gbproxy_peer *peer;
2769 unsigned bss_nu = 0;
2770 unsigned sgsn_nu = 0;
2771
2772 const char *err_msg = NULL;
2773 const char *filter_re = "999999";
2774
2775 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2776 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2777
2778 bssgp_nsi = nsi;
2779 gbcfg.nsi = bssgp_nsi;
2780 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2781 gbcfg.core_mcc = 123;
2782 gbcfg.core_mnc = 456;
2783 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2784 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2785 gbcfg.patch_ptmsi = 1;
2786 gbcfg.acquire_imsi = 1;
2787 gbcfg.bss_ptmsi_state = 0;
2788 gbcfg.sgsn_tlli_state = 1;
2789 gbcfg.route_to_sgsn2 = 1;
2790 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2791
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02002792 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02002793 filter_re, &err_msg) != 0) {
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002794 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2795 err_msg);
2796 OSMO_ASSERT(err_msg == NULL);
2797 }
2798
2799 configure_sgsn_peer(&sgsn_peer[0]);
2800 configure_sgsn2_peer(&sgsn_peer[1]);
2801 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2802
2803 printf("=== %s ===\n", __func__);
2804 printf("--- Initialise SGSN 1 ---\n\n");
2805
2806 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2807
2808 printf("--- Initialise SGSN 2 ---\n\n");
2809
2810 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2811
2812 printf("--- Initialise BSS 1 ---\n\n");
2813
2814 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2815 setup_bssgp(nsi, &bss_peer[0], 0x0);
2816 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2817 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2818 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2819 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2820
2821 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2822 OSMO_ASSERT(peer != NULL);
2823
2824 gprs_dump_nsi(nsi);
2825 dump_global(stdout, 0);
2826 dump_peers(stdout, 0, 0, &gbcfg);
2827
2828 printf("--- Flow control ---\n\n");
2829
2830 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2831 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2832 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2833
2834 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2835
2836 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2837 foreign_bss_tlli, &rai_unknown, cell_id,
2838 GPRS_SAPI_GMM, bss_nu++,
2839 dtap_attach_req, sizeof(dtap_attach_req));
2840
2841 dump_peers(stdout, 0, 0, &gbcfg);
2842
2843 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2844 foreign_bss_tlli, &rai_bss, cell_id,
2845 GPRS_SAPI_GMM, bss_nu++,
2846 dtap_identity_resp, sizeof(dtap_identity_resp));
2847
2848 dump_peers(stdout, 0, 0, &gbcfg);
2849
2850 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2851 random_sgsn_tlli, 0, NULL, 0,
2852 GPRS_SAPI_GMM, sgsn_nu++,
2853 dtap_identity_req, sizeof(dtap_identity_req));
2854
2855 dump_peers(stdout, 0, 0, &gbcfg);
2856
2857 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2858 foreign_bss_tlli, &rai_bss, cell_id,
2859 GPRS_SAPI_GMM, bss_nu++,
2860 dtap_identity_resp, sizeof(dtap_identity_resp));
2861
2862 dump_peers(stdout, 0, 0, &gbcfg);
2863
2864 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2865 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2866 GPRS_SAPI_GMM, sgsn_nu++,
2867 dtap_attach_acc, sizeof(dtap_attach_acc));
2868
2869 dump_peers(stdout, 0, 0, &gbcfg);
2870
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002871 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2872 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2873 OSMO_ASSERT(link_info);
2874 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2875 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2876 OSMO_ASSERT(!link_info->tlli.bss_validated);
2877 OSMO_ASSERT(!link_info->tlli.net_validated);
2878 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2879 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2880 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2881 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2882 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2883 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002884
2885 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2886 local_bss_tlli, &rai_bss, cell_id,
2887 GPRS_SAPI_GMM, bss_nu++,
2888 dtap_attach_complete, sizeof(dtap_attach_complete));
2889
2890 dump_peers(stdout, 0, 0, &gbcfg);
2891
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002892 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2893 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2894 OSMO_ASSERT(link_info);
2895 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2896 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2897 OSMO_ASSERT(link_info->tlli.bss_validated);
2898 OSMO_ASSERT(!link_info->tlli.net_validated);
2899 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2900 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2901 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2902 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002903
2904 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2905 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2906 GPRS_SAPI_GMM, sgsn_nu++,
2907 dtap_gmm_information, sizeof(dtap_gmm_information));
2908
2909 dump_peers(stdout, 0, 0, &gbcfg);
2910
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002911 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2912 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2913 OSMO_ASSERT(link_info);
2914 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2915 OSMO_ASSERT(link_info->tlli.assigned == 0);
2916 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2917 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002918
2919 /* Non-DTAP */
2920 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2921 local_bss_tlli, &rai_bss, cell_id,
2922 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2923
2924 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2925 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2926 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2927
2928 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2929 local_bss_tlli, &rai_bss, cell_id,
2930 llc_ui_ll11_dns_query_ul,
2931 sizeof(llc_ui_ll11_dns_query_ul));
2932
2933 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2934 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2935 llc_ui_ll11_dns_resp_dl,
2936 sizeof(llc_ui_ll11_dns_resp_dl));
2937
2938 dump_peers(stdout, 0, 0, &gbcfg);
2939
2940 /* Other messages */
2941 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2942 local_bss_tlli, 1, 12);
2943
2944 dump_peers(stdout, 0, 0, &gbcfg);
2945
2946 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2947 local_sgsn_tlli, 1, 12);
2948
2949 dump_peers(stdout, 0, 0, &gbcfg);
2950
2951 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2952
2953 dump_peers(stdout, 0, 0, &gbcfg);
2954
2955 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2956
2957 dump_peers(stdout, 0, 0, &gbcfg);
2958
2959 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2960
2961 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2962 foreign_bss_tlli2, &rai_unknown, cell_id,
2963 GPRS_SAPI_GMM, bss_nu++,
2964 dtap_attach_req, sizeof(dtap_attach_req));
2965
2966 dump_peers(stdout, 0, 0, &gbcfg);
2967
2968 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2969 foreign_bss_tlli2, &rai_bss, cell_id,
2970 GPRS_SAPI_GMM, bss_nu++,
2971 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2972
2973 dump_peers(stdout, 0, 0, &gbcfg);
2974
2975 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2976 random_sgsn_tlli2, 0, NULL, 0,
2977 GPRS_SAPI_GMM, sgsn_nu++,
2978 dtap_identity_req, sizeof(dtap_identity_req));
2979
2980 dump_peers(stdout, 0, 0, &gbcfg);
2981
2982 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2983 foreign_bss_tlli2, &rai_bss, cell_id,
2984 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002985 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002986
2987 dump_peers(stdout, 0, 0, &gbcfg);
2988
2989 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2990 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2991 GPRS_SAPI_GMM, sgsn_nu++,
2992 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2993
2994 dump_peers(stdout, 0, 0, &gbcfg);
2995
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002996 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2997 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2998 OSMO_ASSERT(link_info);
2999 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3000 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3001 OSMO_ASSERT(!link_info->tlli.bss_validated);
3002 OSMO_ASSERT(!link_info->tlli.net_validated);
3003 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3004 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3005 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3006 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3007 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3008 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003009
3010 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3011 local_bss_tlli2, &rai_bss, cell_id,
3012 GPRS_SAPI_GMM, bss_nu++,
3013 dtap_attach_complete, sizeof(dtap_attach_complete));
3014
3015 dump_peers(stdout, 0, 0, &gbcfg);
3016
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003017 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3018 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3019 OSMO_ASSERT(link_info);
3020 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3021 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3022 OSMO_ASSERT(link_info->tlli.bss_validated);
3023 OSMO_ASSERT(!link_info->tlli.net_validated);
3024 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3025 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3026 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3027 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003028
3029 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3030 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3031 GPRS_SAPI_GMM, sgsn_nu++,
3032 dtap_gmm_information, sizeof(dtap_gmm_information));
3033
3034 dump_peers(stdout, 0, 0, &gbcfg);
3035
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003036 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3037 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3038 OSMO_ASSERT(link_info);
3039 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3040 OSMO_ASSERT(link_info->tlli.assigned == 0);
3041 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3042 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003043
3044 /* Non-DTAP */
3045 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3046 local_bss_tlli2, &rai_bss, cell_id,
3047 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3048
3049 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3050 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3051 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3052
3053 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3054 local_bss_tlli2, &rai_bss, cell_id,
3055 llc_ui_ll11_dns_query_ul,
3056 sizeof(llc_ui_ll11_dns_query_ul));
3057
3058 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3059 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3060 llc_ui_ll11_dns_resp_dl,
3061 sizeof(llc_ui_ll11_dns_resp_dl));
3062
3063 dump_peers(stdout, 0, 0, &gbcfg);
3064
3065 /* Other messages */
3066 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3067 local_bss_tlli2, 1, 12);
3068
3069 dump_peers(stdout, 0, 0, &gbcfg);
3070
3071 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3072 local_sgsn_tlli2, 1, 12);
3073
3074 dump_peers(stdout, 0, 0, &gbcfg);
3075
3076 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
3080 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3081
3082 dump_peers(stdout, 0, 0, &gbcfg);
3083
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003084 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3085
3086 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3087 foreign_bss_tlli3, &rai_unknown, cell_id,
3088 GPRS_SAPI_GMM, bss_nu++,
3089 dtap_attach_req, sizeof(dtap_attach_req));
3090
3091 dump_peers(stdout, 0, 0, &gbcfg);
3092
3093 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3094 foreign_bss_tlli3, &rai_bss, cell_id,
3095 GPRS_SAPI_GMM, bss_nu++,
3096 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3097
3098 dump_peers(stdout, 0, 0, &gbcfg);
3099
3100 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3101 random_sgsn_tlli3, 0, NULL, 0,
3102 GPRS_SAPI_GMM, sgsn_nu++,
3103 dtap_identity_req, sizeof(dtap_identity_req));
3104
3105 dump_peers(stdout, 0, 0, &gbcfg);
3106
3107 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3108 foreign_bss_tlli3, &rai_bss, cell_id,
3109 GPRS_SAPI_GMM, bss_nu++,
3110 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3111
3112 dump_peers(stdout, 0, 0, &gbcfg);
3113
3114 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3115 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3116 GPRS_SAPI_GMM, sgsn_nu++,
3117 dtap_attach_acc, sizeof(dtap_attach_acc));
3118
3119 dump_peers(stdout, 0, 0, &gbcfg);
3120
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003121 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3122 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3123 OSMO_ASSERT(link_info);
3124 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3125 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3126 OSMO_ASSERT(!link_info->tlli.bss_validated);
3127 OSMO_ASSERT(!link_info->tlli.net_validated);
3128 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3129 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3130 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3131 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3132 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3133 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003134
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003135 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3136 local_bss_tlli3, &rai_bss, cell_id,
3137 GPRS_SAPI_GMM, bss_nu++,
3138 dtap_attach_complete, sizeof(dtap_attach_complete));
3139
3140 dump_peers(stdout, 0, 0, &gbcfg);
3141
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003142 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003143 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003144 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3145 OSMO_ASSERT(link_info);
3146 OSMO_ASSERT(link_info != other_info);
3147 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3148 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3149 OSMO_ASSERT(link_info->tlli.bss_validated);
3150 OSMO_ASSERT(!link_info->tlli.net_validated);
3151 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3152 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3153 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3154 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003155
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003156 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3157 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3158 GPRS_SAPI_GMM, sgsn_nu++,
3159 dtap_gmm_information, sizeof(dtap_gmm_information));
3160
3161 dump_peers(stdout, 0, 0, &gbcfg);
3162
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003163 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003164 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003165 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3166 OSMO_ASSERT(link_info);
3167 OSMO_ASSERT(link_info != other_info);
3168 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3169 OSMO_ASSERT(link_info->tlli.assigned == 0);
3170 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3171 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003172
3173
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003174 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3175
3176 /* Detach */
3177 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3178 local_bss_tlli, &rai_bss, cell_id,
3179 GPRS_SAPI_GMM, bss_nu++,
3180 dtap_detach_req, sizeof(dtap_detach_req));
3181
3182 dump_peers(stdout, 0, 0, &gbcfg);
3183
3184 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3185 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3186 GPRS_SAPI_GMM, sgsn_nu++,
3187 dtap_detach_acc, sizeof(dtap_detach_acc));
3188
3189 dump_peers(stdout, 0, 0, &gbcfg);
3190
3191 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3192
3193 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3194 local_bss_tlli2, &rai_bss, cell_id,
3195 GPRS_SAPI_GMM, bss_nu++,
3196 dtap_detach_req, sizeof(dtap_detach_req));
3197
3198 dump_peers(stdout, 0, 0, &gbcfg);
3199
3200 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3201 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3202 GPRS_SAPI_GMM, sgsn_nu++,
3203 dtap_detach_acc, sizeof(dtap_detach_acc));
3204
3205 dump_peers(stdout, 0, 0, &gbcfg);
3206
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003207 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3208
3209 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3210 local_bss_tlli3, &rai_bss, cell_id,
3211 GPRS_SAPI_GMM, bss_nu++,
3212 dtap_detach_req, sizeof(dtap_detach_req));
3213
3214 dump_peers(stdout, 0, 0, &gbcfg);
3215
3216 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3217 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3218 GPRS_SAPI_GMM, sgsn_nu++,
3219 dtap_detach_acc, sizeof(dtap_detach_acc));
3220
3221 dump_peers(stdout, 0, 0, &gbcfg);
3222
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003223 dump_global(stdout, 0);
3224
Jacob Erlbeckb36032c2014-09-25 13:21:48 +02003225 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003226 gbprox_reset(&gbcfg);
3227 gprs_ns_destroy(nsi);
3228 nsi = NULL;
3229}
3230
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003231static void test_gbproxy_keep_info()
3232{
3233 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3234 struct sockaddr_in bss_peer[1] = {{0},};
3235 struct sockaddr_in sgsn_peer= {0};
3236 struct gprs_ra_id rai_bss =
3237 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3238 uint16_t cell_id = 0x1234;
3239
3240 const uint32_t ptmsi = 0xefe2b700;
3241 const uint32_t local_tlli = 0xefe2b700;
3242 const uint32_t foreign_tlli = 0xafe2b700;
3243
3244 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003245 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003246 struct gbproxy_peer *peer;
3247 unsigned bss_nu = 0;
3248 unsigned sgsn_nu = 0;
3249
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003250 LLIST_HEAD(rcv_list);
3251
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003252 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3253
3254 bssgp_nsi = nsi;
3255 gbcfg.nsi = bssgp_nsi;
3256 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3257 gbcfg.patch_ptmsi = 0;
3258 gbcfg.acquire_imsi = 1;
3259 gbcfg.bss_ptmsi_state = 0;
3260 gbcfg.sgsn_tlli_state = 1;
3261 gbcfg.core_mcc = 0;
3262 gbcfg.core_mnc = 0;
3263 gbcfg.core_apn = NULL;
3264 gbcfg.core_apn_size = 0;
3265 gbcfg.route_to_sgsn2 = 0;
3266 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003267 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003268
3269 configure_sgsn_peer(&sgsn_peer);
3270 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3271
3272 printf("=== %s ===\n", __func__);
3273 printf("--- Initialise SGSN ---\n\n");
3274
3275 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3276
3277 printf("--- Initialise BSS 1 ---\n\n");
3278
3279 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3280 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3281
3282 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3283 OSMO_ASSERT(peer != NULL);
3284
3285 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3286
3287 gprs_dump_nsi(nsi);
3288 dump_global(stdout, 0);
3289 dump_peers(stdout, 0, 0, &gbcfg);
3290
3291 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3292
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003293 received_messages = &rcv_list;
3294
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003295 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3296 foreign_tlli, &rai_bss, cell_id,
3297 GPRS_SAPI_GMM, bss_nu++,
3298 dtap_attach_req, sizeof(dtap_attach_req));
3299
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003300 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3301
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003302 dump_peers(stdout, 0, 0, &gbcfg);
3303
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003304 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3305 OSMO_ASSERT(link_info);
3306 OSMO_ASSERT(link_info->imsi_len == 0);
3307 OSMO_ASSERT(!link_info->is_deregistered);
3308 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003309
3310 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3311 foreign_tlli, &rai_bss, cell_id,
3312 GPRS_SAPI_GMM, bss_nu++,
3313 dtap_identity_resp, sizeof(dtap_identity_resp));
3314
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003315 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3316
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003317 dump_peers(stdout, 0, 0, &gbcfg);
3318
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003319 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3320 OSMO_ASSERT(link_info);
3321 OSMO_ASSERT(link_info->imsi_len > 0);
3322 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003323
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003324 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3325 foreign_tlli, 0, NULL, 0,
3326 GPRS_SAPI_GMM, sgsn_nu++,
3327 dtap_identity_req, sizeof(dtap_identity_req));
3328
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003329 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3330
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003331 dump_peers(stdout, 0, 0, &gbcfg);
3332
3333 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3334 foreign_tlli, &rai_bss, cell_id,
3335 GPRS_SAPI_GMM, bss_nu++,
3336 dtap_identity_resp, sizeof(dtap_identity_resp));
3337
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003338 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
3339
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003340 dump_peers(stdout, 0, 0, &gbcfg);
3341
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003342 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3343 OSMO_ASSERT(link_info);
3344 OSMO_ASSERT(link_info->imsi_len > 0);
3345 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003346
3347 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3348 foreign_tlli, 1, imsi, sizeof(imsi),
3349 GPRS_SAPI_GMM, sgsn_nu++,
3350 dtap_attach_acc, sizeof(dtap_attach_acc));
3351
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003352 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3353
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003354 dump_peers(stdout, 0, 0, &gbcfg);
3355
3356 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3357 local_tlli, &rai_bss, cell_id,
3358 GPRS_SAPI_GMM, bss_nu++,
3359 dtap_attach_complete, sizeof(dtap_attach_complete));
3360
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003361 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3362
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003363 dump_peers(stdout, 0, 0, &gbcfg);
3364
3365 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3366 local_tlli, 1, imsi, sizeof(imsi),
3367 GPRS_SAPI_GMM, sgsn_nu++,
3368 dtap_gmm_information, sizeof(dtap_gmm_information));
3369
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003370 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
3371
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003372 dump_peers(stdout, 0, 0, &gbcfg);
3373
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003374 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3375 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003376
3377 /* Detach (MO) */
3378 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3379 local_tlli, &rai_bss, cell_id,
3380 GPRS_SAPI_GMM, bss_nu++,
3381 dtap_detach_req, sizeof(dtap_detach_req));
3382
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003383 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3384
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003385 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3386 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003387
3388 dump_peers(stdout, 0, 0, &gbcfg);
3389
3390 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3391 local_tlli, 1, imsi, sizeof(imsi),
3392 GPRS_SAPI_GMM, sgsn_nu++,
3393 dtap_detach_acc, sizeof(dtap_detach_acc));
3394
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003395 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3396
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003397 dump_peers(stdout, 0, 0, &gbcfg);
3398
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003399 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3400 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3401 OSMO_ASSERT(link_info);
3402 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003403
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003404 OSMO_ASSERT(!expect_msg());
3405
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003406 /* Re-Attach */
3407 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3408 foreign_tlli, &rai_bss, cell_id,
3409 GPRS_SAPI_GMM, bss_nu++,
3410 dtap_attach_req3, sizeof(dtap_attach_req3));
3411
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003412 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3413
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003414 dump_peers(stdout, 0, 0, &gbcfg);
3415
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003416 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3417 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3418 OSMO_ASSERT(link_info);
3419 OSMO_ASSERT(link_info == link_info2);
3420 OSMO_ASSERT(link_info->imsi_len != 0);
3421 OSMO_ASSERT(!link_info->is_deregistered);
3422 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003423
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003424 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3425 foreign_tlli, 1, imsi, sizeof(imsi),
3426 GPRS_SAPI_GMM, sgsn_nu++,
3427 dtap_attach_acc, sizeof(dtap_attach_acc));
3428
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003429 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3430
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003431 dump_peers(stdout, 0, 0, &gbcfg);
3432
3433 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3434 local_tlli, &rai_bss, cell_id,
3435 GPRS_SAPI_GMM, bss_nu++,
3436 dtap_attach_complete, sizeof(dtap_attach_complete));
3437
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003438 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3439
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003440 dump_peers(stdout, 0, 0, &gbcfg);
3441
3442 /* Detach (MT) */
3443 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3444 local_tlli, 1, imsi, sizeof(imsi),
3445 GPRS_SAPI_GMM, sgsn_nu++,
3446 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3447
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003448 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3449
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003450 dump_peers(stdout, 0, 0, &gbcfg);
3451
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003452 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3453 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003454
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003455 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003456 local_tlli, &rai_bss, cell_id,
3457 GPRS_SAPI_GMM, bss_nu++,
3458 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3459
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003460 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3461 OSMO_ASSERT(!expect_msg());
3462
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003463 dump_peers(stdout, 0, 0, &gbcfg);
3464
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003465 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3466 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3467 OSMO_ASSERT(link_info);
3468 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003469
3470 /* Re-Attach */
3471 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3472 foreign_tlli, &rai_bss, cell_id,
3473 GPRS_SAPI_GMM, bss_nu++,
3474 dtap_attach_req3, sizeof(dtap_attach_req3));
3475
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003476 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3477
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003478 dump_peers(stdout, 0, 0, &gbcfg);
3479
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003480 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3481 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3482 OSMO_ASSERT(link_info);
3483 OSMO_ASSERT(link_info == link_info2);
3484 OSMO_ASSERT(link_info->imsi_len != 0);
3485 OSMO_ASSERT(!link_info->is_deregistered);
3486 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003487
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003488 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3489 foreign_tlli, 1, imsi, sizeof(imsi),
3490 GPRS_SAPI_GMM, sgsn_nu++,
3491 dtap_attach_acc, sizeof(dtap_attach_acc));
3492
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003493 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3494
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003495 dump_peers(stdout, 0, 0, &gbcfg);
3496
3497 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3498 local_tlli, &rai_bss, cell_id,
3499 GPRS_SAPI_GMM, bss_nu++,
3500 dtap_attach_complete, sizeof(dtap_attach_complete));
3501
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003502 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3503
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003504 dump_peers(stdout, 0, 0, &gbcfg);
3505
3506 /* Detach (MT) */
3507 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3508 local_tlli, 1, imsi, sizeof(imsi),
3509 GPRS_SAPI_GMM, sgsn_nu++,
3510 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3511
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003512 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3513
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003514 dump_peers(stdout, 0, 0, &gbcfg);
3515
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003516 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3517 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003518
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003519 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003520 local_tlli, &rai_bss, cell_id,
3521 GPRS_SAPI_GMM, bss_nu++,
3522 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3523
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003524 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3525 OSMO_ASSERT(!expect_msg());
3526
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003527 dump_peers(stdout, 0, 0, &gbcfg);
3528
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003529 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3530 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3531 OSMO_ASSERT(link_info);
3532 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003533
3534 /* Re-Attach */
3535 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3536 foreign_tlli, &rai_bss, cell_id,
3537 GPRS_SAPI_GMM, bss_nu++,
3538 dtap_attach_req3, sizeof(dtap_attach_req3));
3539
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003540 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3541
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003542 dump_peers(stdout, 0, 0, &gbcfg);
3543
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003544 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3545 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3546 OSMO_ASSERT(link_info);
3547 OSMO_ASSERT(link_info == link_info2);
3548 OSMO_ASSERT(link_info->imsi_len != 0);
3549 OSMO_ASSERT(!link_info->is_deregistered);
3550 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003551
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003552 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3553 foreign_tlli, 1, imsi, sizeof(imsi),
3554 GPRS_SAPI_GMM, sgsn_nu++,
3555 dtap_attach_acc, sizeof(dtap_attach_acc));
3556
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003557 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3558
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003559 dump_peers(stdout, 0, 0, &gbcfg);
3560
3561 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3562 local_tlli, &rai_bss, cell_id,
3563 GPRS_SAPI_GMM, bss_nu++,
3564 dtap_attach_complete, sizeof(dtap_attach_complete));
3565
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003566 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3567
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003568 dump_peers(stdout, 0, 0, &gbcfg);
3569
3570 /* RA update procedure (reject -> Detach) */
3571 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3572 local_tlli, &rai_bss, 0x7080,
3573 GPRS_SAPI_GMM, bss_nu++,
3574 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3575
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003576 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
3577
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003578 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3579 local_tlli, 1, imsi, sizeof(imsi),
3580 GPRS_SAPI_GMM, sgsn_nu++,
3581 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3582
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003583 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ));
3584 OSMO_ASSERT(!expect_msg());
3585
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003586 dump_peers(stdout, 0, 0, &gbcfg);
3587
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003588 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3589 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3590 OSMO_ASSERT(link_info);
3591 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003592
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003593 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3594 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3595 foreign_tlli, &rai_bss, cell_id,
3596 GPRS_SAPI_GMM, bss_nu++,
3597 dtap_attach_req, sizeof(dtap_attach_req));
3598
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003599 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3600
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003601 dump_peers(stdout, 0, 0, &gbcfg);
3602
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003603 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3604 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3605 OSMO_ASSERT(link_info);
3606 OSMO_ASSERT(link_info != link_info2);
3607 OSMO_ASSERT(link_info->imsi_len == 0);
3608 OSMO_ASSERT(!link_info->is_deregistered);
3609 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003610
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003611 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3612 foreign_tlli, &rai_bss, cell_id,
3613 GPRS_SAPI_GMM, bss_nu++,
3614 dtap_identity_resp, sizeof(dtap_identity_resp));
3615
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003616 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3617
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003618 dump_peers(stdout, 0, 0, &gbcfg);
3619
3620 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3621 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3622 OSMO_ASSERT(link_info);
3623 OSMO_ASSERT(link_info == link_info2);
3624 OSMO_ASSERT(link_info->imsi_len != 0);
3625 OSMO_ASSERT(!link_info->is_deregistered);
3626 OSMO_ASSERT(!link_info->imsi_acq_pending);
3627
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003628 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3629 foreign_tlli, 1, imsi, sizeof(imsi),
3630 GPRS_SAPI_GMM, sgsn_nu++,
3631 dtap_attach_acc, sizeof(dtap_attach_acc));
3632
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003633 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3634
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003635 dump_peers(stdout, 0, 0, &gbcfg);
3636
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003637 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3638 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3639 OSMO_ASSERT(link_info);
3640 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003641 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003642
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003643 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3644 local_tlli, &rai_bss, cell_id,
3645 GPRS_SAPI_GMM, bss_nu++,
3646 dtap_attach_complete, sizeof(dtap_attach_complete));
3647
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003648 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3649
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003650 dump_peers(stdout, 0, 0, &gbcfg);
3651
3652 /* Detach (MT) */
3653 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3654 local_tlli, 1, imsi, sizeof(imsi),
3655 GPRS_SAPI_GMM, sgsn_nu++,
3656 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3657
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003658 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3659
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003660 dump_peers(stdout, 0, 0, &gbcfg);
3661
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003662 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3663 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003664
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003665 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003666 local_tlli, &rai_bss, cell_id,
3667 GPRS_SAPI_GMM, bss_nu++,
3668 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3669
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003670 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3671
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003672 dump_peers(stdout, 0, 0, &gbcfg);
3673
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003674 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3675 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3676 OSMO_ASSERT(link_info);
3677 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003678
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003679 OSMO_ASSERT(!expect_msg());
3680
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003681 /* Attach rejected */
3682
3683 gbproxy_delete_link_infos(peer);
3684
3685 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3686 foreign_tlli, &rai_bss, cell_id,
3687 GPRS_SAPI_GMM, bss_nu++,
3688 dtap_attach_req, sizeof(dtap_attach_req));
3689
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003690 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3691
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003692 dump_peers(stdout, 0, 0, &gbcfg);
3693
3694 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3695 OSMO_ASSERT(link_info);
3696 OSMO_ASSERT(link_info->imsi_len == 0);
3697 OSMO_ASSERT(!link_info->is_deregistered);
3698 OSMO_ASSERT(link_info->imsi_acq_pending);
3699
3700 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3701 foreign_tlli, &rai_bss, cell_id,
3702 GPRS_SAPI_GMM, bss_nu++,
3703 dtap_identity_resp, sizeof(dtap_identity_resp));
3704
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003705 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3706
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003707 dump_peers(stdout, 0, 0, &gbcfg);
3708
3709 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3710 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3711 OSMO_ASSERT(link_info);
3712 OSMO_ASSERT(link_info == link_info2);
3713 OSMO_ASSERT(link_info->imsi_len != 0);
3714 OSMO_ASSERT(!link_info->is_deregistered);
3715 OSMO_ASSERT(!link_info->imsi_acq_pending);
3716
3717 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3718 foreign_tlli, 1, imsi, sizeof(imsi),
3719 GPRS_SAPI_GMM, sgsn_nu++,
3720 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3721
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003722 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ));
3723
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003724 dump_peers(stdout, 0, 0, &gbcfg);
3725
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003726 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3727
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003728 OSMO_ASSERT(!expect_msg());
3729
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003730 /* Attach (incomplete) and Detach (MO) */
3731
3732 gbproxy_delete_link_infos(peer);
3733
3734 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3735 foreign_tlli, &rai_bss, cell_id,
3736 GPRS_SAPI_GMM, bss_nu++,
3737 dtap_attach_req, sizeof(dtap_attach_req));
3738
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003739 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3740
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003741 dump_peers(stdout, 0, 0, &gbcfg);
3742
3743 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3744 OSMO_ASSERT(link_info);
3745 OSMO_ASSERT(link_info->imsi_len == 0);
3746 OSMO_ASSERT(!link_info->is_deregistered);
3747 OSMO_ASSERT(link_info->imsi_acq_pending);
3748
3749 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3750 foreign_tlli, &rai_bss, cell_id,
3751 GPRS_SAPI_GMM, bss_nu++,
3752 dtap_detach_req, sizeof(dtap_detach_req));
3753
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003754 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3755
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003756 dump_peers(stdout, 0, 0, &gbcfg);
3757
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003758 OSMO_ASSERT(!expect_msg());
3759
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003760 /* Attach (incomplete) and Detach (MT) */
3761
3762 gbproxy_delete_link_infos(peer);
3763
3764 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3765 foreign_tlli, &rai_bss, cell_id,
3766 GPRS_SAPI_GMM, bss_nu++,
3767 dtap_attach_req, sizeof(dtap_attach_req));
3768
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003769 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3770
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003771 dump_peers(stdout, 0, 0, &gbcfg);
3772
3773 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3774 OSMO_ASSERT(link_info);
3775 OSMO_ASSERT(link_info->imsi_len == 0);
3776 OSMO_ASSERT(!link_info->is_deregistered);
3777 OSMO_ASSERT(link_info->imsi_acq_pending);
3778
3779 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3780 foreign_tlli, 1, imsi, sizeof(imsi),
3781 GPRS_SAPI_GMM, sgsn_nu++,
3782 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3783
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003784 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3785
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003786 dump_peers(stdout, 0, 0, &gbcfg);
3787
3788 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3789 OSMO_ASSERT(link_info);
3790
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003791 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003792 foreign_tlli, &rai_bss, cell_id,
3793 GPRS_SAPI_GMM, bss_nu++,
3794 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3795
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003796 /* TODO: The stored messaged should be cleaned when receiving a Detach
3797 * Ack. Remove the first OSMO_ASSERT when this is fixed. */
3798 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3799 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3800
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003801 dump_peers(stdout, 0, 0, &gbcfg);
3802
3803 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3804 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3805 OSMO_ASSERT(link_info);
3806 OSMO_ASSERT(link_info->is_deregistered);
3807
Jacob Erlbeckfb83ed32014-09-22 19:16:06 +02003808 OSMO_ASSERT(!expect_msg());
3809 received_messages = NULL;
3810
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003811 dump_global(stdout, 0);
3812
3813 gbprox_reset(&gbcfg);
3814 gprs_ns_destroy(nsi);
3815 nsi = NULL;
3816}
3817
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003818/* TODO: Move tlv testing to libosmocore */
3819int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3820int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3821 uint8_t **value);
3822int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3823 size_t *value_len);
3824int lv_shift(uint8_t **data, size_t *data_len,
3825 uint8_t **value, size_t *value_len);
3826
3827static void check_tlv_match(uint8_t **data, size_t *data_len,
3828 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3829{
3830 uint8_t *value;
3831 size_t value_len;
3832 int rc;
3833
3834 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3835 OSMO_ASSERT(rc == 0);
3836
3837 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003838 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003839 OSMO_ASSERT(value_len == exp_len);
3840 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3841}
3842
3843static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3844 uint8_t tag, size_t len, const uint8_t *exp_val)
3845{
3846 uint8_t *value;
3847 int rc;
3848
3849 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3850 OSMO_ASSERT(rc == 0);
3851
3852 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003853 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003854 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3855}
3856
3857static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3858 size_t len, const uint8_t *exp_val)
3859{
3860 uint8_t *value;
3861 int rc;
3862
3863 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003864 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003865 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3866}
3867
3868static void check_lv_shift(uint8_t **data, size_t *data_len,
3869 size_t exp_len, const uint8_t *exp_val)
3870{
3871 uint8_t *value;
3872 size_t value_len;
3873 int rc;
3874
3875 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003876 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003877 OSMO_ASSERT(value_len == exp_len);
3878 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3879}
3880
3881static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3882 const uint8_t *test_data)
3883{
3884 uint8_t buf[300] = {0};
3885
3886 uint8_t *unchanged_ptr = buf - 1;
3887 size_t unchanged_len = 0xdead;
3888 size_t tmp_data_len = data_len;
3889 uint8_t *value = unchanged_ptr;
3890 size_t value_len = unchanged_len;
3891 uint8_t *data = buf;
3892
3893 OSMO_ASSERT(data_len <= sizeof(buf));
3894
3895 tlv_put(data, tag, len, test_data);
3896 if (data_len < len + 2) {
3897 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3898 tag, &value, &value_len));
3899 OSMO_ASSERT(tmp_data_len == 0);
3900 OSMO_ASSERT(data == buf + data_len);
3901 OSMO_ASSERT(value == unchanged_ptr);
3902 OSMO_ASSERT(value_len == unchanged_len);
3903 } else {
3904 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3905 tag, &value, &value_len));
3906 OSMO_ASSERT(value != unchanged_ptr);
3907 OSMO_ASSERT(value_len != unchanged_len);
3908 }
3909}
3910
3911static void check_tv_fixed_match_data_len(size_t data_len,
3912 uint8_t tag, size_t len,
3913 const uint8_t *test_data)
3914{
3915 uint8_t buf[300] = {0};
3916
3917 uint8_t *unchanged_ptr = buf - 1;
3918 size_t tmp_data_len = data_len;
3919 uint8_t *value = unchanged_ptr;
3920 uint8_t *data = buf;
3921
3922 OSMO_ASSERT(data_len <= sizeof(buf));
3923
3924 tv_fixed_put(data, tag, len, test_data);
3925
3926 if (data_len < len + 1) {
3927 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3928 tag, len, &value));
3929 OSMO_ASSERT(tmp_data_len == 0);
3930 OSMO_ASSERT(data == buf + data_len);
3931 OSMO_ASSERT(value == unchanged_ptr);
3932 } else {
3933 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3934 tag, len, &value));
3935 OSMO_ASSERT(value != unchanged_ptr);
3936 }
3937}
3938
3939static void check_v_fixed_shift_data_len(size_t data_len,
3940 size_t len, const uint8_t *test_data)
3941{
3942 uint8_t buf[300] = {0};
3943
3944 uint8_t *unchanged_ptr = buf - 1;
3945 size_t tmp_data_len = data_len;
3946 uint8_t *value = unchanged_ptr;
3947 uint8_t *data = buf;
3948
3949 OSMO_ASSERT(data_len <= sizeof(buf));
3950
3951 memcpy(data, test_data, len);
3952
3953 if (data_len < len) {
3954 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3955 len, &value));
3956 OSMO_ASSERT(tmp_data_len == 0);
3957 OSMO_ASSERT(data == buf + data_len);
3958 OSMO_ASSERT(value == unchanged_ptr);
3959 } else {
3960 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3961 len, &value));
3962 OSMO_ASSERT(value != unchanged_ptr);
3963 }
3964}
3965
3966static void check_lv_shift_data_len(size_t data_len,
3967 size_t len, const uint8_t *test_data)
3968{
3969 uint8_t buf[300] = {0};
3970
3971 uint8_t *unchanged_ptr = buf - 1;
3972 size_t unchanged_len = 0xdead;
3973 size_t tmp_data_len = data_len;
3974 uint8_t *value = unchanged_ptr;
3975 size_t value_len = unchanged_len;
3976 uint8_t *data = buf;
3977
3978 lv_put(data, len, test_data);
3979 if (data_len < len + 1) {
3980 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3981 &value, &value_len));
3982 OSMO_ASSERT(tmp_data_len == 0);
3983 OSMO_ASSERT(data == buf + data_len);
3984 OSMO_ASSERT(value == unchanged_ptr);
3985 OSMO_ASSERT(value_len == unchanged_len);
3986 } else {
3987 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3988 &value, &value_len));
3989 OSMO_ASSERT(value != unchanged_ptr);
3990 OSMO_ASSERT(value_len != unchanged_len);
3991 }
3992}
3993
3994static void test_tlv_shift_functions()
3995{
3996 uint8_t test_data[1024];
3997 uint8_t buf[1024];
3998 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003999 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004000 uint8_t *data;
4001 size_t data_len;
4002 const uint8_t tag = 0x1a;
4003
4004 printf("Test shift functions\n");
4005
4006 for (i = 0; i < ARRAY_SIZE(test_data); i++)
4007 test_data[i] = (uint8_t)i;
4008
4009 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02004010 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004011
4012 memset(buf, 0xee, sizeof(buf));
4013 data_end = data = buf;
4014
4015 for (i = 0; i < iterations; i++) {
4016 data_end = tlv_put(data_end, tag, len, test_data);
4017 data_end = tv_fixed_put(data_end, tag, len, test_data);
4018 /* v_fixed_put */
4019 memcpy(data_end, test_data, len);
4020 data_end += len;
4021 data_end = lv_put(data_end, len, test_data);
4022 }
4023
4024 data_len = data_end - data;
4025 OSMO_ASSERT(data_len <= sizeof(buf));
4026
4027 for (i = 0; i < iterations; i++) {
4028 check_tlv_match(&data, &data_len, tag, len, test_data);
4029 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
4030 check_v_fixed_shift(&data, &data_len, len, test_data);
4031 check_lv_shift(&data, &data_len, len, test_data);
4032 }
4033
4034 OSMO_ASSERT(data == data_end);
4035
4036 /* Test at end of data */
4037
4038 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
4039 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
4040 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
4041 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
4042
4043 /* Test invalid data_len */
4044 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
4045 check_tlv_match_data_len(data_len, tag, len, test_data);
4046 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
4047 check_v_fixed_shift_data_len(data_len, len, test_data);
4048 check_lv_shift_data_len(data_len, len, test_data);
4049 }
4050 }
4051}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004052
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004053struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004054 struct gbproxy_peer *peer, uint32_t tlli,
4055 const uint8_t *imsi, size_t imsi_len, time_t now)
4056{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004057 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004058 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004059 int tlli_already_known = 0;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004060 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004061
4062 /* Check, whether the IMSI matches */
4063 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004064 imsi_matches = gbproxy_check_imsi(
4065 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004066 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004067 return NULL;
4068 }
4069
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004070 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004071
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004072 if (!link_info) {
4073 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004074
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004075 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004076 /* TLLI has changed somehow, adjust it */
4077 LOGP(DGPRS, LOGL_INFO,
4078 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004079 link_info->tlli.current, tlli);
4080 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004081 }
4082 }
4083
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004084 if (!link_info) {
4085 link_info = gbproxy_link_info_alloc(peer);
4086 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004087 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004088 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004089 tlli_already_known = 1;
4090 }
4091
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004092 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004093
4094 if (!tlli_already_known)
4095 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
4096
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004097 gbproxy_attach_link_info(peer, now, link_info);
4098 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004099
Jacob Erlbeck8992f302014-09-19 13:17:55 +02004100 if (imsi_matches >= 0)
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004101 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004102
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004103 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004104}
4105
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004106static void test_gbproxy_tlli_expire(void)
4107{
4108 struct gbproxy_config cfg = {0};
4109 struct gbproxy_peer *peer;
4110 const char *err_msg = NULL;
4111 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4112 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004113 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004114 const uint32_t tlli1 = 1234 | 0xc0000000;
4115 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004116 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004117 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004118 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004119
4120 printf("Test TLLI info expiry\n\n");
4121
4122 gbproxy_init_config(&cfg);
4123
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004124 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4125 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004126 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4127 err_msg);
4128 OSMO_ASSERT(err_msg == NULL);
4129 }
4130
4131 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004132 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004133
4134 printf("Test TLLI replacement:\n");
4135
4136 cfg.tlli_max_len = 0;
4137 cfg.tlli_max_age = 0;
4138 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004139 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004140
4141 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004142 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004143 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004144 OSMO_ASSERT(link_info);
4145 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004146 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004147
4148 /* replace the old entry */
4149 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004150 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004151 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004152 OSMO_ASSERT(link_info);
4153 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004154 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004155
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004156 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004157
4158 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004159 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4160 OSMO_ASSERT(link_info);
4161 OSMO_ASSERT(link_info->tlli.current == tlli2);
4162 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4163 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004164
4165 printf("\n");
4166
4167 gbproxy_peer_free(peer);
4168 }
4169
4170 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004171 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004172
4173 printf("Test IMSI replacement:\n");
4174
4175 cfg.tlli_max_len = 0;
4176 cfg.tlli_max_age = 0;
4177 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004178 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004179
4180 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004181 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004182 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004183 OSMO_ASSERT(link_info);
4184 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004185 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004186
4187 /* try to replace the old entry */
4188 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004189 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004190 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004191 OSMO_ASSERT(link_info);
4192 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004193 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004194
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004195 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004196
4197 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004198 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4199 OSMO_ASSERT(!link_info);
4200 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4201 OSMO_ASSERT(link_info);
4202 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004203
4204 printf("\n");
4205
4206 gbproxy_peer_free(peer);
4207 }
4208
4209 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004210 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004211 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004212
4213 printf("Test TLLI expiry, max_len == 1:\n");
4214
4215 cfg.tlli_max_len = 1;
4216 cfg.tlli_max_age = 0;
4217 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004218 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004219
4220 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004221 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004222 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004223
4224 /* replace the old entry */
4225 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004226 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004227 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004228
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004229 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004230 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004231 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004232
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004233 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004234
4235 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004236 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4237 OSMO_ASSERT(!link_info);
4238 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4239 OSMO_ASSERT(link_info);
4240 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004241
4242 printf("\n");
4243
4244 gbproxy_peer_free(peer);
4245 }
4246
4247 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004248 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004249 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004250
4251 printf("Test TLLI expiry, max_age == 1:\n");
4252
4253 cfg.tlli_max_len = 0;
4254 cfg.tlli_max_age = 1;
4255 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004256 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004257
4258 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004259 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004260 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004261
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004262 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004263 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004264 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004265 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004266
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004267 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004268 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004269 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004270
4271 dump_peers(stdout, 2, now + 2, &cfg);
4272
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004273 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004274 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4275 OSMO_ASSERT(!link_info);
4276 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4277 OSMO_ASSERT(link_info);
4278 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004279
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004280 printf("\n");
4281
4282 gbproxy_peer_free(peer);
4283 }
4284
4285 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004286 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004287 int num_removed;
4288
4289 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4290
4291 cfg.tlli_max_len = 0;
4292 cfg.tlli_max_age = 1;
4293 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004294 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004295
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004296 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004297 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004298 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004299
4300 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004301 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004302 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004303 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004304
4305 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004306 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004307 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004308 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004309
4310 dump_peers(stdout, 2, now + 2, &cfg);
4311
4312 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004313 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004314 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004315 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004316
4317 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004318
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004319 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004320 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4321 OSMO_ASSERT(!link_info);
4322 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4323 OSMO_ASSERT(!link_info);
4324 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4325 OSMO_ASSERT(link_info);
4326 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004327
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004328 printf("\n");
4329
4330 gbproxy_peer_free(peer);
4331 }
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004332 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4333 gbprox_reset(&cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004334}
4335
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004336static void test_gbproxy_imsi_matching(void)
4337{
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004338 const char *err_msg = NULL;
4339 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4340 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4341 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4342 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4343 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4344 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4345 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4346 const char *filter_re1 = ".*";
4347 const char *filter_re2 = "^1234";
4348 const char *filter_re3 = "^4321";
4349 const char *filter_re4_bad = "^12[";
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004350 struct gbproxy_match match = {0,};
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004351
4352 printf("=== Test IMSI/TMSI matching ===\n\n");
4353
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004354 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004355
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004356 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4357 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004358
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004359 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4360 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004361
4362 err_msg = NULL;
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004363 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004364 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004365 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004366
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004367 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4368 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004369
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004370 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4371 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004372
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004373 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4374 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004375
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004376 gbproxy_clear_patch_filter(&match);
4377 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004378
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004379 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4380 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004381
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004382 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4383 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004384 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004385 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004386 * case. */
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004387 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4388 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4389 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4390 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4391 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004392
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004393 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4394 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004395
Jacob Erlbeck9a83d7a2014-09-25 11:17:31 +02004396 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4397 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4398 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4399 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4400 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4401 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4402 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004403
4404 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck9ccc41e2014-09-25 11:21:34 +02004405
4406 gbproxy_clear_patch_filter(&match);
4407 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004408}
4409
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004410static struct log_info_cat gprs_categories[] = {
4411 [DGPRS] = {
4412 .name = "DGPRS",
4413 .description = "GPRS Packet Service",
4414 .enabled = 1, .loglevel = LOGL_DEBUG,
4415 },
4416 [DNS] = {
4417 .name = "DNS",
4418 .description = "GPRS Network Service (NS)",
4419 .enabled = 1, .loglevel = LOGL_INFO,
4420 },
4421 [DBSSGP] = {
4422 .name = "DBSSGP",
4423 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4424 .enabled = 1, .loglevel = LOGL_DEBUG,
4425 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004426};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004427
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004428static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004429 .cat = gprs_categories,
4430 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004431};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004432
4433int main(int argc, char **argv)
4434{
4435 osmo_init_logging(&info);
4436 log_set_use_color(osmo_stderr_target, 0);
4437 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02004438 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004439
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004440 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004441 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4442 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004443
4444 rate_ctr_init(NULL);
4445
4446 setlinebuf(stdout);
4447
4448 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004449 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004450 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004451 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004452 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004453 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004454 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004455 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004456 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004457 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004458 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004459 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004460 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004461 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004462
4463 exit(EXIT_SUCCESS);
4464}