blob: 84d51bdd8a89177df2d0f650dd059877b6487517 [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 Erlbeck91d2f8a2014-09-19 15:07:27 +0200132 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200133 stored_msgs++;
134
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200135 if (link_info->imsi_len > 0) {
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200136 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
137 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200138 link_info->imsi,
139 link_info->imsi_len);
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200140 } else {
141 snprintf(mi_buf, sizeof(mi_buf), "(none)");
142 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200143 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200144 indent, "", link_info->tlli.current);
145 if (link_info->tlli.assigned)
146 fprintf(stream, "/%08x", link_info->tlli.assigned);
147 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200148 fprintf(stream, " -> %08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200149 link_info->sgsn_tlli.current);
150 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200151 fprintf(stream, "/%08x",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200152 link_info->sgsn_tlli.assigned);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200153 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200154 fprintf(stream, ", IMSI %s, AGE %d",
155 mi_buf, (int)age);
156
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200157 if (stored_msgs)
158 fprintf(stream, ", STORED %d", stored_msgs);
159
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200160 if (cfg->check_imsi && link_info->imsi_matches)
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200161 fprintf(stream, ", IMSI matches");
162
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200163 if (link_info->imsi_acq_pending)
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200164 fprintf(stream, ", IMSI acquisition in progress");
165
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200166 if (cfg->route_to_sgsn2)
167 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200168 link_info->sgsn_nsei);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +0200169
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +0200170 if (link_info->is_deregistered)
Jacob Erlbeck7430da62014-09-12 15:09:56 +0200171 fprintf(stream, ", DE-REGISTERED");
172
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200173 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200174 if (rc < 0)
175 return rc;
176 }
177 }
178
179 return 0;
180}
181
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200182const uint8_t *convert_ra(struct gprs_ra_id *raid)
183{
184 static uint8_t buf[6];
185 gsm48_construct_ra(buf, raid);
186 return buf;
187}
188
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200189/* DTAP - Attach Request */
190static const unsigned char dtap_attach_req[] = {
191 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
192 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
193 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
194 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
195 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
196 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200197};
198
Jacob Erlbeck991606b2014-09-12 10:33:38 +0200199/* DTAP - Attach Request (invalid RAI) */
200static const unsigned char dtap_attach_req2[] = {
201 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
202 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
203 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
204 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
205 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
206 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
207};
208
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200209/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
210static const unsigned char dtap_attach_req3[] = {
211 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
212 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
213 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
214 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
215 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
216 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
217};
218
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200219/* DTAP - Identity Request */
220static const unsigned char dtap_identity_req[] = {
221 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200222};
223
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200224/* DTAP - Identity Response */
225static const unsigned char dtap_identity_resp[] = {
226 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
227 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200228};
229
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200230/* DTAP - Identity Response, IMSI 2 */
231static const unsigned char dtap_identity2_resp[] = {
232 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
233 0x16, 0x17, 0x18
234};
235
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +0200236/* DTAP - Identity Response, IMSI 3 */
237static const unsigned char dtap_identity3_resp[] = {
238 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
239 0x26, 0x27, 0x28
240};
241
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200242/* DTAP - Attach Accept */
243static const unsigned char dtap_attach_acc[] = {
244 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
245 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
246 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200247};
248
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200249/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200250static const unsigned char dtap_attach_acc2[] = {
251 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
252 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
253 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
254};
255
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200256/* DTAP - Attach Complete */
257static const unsigned char dtap_attach_complete[] = {
258 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200259};
260
Jacob Erlbeck2bf32612014-09-22 11:26:58 +0200261/* DTAP - Attach Reject (GPRS services not allowed) */
262static const unsigned char dtap_attach_rej7[] = {
263 0x08, 0x04, 0x07
264};
265
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200266/* DTAP - GMM Information */
267static const unsigned char dtap_gmm_information[] = {
268 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200269};
270
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200271/* DTAP - Routing Area Update Request */
272static const unsigned char dtap_ra_upd_req[] = {
273 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
274 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
275 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
276 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
277 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
278 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
279 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200280};
281
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200282/* DTAP - Routing Area Update Accept */
283static const unsigned char dtap_ra_upd_acc[] = {
284 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
285 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
286 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200287};
288
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200289/* DTAP - Routing Area Update Accept, P-TMSI 2 */
290static const unsigned char dtap_ra_upd_acc2[] = {
291 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
292 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
293 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
294};
295
296/* DTAP - Routing Area Update Accept, P-TMSI 3 */
297static const unsigned char dtap_ra_upd_acc3[] = {
298 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
299 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
300 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
301};
302
303/* DTAP - Routing Area Update Complete */
304static const unsigned char dtap_ra_upd_complete[] = {
305 0x08, 0x0a
306};
307
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200308/* DTAP - Routing Area Update Reject */
309/* cause = 10 ("Implicitly detached"), force_standby = 0 */
310static const unsigned char dtap_ra_upd_rej[] = {
311 0x08, 0x0b, 0x0a, 0x00,
312};
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200313
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200314/* DTAP - Activate PDP Context Request */
315static const unsigned char dtap_act_pdp_ctx_req[] = {
316 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200317 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
319 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
320 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
321 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200322 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200323};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200324
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200325/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200326/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200327static const unsigned char dtap_detach_po_req[] = {
328 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
329 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200330};
331
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200332/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200333/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200334static const unsigned char dtap_detach_req[] = {
335 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
336 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200337};
338
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200339/* DTAP - Detach Accept (MO) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200340static const unsigned char dtap_detach_acc[] = {
341 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200342};
343
Jacob Erlbeck772a22b2014-09-15 14:18:09 +0200344/* DTAP - Detach Request (MT) */
345/* normal detach, reattach required, implicitly detached */
346static const unsigned char dtap_mt_detach_rea_req[] = {
347 0x08, 0x05, 0x01, 0x25, 0x0a
348};
349
350/* DTAP - Detach Request (MT) */
351/* normal detach, reattach not required, implicitly detached */
352static const unsigned char dtap_mt_detach_req[] = {
353 0x08, 0x05, 0x02, 0x25, 0x0a
354};
355
356/* DTAP - Detach Accept (MT) */
357static const unsigned char dtap_mt_detach_acc[] = {
358 0x08, 0x06
359};
360
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200361/* GPRS-LLC - SAPI: LLGMM, U, XID */
362static const unsigned char llc_u_xid_ul[] = {
363 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
364 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
365};
366
367/* GPRS-LLC - SAPI: LLGMM, U, XID */
368static const unsigned char llc_u_xid_dl[] = {
369 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
370 0xe4, 0xa9, 0x1a, 0x9e
371};
372
373/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
374static const unsigned char llc_ui_ll11_dns_query_ul[] = {
375 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
376 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
377 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
378 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
379 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
380 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
381 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
382 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
383 0x8f, 0x07
384};
385
386/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
387static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
388 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
389 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
390 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
391 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
392 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
393 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
394 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
395 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
396 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
397 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
398 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
399 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
400 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
401 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
402 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
403 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
404 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
405 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
406 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
407 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
408 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
409 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
410 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
411 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
412 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
413 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
414};
415
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200416static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
417 struct sockaddr_in *peer, const unsigned char* data,
418 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200419
420static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
421 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
422{
423 /* GPRS Network Service, PDU type: NS_RESET,
424 */
425 unsigned char msg[12] = {
426 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
427 0x04, 0x82, 0x11, 0x22
428 };
429
430 msg[3] = cause;
431 msg[6] = nsvci / 256;
432 msg[7] = nsvci % 256;
433 msg[10] = nsei / 256;
434 msg[11] = nsei % 256;
435
436 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
437}
438
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200439static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
440 uint16_t nsvci, uint16_t nsei)
441{
442 /* GPRS Network Service, PDU type: NS_RESET_ACK,
443 */
444 unsigned char msg[9] = {
445 0x03, 0x01, 0x82, 0x11, 0x22,
446 0x04, 0x82, 0x11, 0x22
447 };
448
449 msg[3] = nsvci / 256;
450 msg[4] = nsvci % 256;
451 msg[7] = nsei / 256;
452 msg[8] = nsei % 256;
453
454 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
455}
456
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200457static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
458{
459 /* GPRS Network Service, PDU type: NS_ALIVE */
460 unsigned char msg[1] = {
461 0x0a
462 };
463
464 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
465}
466
467static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
468{
469 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
470 unsigned char msg[1] = {
471 0x0b
472 };
473
474 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
475}
476
477static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
478{
479 /* GPRS Network Service, PDU type: NS_UNBLOCK */
480 unsigned char msg[1] = {
481 0x06
482 };
483
484 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
485}
486
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200487static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
488{
489 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
490 unsigned char msg[1] = {
491 0x07
492 };
493
494 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
495}
496
497static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
498 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200499 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
500{
501 /* GPRS Network Service, PDU type: NS_UNITDATA */
502 unsigned char msg[4096] = {
503 0x00, 0x00, 0x00, 0x00
504 };
505
506 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
507
508 msg[2] = nsbvci / 256;
509 msg[3] = nsbvci % 256;
510 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
511
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200512 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200513}
514
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200515static void send_bssgp_ul_unitdata(
516 struct gprs_ns_inst *nsi, const char *text,
517 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
518 struct gprs_ra_id *raid, uint16_t cell_id,
519 const uint8_t *llc_msg, size_t llc_msg_size)
520{
521 /* GPRS Network Service, PDU type: NS_UNITDATA */
522 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
523 unsigned char msg[4096] = {
524 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
525 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
526 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
527 };
528
529 size_t bssgp_msg_size = 23 + llc_msg_size;
530
531 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
532
533 gsm48_construct_ra(msg + 10, raid);
534 msg[1] = (uint8_t)(tlli >> 24);
535 msg[2] = (uint8_t)(tlli >> 16);
536 msg[3] = (uint8_t)(tlli >> 8);
537 msg[4] = (uint8_t)(tlli >> 0);
538 msg[16] = cell_id / 256;
539 msg[17] = cell_id % 256;
540 msg[21] = llc_msg_size / 256;
541 msg[22] = llc_msg_size % 256;
542 memcpy(msg + 23, llc_msg, llc_msg_size);
543
544 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
545 src_addr, nsbvci, msg, bssgp_msg_size);
546}
547
548static void send_bssgp_dl_unitdata(
549 struct gprs_ns_inst *nsi, const char *text,
550 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
551 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
552 const uint8_t *llc_msg, size_t llc_msg_size)
553{
554 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
555 unsigned char msg[4096] = {
556 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
557 0x16, 0x82, 0x02, 0x58,
558 };
559 unsigned char racap_drx[] = {
560 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
561 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
562 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
563 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
564 };
565
566 size_t bssgp_msg_size = 0;
567
568 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
569
570 msg[1] = (uint8_t)(tlli >> 24);
571 msg[2] = (uint8_t)(tlli >> 16);
572 msg[3] = (uint8_t)(tlli >> 8);
573 msg[4] = (uint8_t)(tlli >> 0);
574
575 bssgp_msg_size = 12;
576
577 if (with_racap_drx) {
578 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
579 bssgp_msg_size += sizeof(racap_drx);
580 }
581
582 if (imsi) {
583 OSMO_ASSERT(imsi_size <= 127);
584 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
585 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
586 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
587 bssgp_msg_size += 2 + imsi_size;
588 }
589
590 if ((bssgp_msg_size % 4) != 0) {
591 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
592 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
593 msg[bssgp_msg_size + 1] = 0x80 | abytes;
594 memset(msg + bssgp_msg_size + 2, 0, abytes);
595 bssgp_msg_size += 2 + abytes;
596 }
597
598 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
599 if (llc_msg_size < 128) {
600 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
601 bssgp_msg_size += 2;
602 } else {
603 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
604 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
605 bssgp_msg_size += 3;
606 }
607 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
608 bssgp_msg_size += llc_msg_size;
609
610
611 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
612 src_addr, nsbvci, msg, bssgp_msg_size);
613}
614
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200615static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
616 uint16_t bvci)
617{
618 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
619 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200620 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200621 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200622 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
623 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200624 };
625
626 msg[3] = bvci / 256;
627 msg[4] = bvci % 256;
628
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200629 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
630}
631
632static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
633 struct sockaddr_in *src_addr, uint16_t bvci)
634{
635 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
636 * BSSGP RESET_ACK */
637 static unsigned char msg[5] = {
638 0x23, 0x04, 0x82, 0x00,
639 0x00
640 };
641
642 msg[3] = bvci / 256;
643 msg[4] = bvci % 256;
644
645 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200646}
647
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200648static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
649 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200650 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200651 struct gprs_ra_id *raid)
652{
653 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
654 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200655 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
656 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200657 };
658
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200659 msg[3] = (uint8_t)(tlli >> 24);
660 msg[4] = (uint8_t)(tlli >> 16);
661 msg[5] = (uint8_t)(tlli >> 8);
662 msg[6] = (uint8_t)(tlli >> 0);
663
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200664 gsm48_construct_ra(msg + 9, raid);
665
666 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
667}
668
669static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
670 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200671 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200672 struct gprs_ra_id *raid)
673{
674 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
675 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200676 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
677 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200678 0x81, 0x01
679 };
680
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200681 msg[3] = (uint8_t)(tlli >> 24);
682 msg[4] = (uint8_t)(tlli >> 16);
683 msg[5] = (uint8_t)(tlli >> 8);
684 msg[6] = (uint8_t)(tlli >> 0);
685
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200686 gsm48_construct_ra(msg + 9, raid);
687
688 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
689}
690
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200691static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
692 struct sockaddr_in *src_addr,
693 uint16_t bvci, uint32_t tlli,
694 unsigned n_frames, unsigned n_octets)
695{
696 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
697 unsigned char msg[] = {
698 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
699 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
700 /* n octets */ 0xff, 0xff, 0xff
701 };
702
703 msg[3] = (uint8_t)(tlli >> 24);
704 msg[4] = (uint8_t)(tlli >> 16);
705 msg[5] = (uint8_t)(tlli >> 8);
706 msg[6] = (uint8_t)(tlli >> 0);
707 msg[9] = (uint8_t)(n_frames);
708 msg[12] = (uint8_t)(bvci >> 8);
709 msg[13] = (uint8_t)(bvci >> 0);
710 msg[16] = (uint8_t)(n_octets >> 16);
711 msg[17] = (uint8_t)(n_octets >> 8);
712 msg[18] = (uint8_t)(n_octets >> 0);
713
714 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
715}
716
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200717static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
718 struct sockaddr_in *src_addr,
719 uint16_t bvci, uint8_t tag)
720{
721 /* GPRS Network Service, PDU type: NS_UNITDATA,
722 * BSSGP FLOW_CONTROL_BVC */
723 unsigned char msg[] = {
724 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
725 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
726 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
727 };
728
729 msg[3] = tag;
730
731 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
732 msg, sizeof(msg));
733}
734
735static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
736 struct sockaddr_in *src_addr,
737 uint16_t bvci, uint8_t tag)
738{
739 /* GPRS Network Service, PDU type: NS_UNITDATA,
740 * BSSGP FLOW_CONTROL_BVC_ACK */
741 unsigned char msg[] = {
742 0x27, 0x1e, 0x81, /* Tag */ 0xce
743 };
744
745 msg[3] = tag;
746
747 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
748 msg, sizeof(msg));
749}
750
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200751static void send_llc_ul_ui(
752 struct gprs_ns_inst *nsi, const char *text,
753 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
754 struct gprs_ra_id *raid, uint16_t cell_id,
755 unsigned sapi, unsigned nu,
756 const uint8_t *msg, size_t msg_size)
757{
758 unsigned char llc_msg[4096] = {
759 0x00, 0xc0, 0x01
760 };
761
762 size_t llc_msg_size = 3 + msg_size + 3;
763 uint8_t e_bit = 0;
764 uint8_t pm_bit = 1;
765 unsigned fcs;
766
767 nu &= 0x01ff;
768
769 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
770
771 llc_msg[0] = (sapi & 0x0f);
772 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
773 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
774
775 memcpy(llc_msg + 3, msg, msg_size);
776
777 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
778 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
779 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
780 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
781
782 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
783 src_addr, nsbvci, tlli, raid, cell_id,
784 llc_msg, llc_msg_size);
785}
786
787static void send_llc_dl_ui(
788 struct gprs_ns_inst *nsi, const char *text,
789 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
790 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
791 unsigned sapi, unsigned nu,
792 const uint8_t *msg, size_t msg_size)
793{
794 /* GPRS Network Service, PDU type: NS_UNITDATA */
795 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
796 unsigned char llc_msg[4096] = {
797 0x00, 0x00, 0x01
798 };
799
800 size_t llc_msg_size = 3 + msg_size + 3;
801 uint8_t e_bit = 0;
802 uint8_t pm_bit = 1;
803 unsigned fcs;
804
805 nu &= 0x01ff;
806
807 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
808
809 llc_msg[0] = 0x40 | (sapi & 0x0f);
810 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
811 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
812
813 memcpy(llc_msg + 3, msg, msg_size);
814
815 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
816 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
817 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
818 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
819
820 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
821 src_addr, nsbvci, tlli,
822 with_racap_drx, imsi, imsi_size,
823 llc_msg, llc_msg_size);
824}
825
826
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200827static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
828 uint16_t nsvci, uint16_t nsei)
829{
830 printf("Setup NS-VC: remote 0x%08x:%d, "
831 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
832 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
833 nsvci, nsvci, nsei, nsei);
834
835 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
836 send_ns_alive(nsi, src_addr);
837 send_ns_unblock(nsi, src_addr);
838 send_ns_alive_ack(nsi, src_addr);
839}
840
841static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
842 uint16_t bvci)
843{
844 printf("Setup BSSGP: remote 0x%08x:%d, "
845 "BVCI 0x%04x(%d)\n\n",
846 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
847 bvci, bvci);
848
849 send_bssgp_reset(nsi, src_addr, bvci);
850}
851
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200852static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
853 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200854{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200855 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
856 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200857 send_ns_alive_ack(nsi, sgsn_peer);
858 send_ns_unblock_ack(nsi, sgsn_peer);
859 send_ns_alive(nsi, sgsn_peer);
860}
861
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200862static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
863{
864 sgsn_peer->sin_family = AF_INET;
865 sgsn_peer->sin_port = htons(32000);
866 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
867}
868
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200869static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
870{
871 sgsn_peer->sin_family = AF_INET;
872 sgsn_peer->sin_port = htons(32001);
873 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
874}
875
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200876static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
877{
878 size_t i;
879
880 for (i = 0; i < size; ++i) {
881 bss_peers[i].sin_family = AF_INET;
882 bss_peers[i].sin_port = htons((i + 1) * 1111);
883 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
884 }
885}
886
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200887int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
888 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
889
890/* override */
891int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
892 struct msgb *msg, uint16_t bvci)
893{
894 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
895 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200896 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200897
898 switch (event) {
899 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200900 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200901 default:
902 break;
903 }
904 return 0;
905}
906
907/* override */
908ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
909 const struct sockaddr *dest_addr, socklen_t addrlen)
910{
911 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
912 const struct sockaddr *, socklen_t);
913 static sendto_t real_sendto = NULL;
914 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200915 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200916
917 if (!real_sendto)
918 real_sendto = dlsym(RTLD_NEXT, "sendto");
919
920 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200921 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
922 dest_host, dest_port,
923 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200924 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200925 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
926 dest_host, dest_port,
927 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200928 else if (dest_host == REMOTE_SGSN2_ADDR)
929 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
930 dest_host, dest_port,
931 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200932 else
933 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
934
935 return len;
936}
937
938/* override */
939int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
940{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200941 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
942 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200943 uint16_t bvci = msgb_bvci(msg);
944 uint16_t nsei = msgb_nsei(msg);
945
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200946 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200947
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200948 if (!real_gprs_ns_sendmsg)
949 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
950
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200951 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200952 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
953 "msg length %d (%s)\n",
954 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200955 else if (nsei == SGSN2_NSEI)
956 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
957 "msg length %d (%s)\n",
958 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200959 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200960 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
961 "msg length %d (%s)\n",
962 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200963
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200964 if (received_messages) {
965 struct msgb *msg_copy;
966 msg_copy = gprs_msgb_copy(msg, "received_messages");
967 llist_add_tail(&msg_copy->list, received_messages);
968 }
969
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200970 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200971}
972
Jacob Erlbeckacfaff32014-09-22 18:54:34 +0200973/* Get the next message from the receive FIFO
974 *
975 * \returns a pointer to the message which will be invalidated at the next call
976 * to expect_msg. Returns NULL, if there is no message left.
977 */
978static struct msgb *expect_msg(void)
979{
980 static struct msgb *msg = NULL;
981
982 msgb_free(msg);
983 msg = NULL;
984
985 if (!received_messages)
986 return NULL;
987
988 if (llist_empty(received_messages))
989 return NULL;
990
991 msg = llist_entry(received_messages->next, struct msgb, list);
992 llist_del(&msg->list);
993
994 return msg;
995}
996
997struct expect_result {
998 struct msgb *msg;
999 struct gprs_gb_parse_context parse_ctx;
1000};
1001
1002static struct expect_result *expect_bssgp_msg(
1003 int match_nsei, int match_bvci, int match_pdu_type)
1004{
1005 static struct expect_result result;
1006 static const struct expect_result empty_result = {0,};
1007 static struct msgb *msg;
1008 uint16_t nsei;
1009 int rc;
1010
1011 memcpy(&result, &empty_result, sizeof(result));
1012
1013 msg = expect_msg();
1014 if (!msg)
1015 return NULL;
1016
1017 nsei = msgb_nsei(msg);
1018
1019 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1020 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1021 __func__, match_nsei, nsei);
1022 return NULL;
1023 }
1024
1025 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1026 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1027 __func__, match_bvci, msgb_bvci(msg));
1028 return NULL;
1029 }
1030
1031 result.msg = msg;
1032
1033 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1034 result.parse_ctx.peer_nsei = nsei;
1035
1036 if (!msgb_bssgph(msg)) {
1037 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1038 return NULL;
1039 }
1040
1041 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1042 &result.parse_ctx);
1043
1044 if (!rc) {
1045 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1046 return NULL;
1047 }
1048
1049 if (match_pdu_type != MATCH_ANY &&
1050 match_pdu_type != result.parse_ctx.pdu_type) {
1051 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1052 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1053 return NULL;
1054 }
1055
1056 return &result;
1057}
1058
1059static struct expect_result *expect_llc_msg(
1060 int match_nsei, int match_bvci, int match_sapi, int match_type)
1061{
1062 static struct expect_result *result;
1063
1064 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1065 if (!result)
1066 return NULL;
1067
1068 if (!result->parse_ctx.llc) {
1069 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1070 return NULL;
1071 }
1072
1073 if (match_sapi != MATCH_ANY &&
1074 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1075 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1076 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1077 return NULL;
1078 }
1079
1080 if (match_type != MATCH_ANY &&
1081 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1082 fprintf(stderr,
1083 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1084 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1085 return NULL;
1086 }
1087
1088 return result;
1089}
1090
1091static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1092 int match_type)
1093{
1094 static struct expect_result *result;
1095
1096 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1097 if (!result)
1098 return NULL;
1099
1100 if (!result->parse_ctx.g48_hdr) {
1101 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1102 return NULL;
1103 }
1104
1105 if (match_type != MATCH_ANY &&
1106 match_type != result->parse_ctx.g48_hdr->msg_type) {
1107 fprintf(stderr,
1108 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1109 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1110 return NULL;
1111 }
1112
1113 return result;
1114}
1115
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001116static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1117 struct rate_ctr_group *ctrg)
1118{
1119 unsigned int i;
1120
1121 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1122 struct rate_ctr *ctr = &ctrg->ctr[i];
1123 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1124 fprintf(stream, " %s%s: %llu%s",
1125 prefix, ctrg->desc->ctr_desc[i].description,
1126 (long long)ctr->current,
1127 "\n");
1128 };
1129}
1130
1131/* Signal handler for signals from NS layer */
1132static int test_signal(unsigned int subsys, unsigned int signal,
1133 void *handler_data, void *signal_data)
1134{
1135 struct ns_signal_data *nssd = signal_data;
1136 int rc;
1137
1138 if (subsys != SS_L_NS)
1139 return 0;
1140
1141 switch (signal) {
1142 case S_NS_RESET:
1143 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1144 nssd->nsvc->nsvci,
1145 gprs_ns_ll_str(nssd->nsvc));
1146 break;
1147
1148 case S_NS_ALIVE_EXP:
1149 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1150 nssd->nsvc->nsvci,
1151 gprs_ns_ll_str(nssd->nsvc));
1152 break;
1153
1154 case S_NS_BLOCK:
1155 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1156 nssd->nsvc->nsvci,
1157 gprs_ns_ll_str(nssd->nsvc));
1158 break;
1159
1160 case S_NS_UNBLOCK:
1161 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1162 nssd->nsvc->nsvci,
1163 gprs_ns_ll_str(nssd->nsvc));
1164 break;
1165
1166 case S_NS_REPLACED:
1167 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1168 nssd->nsvc->nsvci,
1169 gprs_ns_ll_str(nssd->nsvc));
1170 printf(" -> 0x%04x/%s\n",
1171 nssd->old_nsvc->nsvci,
1172 gprs_ns_ll_str(nssd->old_nsvc));
1173 break;
1174
1175 default:
1176 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1177 nssd->nsvc->nsvci,
1178 gprs_ns_ll_str(nssd->nsvc));
1179 break;
1180 }
1181 printf("\n");
1182 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1183 return rc;
1184}
1185
1186static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1187{
1188 struct msgb *msg;
1189 int ret;
1190 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1191 fprintf(stderr, "message too long: %d\n", data_len);
1192 return -1;
1193 }
1194
1195 msg = gprs_ns_msgb_alloc();
1196 memmove(msg->data, data, data_len);
1197 msg->l2h = msg->data;
1198 msgb_put(msg, data_len);
1199
1200 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1201 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1202 osmo_hexdump(data, data_len));
1203
1204 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1205
1206 printf("result (%s) = %d\n\n", text, ret);
1207
1208 msgb_free(msg);
1209
1210 return ret;
1211}
1212
1213static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1214{
1215 struct gprs_nsvc *nsvc;
1216
1217 printf("Current NS-VCIs:\n");
1218 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1219 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001220 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001221 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001222 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1223 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1224 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001225 );
1226 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1227 }
1228 printf("\n");
1229}
1230
1231static void test_gbproxy()
1232{
1233 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1234 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001235 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001236
1237 bssgp_nsi = nsi;
1238 gbcfg.nsi = bssgp_nsi;
1239 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1240
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001241 configure_sgsn_peer(&sgsn_peer);
1242 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001243
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001244 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001245 printf("--- Initialise SGSN ---\n\n");
1246
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001247 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001248 gprs_dump_nsi(nsi);
1249
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001250 printf("--- Initialise BSS 1 ---\n\n");
1251
1252 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1253 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1254 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001255 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001256
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001257 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1258
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001259 printf("--- Initialise BSS 2 ---\n\n");
1260
1261 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1262 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1263 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001264 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001265
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001266 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1267
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001268 printf("--- Move BSS 1 to new port ---\n\n");
1269
1270 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1271 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001272 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001273
1274 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1275
1276 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1277 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001278 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001279
1280 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1281
1282 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1283 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001284 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001285
1286 printf("--- Move BSS 2 to new port ---\n\n");
1287
1288 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1289 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001290 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001291
1292 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1293
1294 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1295 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001296 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001297
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001298 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1299
1300 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1301 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001302 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001303
1304 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1305
1306 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1307 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001308 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001309
1310 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1311
1312 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1313
1314 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1315 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001316 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001317
1318 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1319
1320 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1321
1322 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1323 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001324 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001325
1326 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1327
1328 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1329
1330 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1331
1332 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1333
1334 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1335
1336 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1337
1338 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1339
1340 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1341
1342 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1343
1344 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1345
1346 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1347
1348 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1349
1350 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1351
1352 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1353
1354 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1355 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001356 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001357
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001358 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001359
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001360 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1361
1362 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1363
1364 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1365
1366 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1367
1368 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1369
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001370 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1371
1372 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1373
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001374 /* Find peer */
1375 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1376 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1377 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1378 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1379 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1380 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1381
1382
1383 /* Cleanup */
1384 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1385 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1386 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1387 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1388 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1389
1390 dump_peers(stdout, 0, 0, &gbcfg);
1391
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001392 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001393
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001394 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001395 gprs_ns_destroy(nsi);
1396 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001397}
1398
1399static void test_gbproxy_ident_changes()
1400{
1401 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1402 struct sockaddr_in bss_peer[1] = {{0},};
1403 struct sockaddr_in sgsn_peer= {0};
1404 uint16_t nsei[2] = {0x1000, 0x2000};
1405 uint16_t nsvci[2] = {0x1001, 0x2001};
1406 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1407
1408 bssgp_nsi = nsi;
1409 gbcfg.nsi = bssgp_nsi;
1410 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1411
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001412 configure_sgsn_peer(&sgsn_peer);
1413 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001414
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001415 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001416 printf("--- Initialise SGSN ---\n\n");
1417
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001418 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001419 gprs_dump_nsi(nsi);
1420
1421 printf("--- Initialise BSS 1 ---\n\n");
1422
1423 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1424 gprs_dump_nsi(nsi);
1425
1426 printf("--- Setup BVCI 1 ---\n\n");
1427
1428 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1429 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001430 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001431
1432 printf("--- Setup BVCI 2 ---\n\n");
1433
1434 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1435 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001436 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001437
1438 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1439
1440 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1441 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1442
1443 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1444
1445 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1446 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1447
1448 printf("--- Change NSEI ---\n\n");
1449
1450 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1451 gprs_dump_nsi(nsi);
1452
1453 printf("--- Setup BVCI 1 ---\n\n");
1454
1455 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1456 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001457 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001458
1459 printf("--- Setup BVCI 3 ---\n\n");
1460
1461 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1462 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001463 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001464
1465 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1466
1467 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1468 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1469
1470 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1471 " (should fail) ---\n\n");
1472
1473 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001474 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001475 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001476 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001477
1478 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1479
1480 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1481 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1482
1483 printf("--- Change NSVCI ---\n\n");
1484
1485 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1486 gprs_dump_nsi(nsi);
1487
1488 printf("--- Setup BVCI 1 ---\n\n");
1489
1490 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1491 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001492 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001493
1494 printf("--- Setup BVCI 4 ---\n\n");
1495
1496 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1497 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001498 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001499
1500 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1501
1502 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1503 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1504
1505 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1506 " (should fail) ---\n\n");
1507
1508 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001509 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001510 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001511 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001512
1513 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1514
1515 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1516 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1517
1518 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1519
1520 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1521 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1522
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001523 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001524 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001525
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001526 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001527 gprs_ns_destroy(nsi);
1528 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001529}
1530
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001531static void test_gbproxy_ra_patching()
1532{
1533 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1534 struct sockaddr_in bss_peer[1] = {{0},};
1535 struct sockaddr_in sgsn_peer= {0};
1536 struct gprs_ra_id rai_bss =
1537 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1538 struct gprs_ra_id rai_sgsn =
1539 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1540 struct gprs_ra_id rai_unknown =
1541 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001542 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001543 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001544 const uint32_t ptmsi = 0xefe2b700;
1545 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001546 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001547 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001548 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001549 struct gbproxy_link_info *link_info;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001550 struct gbproxy_peer *peer;
1551
1552 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001553
1554 bssgp_nsi = nsi;
1555 gbcfg.nsi = bssgp_nsi;
1556 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001557 gbcfg.core_mcc = 123;
1558 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001559 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001560 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001561 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001562
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001563 configure_sgsn_peer(&sgsn_peer);
1564 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001565
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001566 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001567 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001568 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1569 gbcfg.match_re, err_msg);
1570 exit(1);
1571 }
1572
1573
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001574 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001575 printf("--- Initialise SGSN ---\n\n");
1576
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001577 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001578 gprs_dump_nsi(nsi);
1579
1580 printf("--- Initialise BSS 1 ---\n\n");
1581
1582 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1583 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1584 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001585 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001586
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001587 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001588 OSMO_ASSERT(peer != NULL);
1589
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001590 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1591
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001592 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1593 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001594
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001595 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001596 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001597
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001598 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1599 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1600
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001601 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1602
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001603 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1604 foreign_tlli, &rai_bss, cell_id,
1605 GPRS_SAPI_GMM, 0,
1606 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001607
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001608 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1609
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001610 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1611 foreign_tlli, 0, NULL, 0,
1612 GPRS_SAPI_GMM, 0,
1613 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001614
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001615 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1616 foreign_tlli, &rai_bss, cell_id,
1617 GPRS_SAPI_GMM, 3,
1618 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001619
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001620 OSMO_ASSERT(5 == 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 Erlbeckc53f2a62014-08-15 14:56:28 +02001623 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1624 foreign_tlli, 1, imsi, sizeof(imsi),
1625 GPRS_SAPI_GMM, 1,
1626 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001627
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001628 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1629
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001630 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1631 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1632 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1633
1634 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1635 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1636 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1637
1638 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1639 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1640 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1641
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001642 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1643 OSMO_ASSERT(link_info);
1644 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1645 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1646 OSMO_ASSERT(!link_info->tlli.bss_validated);
1647 OSMO_ASSERT(!link_info->tlli.net_validated);
1648 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1649 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1650 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1651 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001652
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001653 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1654 local_tlli, &rai_bss, cell_id,
1655 GPRS_SAPI_GMM, 4,
1656 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001657
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001658 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1659
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001660 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1661 OSMO_ASSERT(link_info);
1662 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1663 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1664 OSMO_ASSERT(link_info->tlli.bss_validated);
1665 OSMO_ASSERT(!link_info->tlli.net_validated);
1666 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1667 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1668 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1669 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001670
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001671 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001672 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1673 local_tlli, &rai_bss, cell_id,
1674 GPRS_SAPI_GMM, 3,
1675 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001676
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001677 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1678
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001679 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1680 OSMO_ASSERT(link_info);
1681 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1682 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1683 OSMO_ASSERT(link_info->tlli.bss_validated);
1684 OSMO_ASSERT(!link_info->tlli.net_validated);
1685 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1686 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1687 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1688 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001689
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001690 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1691 local_tlli, 1, imsi, sizeof(imsi),
1692 GPRS_SAPI_GMM, 2,
1693 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001694
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001695 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1696
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001697 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1698 OSMO_ASSERT(link_info);
1699 OSMO_ASSERT(link_info->tlli.assigned == 0);
1700 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1701 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1702 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001703
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001704 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001705 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1706 local_tlli, &rai_bss, cell_id,
1707 GPRS_SAPI_GMM, 3,
1708 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001709
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001710 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1711
Jacob Erlbeck73685282014-05-23 20:48:07 +02001712 gbcfg.core_apn[0] = 0;
1713 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001714
1715 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001716 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1717 local_tlli, &rai_bss, cell_id,
1718 GPRS_SAPI_GMM, 3,
1719 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001720
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001721 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1722
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001723 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001724
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001725 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001726 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1727 local_tlli, &rai_bss, cell_id,
1728 GPRS_SAPI_GMM, 6,
1729 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001730
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001731 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1732 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1733
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001734 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1735 local_tlli, 1, imsi, sizeof(imsi),
1736 GPRS_SAPI_GMM, 5,
1737 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001738
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001739 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001740
1741 printf("--- RA update ---\n\n");
1742
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001743 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1744 foreign_tlli, &rai_bss, 0x7080,
1745 GPRS_SAPI_GMM, 5,
1746 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001747
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001748 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1749
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001750 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1751 foreign_tlli, 1, imsi, sizeof(imsi),
1752 GPRS_SAPI_GMM, 6,
1753 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001754
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001755 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1756
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001757 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001758 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1759 local_tlli, &rai_bss, cell_id,
1760 GPRS_SAPI_GMM, 3,
1761 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001762
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001763 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1764
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001765 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001766
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001767 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001768 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1769 local_tlli, &rai_bss, cell_id,
1770 GPRS_SAPI_GMM, 6,
1771 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001772
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001773 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1774
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001775 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001776 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001777
1778 printf("--- Bad cases ---\n\n");
1779
Jacob Erlbeck991606b2014-09-12 10:33:38 +02001780 /* The RAI in the Attach Request message differs from the RAI in the
1781 * BSSGP message, only patch the latter */
1782
1783 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1784 foreign_tlli2, &rai_bss, cell_id,
1785 GPRS_SAPI_GMM, 0,
1786 dtap_attach_req2, sizeof(dtap_attach_req2));
1787
Jacob Erlbeck948c07f2014-09-11 15:22:18 +02001788 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1789
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001790 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001791 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1792 local_tlli, &rai_bss, cell_id,
1793 GPRS_SAPI_GMM, 3,
1794 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001795
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001796 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001797 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001798
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001799 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001800 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001801
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001802 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001803 gprs_ns_destroy(nsi);
1804 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001805}
1806
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001807static void test_gbproxy_ptmsi_assignment()
1808{
1809 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1810 struct sockaddr_in bss_peer[1] = {{0},};
1811 struct sockaddr_in sgsn_peer= {0};
1812 struct gprs_ra_id rai_bss =
1813 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1814 struct gprs_ra_id rai_unknown =
1815 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1816 uint16_t cell_id = 0x1234;
1817
1818 const uint32_t ptmsi = 0xefe2b700;
1819 const uint32_t local_tlli = 0xefe2b700;
1820
1821 const uint32_t foreign_tlli1 = 0x8000dead;
1822 const uint32_t foreign_tlli2 = 0x8000beef;
1823
1824 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1825 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1826
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001827 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001828 struct gbproxy_peer *peer;
1829 unsigned bss_nu = 0;
1830 unsigned sgsn_nu = 0;
1831
1832 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1833
1834 bssgp_nsi = nsi;
1835 gbcfg.nsi = bssgp_nsi;
1836 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1837 gbcfg.core_mcc = 0;
1838 gbcfg.core_mnc = 0;
1839 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1840 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1841 gbcfg.patch_ptmsi = 0;
1842 gbcfg.bss_ptmsi_state = 0;
1843 gbcfg.sgsn_tlli_state = 1;
1844
1845 configure_sgsn_peer(&sgsn_peer);
1846 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1847
1848 printf("=== %s ===\n", __func__);
1849 printf("--- Initialise SGSN ---\n\n");
1850
1851 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1852
1853 printf("--- Initialise BSS 1 ---\n\n");
1854
1855 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1856 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1857
1858 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1859 OSMO_ASSERT(peer != NULL);
1860
1861 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1862
1863 gprs_dump_nsi(nsi);
1864 dump_global(stdout, 0);
1865 dump_peers(stdout, 0, 0, &gbcfg);
1866
1867 printf("--- Establish first LLC connection ---\n\n");
1868
1869 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1870 foreign_tlli1, &rai_unknown, cell_id,
1871 GPRS_SAPI_GMM, bss_nu++,
1872 dtap_attach_req, sizeof(dtap_attach_req));
1873
1874 dump_peers(stdout, 0, 0, &gbcfg);
1875
1876 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1877 foreign_tlli1, 0, NULL, 0,
1878 GPRS_SAPI_GMM, sgsn_nu++,
1879 dtap_identity_req, sizeof(dtap_identity_req));
1880
1881 dump_peers(stdout, 0, 0, &gbcfg);
1882
1883 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1884 foreign_tlli1, &rai_bss, cell_id,
1885 GPRS_SAPI_GMM, bss_nu++,
1886 dtap_identity_resp, sizeof(dtap_identity_resp));
1887
1888 dump_peers(stdout, 0, 0, &gbcfg);
1889
1890 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1891 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1892 GPRS_SAPI_GMM, sgsn_nu++,
1893 dtap_attach_acc, sizeof(dtap_attach_acc));
1894
1895 dump_peers(stdout, 0, 0, &gbcfg);
1896
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001897 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1898 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1899 OSMO_ASSERT(link_info);
1900 OSMO_ASSERT(link_info == link_info2);
1901 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1902 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1903 OSMO_ASSERT(!link_info->tlli.bss_validated);
1904 OSMO_ASSERT(!link_info->tlli.net_validated);
1905 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001906
1907 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1908 local_tlli, &rai_bss, cell_id,
1909 GPRS_SAPI_GMM, bss_nu++,
1910 dtap_attach_complete, sizeof(dtap_attach_complete));
1911
1912 dump_peers(stdout, 0, 0, &gbcfg);
1913
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001914 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1915 OSMO_ASSERT(link_info);
1916 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1917 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1918 OSMO_ASSERT(link_info->tlli.bss_validated);
1919 OSMO_ASSERT(!link_info->tlli.net_validated);
1920 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001921
1922
1923 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1924 local_tlli, 1, imsi1, sizeof(imsi1),
1925 GPRS_SAPI_GMM, sgsn_nu++,
1926 dtap_gmm_information, sizeof(dtap_gmm_information));
1927
1928 dump_peers(stdout, 0, 0, &gbcfg);
1929
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001930 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1931 OSMO_ASSERT(link_info);
1932 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
1933 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001934
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001935 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1936 OSMO_ASSERT(link_info == link_info2);
1937 OSMO_ASSERT(link_info->tlli.assigned == 0);
1938 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1939 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001940
1941 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
1942
1943 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1944 foreign_tlli2, &rai_unknown, cell_id,
1945 GPRS_SAPI_GMM, bss_nu++,
1946 dtap_attach_req, sizeof(dtap_attach_req));
1947
1948 dump_peers(stdout, 0, 0, &gbcfg);
1949
1950 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1951 foreign_tlli2, 0, NULL, 0,
1952 GPRS_SAPI_GMM, sgsn_nu++,
1953 dtap_identity_req, sizeof(dtap_identity_req));
1954
1955 dump_peers(stdout, 0, 0, &gbcfg);
1956
1957 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1958 foreign_tlli2, &rai_bss, cell_id,
1959 GPRS_SAPI_GMM, bss_nu++,
1960 dtap_identity2_resp, sizeof(dtap_identity2_resp));
1961
1962 dump_peers(stdout, 0, 0, &gbcfg);
1963
1964 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1965 foreign_tlli2, 1, imsi2, sizeof(imsi2),
1966 GPRS_SAPI_GMM, sgsn_nu++,
1967 dtap_attach_acc, sizeof(dtap_attach_acc));
1968
1969 dump_peers(stdout, 0, 0, &gbcfg);
1970
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001971 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
1972 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1973 OSMO_ASSERT(link_info);
1974 OSMO_ASSERT(link_info == link_info2);
1975 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1976 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
1977 OSMO_ASSERT(!link_info->tlli.bss_validated);
1978 OSMO_ASSERT(!link_info->tlli.net_validated);
1979 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001980
1981 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1982 local_tlli, &rai_bss, cell_id,
1983 GPRS_SAPI_GMM, bss_nu++,
1984 dtap_attach_complete, sizeof(dtap_attach_complete));
1985
1986 dump_peers(stdout, 0, 0, &gbcfg);
1987
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02001988 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1989 OSMO_ASSERT(link_info);
1990 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1991 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
1992 OSMO_ASSERT(link_info->tlli.bss_validated);
1993 OSMO_ASSERT(!link_info->tlli.net_validated);
1994 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02001995
1996 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1997 local_tlli, 1, imsi2, sizeof(imsi2),
1998 GPRS_SAPI_GMM, sgsn_nu++,
1999 dtap_gmm_information, sizeof(dtap_gmm_information));
2000
2001 dump_peers(stdout, 0, 0, &gbcfg);
2002
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002003 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2004 OSMO_ASSERT(link_info);
2005 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2006 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002007
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002008 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2009 OSMO_ASSERT(link_info == link_info2);
2010 OSMO_ASSERT(link_info->tlli.assigned == 0);
2011 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2012 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02002013
2014 dump_global(stdout, 0);
2015
2016 gbprox_reset(&gbcfg);
2017 gprs_ns_destroy(nsi);
2018 nsi = NULL;
2019}
2020
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002021static void test_gbproxy_ptmsi_patching()
2022{
2023 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2024 struct sockaddr_in bss_peer[1] = {{0},};
2025 struct sockaddr_in sgsn_peer= {0};
2026 struct gprs_ra_id rai_bss =
2027 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2028 struct gprs_ra_id rai_sgsn =
2029 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002030 struct gprs_ra_id rai_wrong_mcc_sgsn =
2031 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002032 struct gprs_ra_id rai_unknown =
2033 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2034 uint16_t cell_id = 0x1234;
2035
2036 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002037 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2038 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002039 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002040 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2041 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002042 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002043 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002044
2045 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002046 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2047 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002048 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002049 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2050 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002051 const uint32_t foreign_bss_tlli = 0x8000dead;
2052
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002053
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002054 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002055 struct gbproxy_link_info *link_info;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002056 struct gbproxy_peer *peer;
2057 unsigned bss_nu = 0;
2058 unsigned sgsn_nu = 0;
2059
2060 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002061 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2062 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2063 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2064 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2065 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002066
2067 bssgp_nsi = nsi;
2068 gbcfg.nsi = bssgp_nsi;
2069 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2070 gbcfg.core_mcc = 123;
2071 gbcfg.core_mnc = 456;
2072 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2073 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2074 gbcfg.patch_ptmsi = 1;
2075 gbcfg.bss_ptmsi_state = 0;
2076 gbcfg.sgsn_tlli_state = 1;
2077
2078 configure_sgsn_peer(&sgsn_peer);
2079 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2080
2081 printf("=== %s ===\n", __func__);
2082 printf("--- Initialise SGSN ---\n\n");
2083
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002084 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002085
2086 printf("--- Initialise BSS 1 ---\n\n");
2087
2088 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2089 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2090
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02002091 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002092 OSMO_ASSERT(peer != NULL);
2093
2094 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2095
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002096 gprs_dump_nsi(nsi);
2097 dump_global(stdout, 0);
2098 dump_peers(stdout, 0, 0, &gbcfg);
2099
2100 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2101
2102 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2103 foreign_bss_tlli, &rai_unknown, cell_id,
2104 GPRS_SAPI_GMM, bss_nu++,
2105 dtap_attach_req, sizeof(dtap_attach_req));
2106
2107 dump_peers(stdout, 0, 0, &gbcfg);
2108
2109 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2110 random_sgsn_tlli, 0, NULL, 0,
2111 GPRS_SAPI_GMM, sgsn_nu++,
2112 dtap_identity_req, sizeof(dtap_identity_req));
2113
2114 dump_peers(stdout, 0, 0, &gbcfg);
2115
2116 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2117 foreign_bss_tlli, &rai_bss, cell_id,
2118 GPRS_SAPI_GMM, bss_nu++,
2119 dtap_identity_resp, sizeof(dtap_identity_resp));
2120
2121 dump_peers(stdout, 0, 0, &gbcfg);
2122
2123 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2124 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2125 GPRS_SAPI_GMM, sgsn_nu++,
2126 dtap_attach_acc, sizeof(dtap_attach_acc));
2127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002130 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2131 OSMO_ASSERT(link_info);
2132 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2133 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2134 OSMO_ASSERT(!link_info->tlli.bss_validated);
2135 OSMO_ASSERT(!link_info->tlli.net_validated);
2136 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2137 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2138 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2139 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2140 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2141 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002142
2143 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2144 local_bss_tlli, &rai_bss, cell_id,
2145 GPRS_SAPI_GMM, bss_nu++,
2146 dtap_attach_complete, sizeof(dtap_attach_complete));
2147
2148 dump_peers(stdout, 0, 0, &gbcfg);
2149
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002150 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2151 OSMO_ASSERT(link_info);
2152 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2153 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2154 OSMO_ASSERT(link_info->tlli.bss_validated);
2155 OSMO_ASSERT(!link_info->tlli.net_validated);
2156 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2157 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2158 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2159 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002160
2161 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2162 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2163 GPRS_SAPI_GMM, sgsn_nu++,
2164 dtap_gmm_information, sizeof(dtap_gmm_information));
2165
2166 dump_peers(stdout, 0, 0, &gbcfg);
2167
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002168 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2169 OSMO_ASSERT(link_info);
2170 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2171 OSMO_ASSERT(link_info->tlli.assigned == 0);
2172 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2173 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002174
Jacob Erlbeck82add782014-09-05 18:08:12 +02002175 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2176 local_bss_tlli, &rai_bss, cell_id,
2177 GPRS_SAPI_GMM, bss_nu++,
2178 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2179
2180 dump_peers(stdout, 0, 0, &gbcfg);
2181
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002182 /* Non-DTAP */
2183 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2184 local_bss_tlli, &rai_bss, cell_id,
2185 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2186
2187 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2188 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2189 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2190
2191 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2192 local_bss_tlli, &rai_bss, cell_id,
2193 llc_ui_ll11_dns_query_ul,
2194 sizeof(llc_ui_ll11_dns_query_ul));
2195
2196 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2197 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2198 llc_ui_ll11_dns_resp_dl,
2199 sizeof(llc_ui_ll11_dns_resp_dl));
2200
2201 dump_peers(stdout, 0, 0, &gbcfg);
2202
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002203 /* Repeated RA Update Requests */
2204 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2205 local_bss_tlli, &rai_bss, 0x7080,
2206 GPRS_SAPI_GMM, bss_nu++,
2207 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2208
2209 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2210 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2211 GPRS_SAPI_GMM, sgsn_nu++,
2212 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2213
2214 dump_peers(stdout, 0, 0, &gbcfg);
2215
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002216 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2217 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2218 OSMO_ASSERT(link_info);
2219 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2220 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2221 OSMO_ASSERT(!link_info->tlli.bss_validated);
2222 OSMO_ASSERT(!link_info->tlli.net_validated);
2223 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2224 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2225 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2226 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2227 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2228 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002229
2230 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2231 local_bss_tlli2, &rai_bss, 0x7080,
2232 GPRS_SAPI_GMM, bss_nu++,
2233 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2234
2235 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2236 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2237 GPRS_SAPI_GMM, sgsn_nu++,
2238 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2239
2240 dump_peers(stdout, 0, 0, &gbcfg);
2241
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002242 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2243 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2244 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2245 OSMO_ASSERT(link_info);
2246 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2247 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2248 OSMO_ASSERT(!link_info->tlli.bss_validated);
2249 OSMO_ASSERT(!link_info->tlli.net_validated);
2250 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2251 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2252 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2253 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2254 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2255 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002256
2257 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2258 local_bss_tlli3, &rai_bss, 0x7080,
2259 GPRS_SAPI_GMM, bss_nu++,
2260 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2261
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002262 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002263
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002264 OSMO_ASSERT(link_info);
2265 OSMO_ASSERT(link_info->tlli.bss_validated);
2266 OSMO_ASSERT(!link_info->tlli.net_validated);
2267 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2268 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002269
2270 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2271 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2272 GPRS_SAPI_GMM, sgsn_nu++,
2273 dtap_gmm_information, sizeof(dtap_gmm_information));
2274
2275 dump_peers(stdout, 0, 0, &gbcfg);
2276
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002277 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2278 OSMO_ASSERT(link_info);
2279 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2280 OSMO_ASSERT(link_info->tlli.assigned == 0);
2281 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2282 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002283
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002284 /* Other messages */
2285 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002286 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002287
2288 dump_peers(stdout, 0, 0, &gbcfg);
2289
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002290 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002291
2292 dump_peers(stdout, 0, 0, &gbcfg);
2293
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002294 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002295
2296 dump_peers(stdout, 0, 0, &gbcfg);
2297
2298 /* Bad case: Invalid BVCI */
2299 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002300 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002301 dump_global(stdout, 0);
2302
2303 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002304 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002305
2306 dump_global(stdout, 0);
2307
2308 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002309 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002310 &rai_wrong_mcc_sgsn);
2311
2312 dump_global(stdout, 0);
2313
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02002314 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2315 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2316 unknown_sgsn_tlli, 1, NULL, 0,
2317 GPRS_SAPI_GMM, 2,
2318 dtap_gmm_information, sizeof(dtap_gmm_information));
2319
2320 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2321 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2322 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2323 GPRS_SAPI_GMM, 3,
2324 dtap_gmm_information, sizeof(dtap_gmm_information));
2325
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002326 /* Detach */
2327 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002328 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002329 GPRS_SAPI_GMM, bss_nu++,
2330 dtap_detach_req, sizeof(dtap_detach_req));
2331
2332 dump_peers(stdout, 0, 0, &gbcfg);
2333
2334 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02002335 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002336 GPRS_SAPI_GMM, sgsn_nu++,
2337 dtap_detach_acc, sizeof(dtap_detach_acc));
2338
2339 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02002340
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002341 dump_global(stdout, 0);
2342
2343 gbprox_reset(&gbcfg);
2344 gprs_ns_destroy(nsi);
2345 nsi = NULL;
2346}
2347
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002348static void test_gbproxy_imsi_acquisition()
2349{
2350 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2351 struct sockaddr_in bss_peer[1] = {{0},};
2352 struct sockaddr_in sgsn_peer= {0};
2353 struct gprs_ra_id rai_bss =
2354 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2355 struct gprs_ra_id rai_sgsn =
2356 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2357 struct gprs_ra_id rai_wrong_mcc_sgsn =
2358 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2359 struct gprs_ra_id rai_unknown =
2360 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2361 uint16_t cell_id = 0x1234;
2362
2363 const uint32_t sgsn_ptmsi = 0xefe2b700;
2364 const uint32_t local_sgsn_tlli = 0xefe2b700;
2365 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002366 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002367
2368 const uint32_t bss_ptmsi = 0xc00f7304;
2369 const uint32_t local_bss_tlli = 0xc00f7304;
2370 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002371 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002372
2373 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002374 struct gbproxy_link_info *link_info;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002375 struct gbproxy_peer *peer;
2376 unsigned bss_nu = 0;
2377 unsigned sgsn_nu = 0;
2378
2379 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2380
2381 bssgp_nsi = nsi;
2382 gbcfg.nsi = bssgp_nsi;
2383 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2384 gbcfg.core_mcc = 123;
2385 gbcfg.core_mnc = 456;
2386 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2387 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2388 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002389 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002390 gbcfg.bss_ptmsi_state = 0;
2391 gbcfg.sgsn_tlli_state = 1;
2392
2393 configure_sgsn_peer(&sgsn_peer);
2394 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2395
2396 printf("=== %s ===\n", __func__);
2397 printf("--- Initialise SGSN ---\n\n");
2398
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002399 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002400
2401 printf("--- Initialise BSS 1 ---\n\n");
2402
2403 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2404 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2405
2406 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2407 OSMO_ASSERT(peer != NULL);
2408
2409 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2410
2411 gprs_dump_nsi(nsi);
2412 dump_global(stdout, 0);
2413 dump_peers(stdout, 0, 0, &gbcfg);
2414
2415 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2416
2417 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002418 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002419 GPRS_SAPI_GMM, bss_nu++,
2420 dtap_attach_req, sizeof(dtap_attach_req));
2421
2422 dump_peers(stdout, 0, 0, &gbcfg);
2423
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02002424 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2425 foreign_bss_tlli, &rai_bss, cell_id,
2426 GPRS_SAPI_GMM, bss_nu++,
2427 dtap_identity_resp, sizeof(dtap_identity_resp));
2428
2429 dump_peers(stdout, 0, 0, &gbcfg);
2430
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002431 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2432 random_sgsn_tlli, 0, NULL, 0,
2433 GPRS_SAPI_GMM, sgsn_nu++,
2434 dtap_identity_req, sizeof(dtap_identity_req));
2435
2436 dump_peers(stdout, 0, 0, &gbcfg);
2437
2438 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2439 foreign_bss_tlli, &rai_bss, cell_id,
2440 GPRS_SAPI_GMM, bss_nu++,
2441 dtap_identity_resp, sizeof(dtap_identity_resp));
2442
2443 dump_peers(stdout, 0, 0, &gbcfg);
2444
2445 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2446 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2447 GPRS_SAPI_GMM, sgsn_nu++,
2448 dtap_attach_acc, sizeof(dtap_attach_acc));
2449
2450 dump_peers(stdout, 0, 0, &gbcfg);
2451
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002452 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2453 OSMO_ASSERT(link_info);
2454 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2455 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2456 OSMO_ASSERT(!link_info->tlli.bss_validated);
2457 OSMO_ASSERT(!link_info->tlli.net_validated);
2458 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2459 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2460 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2461 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2462 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2463 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002464
2465 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2466 local_bss_tlli, &rai_bss, cell_id,
2467 GPRS_SAPI_GMM, bss_nu++,
2468 dtap_attach_complete, sizeof(dtap_attach_complete));
2469
2470 dump_peers(stdout, 0, 0, &gbcfg);
2471
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002472 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2473 OSMO_ASSERT(link_info);
2474 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2475 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2476 OSMO_ASSERT(link_info->tlli.bss_validated);
2477 OSMO_ASSERT(!link_info->tlli.net_validated);
2478 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2479 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2480 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2481 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002482
2483 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2484 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2485 GPRS_SAPI_GMM, sgsn_nu++,
2486 dtap_gmm_information, sizeof(dtap_gmm_information));
2487
2488 dump_peers(stdout, 0, 0, &gbcfg);
2489
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002490 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2491 OSMO_ASSERT(link_info);
2492 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2493 OSMO_ASSERT(link_info->tlli.assigned == 0);
2494 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2495 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002496
2497 /* Non-DTAP */
2498 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2499 local_bss_tlli, &rai_bss, cell_id,
2500 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2501
2502 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2503 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2504 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2505
2506 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2507 local_bss_tlli, &rai_bss, cell_id,
2508 llc_ui_ll11_dns_query_ul,
2509 sizeof(llc_ui_ll11_dns_query_ul));
2510
2511 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2512 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2513 llc_ui_ll11_dns_resp_dl,
2514 sizeof(llc_ui_ll11_dns_resp_dl));
2515
2516 dump_peers(stdout, 0, 0, &gbcfg);
2517
2518 /* Other messages */
2519 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2520 local_bss_tlli, 1, 12);
2521
2522 dump_peers(stdout, 0, 0, &gbcfg);
2523
2524 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2525 local_sgsn_tlli, 1, 12);
2526
2527 dump_peers(stdout, 0, 0, &gbcfg);
2528
2529 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2530
2531 dump_peers(stdout, 0, 0, &gbcfg);
2532
2533 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2534
2535 dump_peers(stdout, 0, 0, &gbcfg);
2536
2537 /* Bad case: Invalid BVCI */
2538 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2539 local_bss_tlli, 1, 12);
2540 dump_global(stdout, 0);
2541
2542 /* Bad case: Invalid RAI */
2543 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2544
2545 dump_global(stdout, 0);
2546
2547 /* Bad case: Invalid MCC (LAC ok) */
2548 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2549 &rai_wrong_mcc_sgsn);
2550
2551 dump_global(stdout, 0);
2552
2553 /* Detach */
2554 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2555 local_bss_tlli, &rai_bss, cell_id,
2556 GPRS_SAPI_GMM, bss_nu++,
2557 dtap_detach_req, sizeof(dtap_detach_req));
2558
2559 dump_peers(stdout, 0, 0, &gbcfg);
2560
2561 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2562 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2563 GPRS_SAPI_GMM, sgsn_nu++,
2564 dtap_detach_acc, sizeof(dtap_detach_acc));
2565
2566 dump_peers(stdout, 0, 0, &gbcfg);
2567
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002568 /* RA Update request */
2569
2570 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2571 foreign_bss_tlli, &rai_unknown, 0x7080,
2572 GPRS_SAPI_GMM, bss_nu++,
2573 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2574
2575 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2576 foreign_bss_tlli, &rai_bss, cell_id,
2577 GPRS_SAPI_GMM, bss_nu++,
2578 dtap_identity_resp, sizeof(dtap_identity_resp));
2579
2580 dump_peers(stdout, 0, 0, &gbcfg);
2581
2582 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2583 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2584 GPRS_SAPI_GMM, sgsn_nu++,
2585 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2586
2587 dump_peers(stdout, 0, 0, &gbcfg);
2588
2589 /* Detach */
2590
2591 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2592 local_bss_tlli, &rai_bss, cell_id,
2593 GPRS_SAPI_GMM, bss_nu++,
2594 dtap_detach_req, sizeof(dtap_detach_req));
2595
2596 dump_peers(stdout, 0, 0, &gbcfg);
2597
2598 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2599 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2600 GPRS_SAPI_GMM, sgsn_nu++,
2601 dtap_detach_acc, sizeof(dtap_detach_acc));
2602
2603 dump_peers(stdout, 0, 0, &gbcfg);
2604
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002605 /* Special case: Repeated Attach Requests */
2606
2607 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2608 foreign_bss_tlli, &rai_unknown, cell_id,
2609 GPRS_SAPI_GMM, bss_nu++,
2610 dtap_attach_req, sizeof(dtap_attach_req));
2611
2612 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2613 foreign_bss_tlli, &rai_unknown, cell_id,
2614 GPRS_SAPI_GMM, bss_nu++,
2615 dtap_attach_req, sizeof(dtap_attach_req));
2616
Jacob Erlbeck991606b2014-09-12 10:33:38 +02002617 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2618 foreign_bss_tlli, &rai_bss, cell_id,
2619 GPRS_SAPI_GMM, bss_nu++,
2620 dtap_detach_req, sizeof(dtap_detach_req));
2621
2622 dump_peers(stdout, 0, 0, &gbcfg);
2623
2624 /* Special case: Detach from an unknown TLLI */
2625
2626 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2627 other_bss_tlli, &rai_bss, cell_id,
2628 GPRS_SAPI_GMM, bss_nu++,
2629 dtap_detach_req, sizeof(dtap_detach_req));
2630
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002631 dump_peers(stdout, 0, 0, &gbcfg);
2632
Jacob Erlbeck2ec27572014-09-18 09:57:47 +02002633 /* Special case: Repeated RA Update Requests */
2634
2635 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2636 foreign_bss_tlli, &rai_unknown, 0x7080,
2637 GPRS_SAPI_GMM, bss_nu++,
2638 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2639
2640 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2641 foreign_bss_tlli, &rai_unknown, 0x7080,
2642 GPRS_SAPI_GMM, bss_nu++,
2643 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2644
2645 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2646 foreign_bss_tlli, &rai_bss, cell_id,
2647 GPRS_SAPI_GMM, bss_nu++,
2648 dtap_detach_req, sizeof(dtap_detach_req));
2649
2650 dump_peers(stdout, 0, 0, &gbcfg);
2651
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002652 dump_global(stdout, 0);
2653
2654 gbprox_reset(&gbcfg);
2655 gprs_ns_destroy(nsi);
2656 nsi = NULL;
2657}
2658
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002659static void test_gbproxy_secondary_sgsn()
2660{
2661 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2662 struct sockaddr_in bss_peer[1] = {{0},};
2663 struct sockaddr_in sgsn_peer[2]= {{0},};
2664 struct gprs_ra_id rai_bss =
2665 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2666 struct gprs_ra_id rai_sgsn =
2667 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2668 struct gprs_ra_id rai_unknown =
2669 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2670 uint16_t cell_id = 0x1234;
2671
2672 const uint32_t sgsn_ptmsi = 0xefe2b700;
2673 const uint32_t local_sgsn_tlli = 0xefe2b700;
2674 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2675
2676 const uint32_t bss_ptmsi = 0xc00f7304;
2677 const uint32_t local_bss_tlli = 0xc00f7304;
2678 const uint32_t foreign_bss_tlli = 0x8000dead;
2679
2680 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2681 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2682 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2683 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2684 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2685 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2686
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002687 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02002688 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002689 const uint32_t local_bss_tlli3 = 0xead4775a;
2690 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2691
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002692 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2693 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02002694 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002695 struct gbproxy_link_info *link_info;
2696 struct gbproxy_link_info *other_info;
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002697 struct gbproxy_peer *peer;
2698 unsigned bss_nu = 0;
2699 unsigned sgsn_nu = 0;
2700
2701 const char *err_msg = NULL;
2702 const char *filter_re = "999999";
2703
2704 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2705 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2706
2707 bssgp_nsi = nsi;
2708 gbcfg.nsi = bssgp_nsi;
2709 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2710 gbcfg.core_mcc = 123;
2711 gbcfg.core_mnc = 456;
2712 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2713 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2714 gbcfg.patch_ptmsi = 1;
2715 gbcfg.acquire_imsi = 1;
2716 gbcfg.bss_ptmsi_state = 0;
2717 gbcfg.sgsn_tlli_state = 1;
2718 gbcfg.route_to_sgsn2 = 1;
2719 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2720
2721 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2722 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2723 err_msg);
2724 OSMO_ASSERT(err_msg == NULL);
2725 }
2726
2727 configure_sgsn_peer(&sgsn_peer[0]);
2728 configure_sgsn2_peer(&sgsn_peer[1]);
2729 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2730
2731 printf("=== %s ===\n", __func__);
2732 printf("--- Initialise SGSN 1 ---\n\n");
2733
2734 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2735
2736 printf("--- Initialise SGSN 2 ---\n\n");
2737
2738 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2739
2740 printf("--- Initialise BSS 1 ---\n\n");
2741
2742 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2743 setup_bssgp(nsi, &bss_peer[0], 0x0);
2744 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2745 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2746 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2747 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2748
2749 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2750 OSMO_ASSERT(peer != NULL);
2751
2752 gprs_dump_nsi(nsi);
2753 dump_global(stdout, 0);
2754 dump_peers(stdout, 0, 0, &gbcfg);
2755
2756 printf("--- Flow control ---\n\n");
2757
2758 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2759 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2760 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2761
2762 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2763
2764 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2765 foreign_bss_tlli, &rai_unknown, cell_id,
2766 GPRS_SAPI_GMM, bss_nu++,
2767 dtap_attach_req, sizeof(dtap_attach_req));
2768
2769 dump_peers(stdout, 0, 0, &gbcfg);
2770
2771 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2772 foreign_bss_tlli, &rai_bss, cell_id,
2773 GPRS_SAPI_GMM, bss_nu++,
2774 dtap_identity_resp, sizeof(dtap_identity_resp));
2775
2776 dump_peers(stdout, 0, 0, &gbcfg);
2777
2778 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2779 random_sgsn_tlli, 0, NULL, 0,
2780 GPRS_SAPI_GMM, sgsn_nu++,
2781 dtap_identity_req, sizeof(dtap_identity_req));
2782
2783 dump_peers(stdout, 0, 0, &gbcfg);
2784
2785 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2786 foreign_bss_tlli, &rai_bss, cell_id,
2787 GPRS_SAPI_GMM, bss_nu++,
2788 dtap_identity_resp, sizeof(dtap_identity_resp));
2789
2790 dump_peers(stdout, 0, 0, &gbcfg);
2791
2792 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2793 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2794 GPRS_SAPI_GMM, sgsn_nu++,
2795 dtap_attach_acc, sizeof(dtap_attach_acc));
2796
2797 dump_peers(stdout, 0, 0, &gbcfg);
2798
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002799 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2800 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2801 OSMO_ASSERT(link_info);
2802 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2803 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2804 OSMO_ASSERT(!link_info->tlli.bss_validated);
2805 OSMO_ASSERT(!link_info->tlli.net_validated);
2806 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2807 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2808 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2809 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2810 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2811 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002812
2813 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2814 local_bss_tlli, &rai_bss, cell_id,
2815 GPRS_SAPI_GMM, bss_nu++,
2816 dtap_attach_complete, sizeof(dtap_attach_complete));
2817
2818 dump_peers(stdout, 0, 0, &gbcfg);
2819
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002820 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2821 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2822 OSMO_ASSERT(link_info);
2823 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2824 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2825 OSMO_ASSERT(link_info->tlli.bss_validated);
2826 OSMO_ASSERT(!link_info->tlli.net_validated);
2827 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2828 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2829 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2830 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002831
2832 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2833 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2834 GPRS_SAPI_GMM, sgsn_nu++,
2835 dtap_gmm_information, sizeof(dtap_gmm_information));
2836
2837 dump_peers(stdout, 0, 0, &gbcfg);
2838
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002839 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2840 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2841 OSMO_ASSERT(link_info);
2842 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2843 OSMO_ASSERT(link_info->tlli.assigned == 0);
2844 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2845 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002846
2847 /* Non-DTAP */
2848 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2849 local_bss_tlli, &rai_bss, cell_id,
2850 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2851
2852 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2853 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2854 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2855
2856 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2857 local_bss_tlli, &rai_bss, cell_id,
2858 llc_ui_ll11_dns_query_ul,
2859 sizeof(llc_ui_ll11_dns_query_ul));
2860
2861 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2862 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2863 llc_ui_ll11_dns_resp_dl,
2864 sizeof(llc_ui_ll11_dns_resp_dl));
2865
2866 dump_peers(stdout, 0, 0, &gbcfg);
2867
2868 /* Other messages */
2869 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2870 local_bss_tlli, 1, 12);
2871
2872 dump_peers(stdout, 0, 0, &gbcfg);
2873
2874 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2875 local_sgsn_tlli, 1, 12);
2876
2877 dump_peers(stdout, 0, 0, &gbcfg);
2878
2879 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2880
2881 dump_peers(stdout, 0, 0, &gbcfg);
2882
2883 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2884
2885 dump_peers(stdout, 0, 0, &gbcfg);
2886
2887 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2888
2889 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2890 foreign_bss_tlli2, &rai_unknown, cell_id,
2891 GPRS_SAPI_GMM, bss_nu++,
2892 dtap_attach_req, sizeof(dtap_attach_req));
2893
2894 dump_peers(stdout, 0, 0, &gbcfg);
2895
2896 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2897 foreign_bss_tlli2, &rai_bss, cell_id,
2898 GPRS_SAPI_GMM, bss_nu++,
2899 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2900
2901 dump_peers(stdout, 0, 0, &gbcfg);
2902
2903 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2904 random_sgsn_tlli2, 0, NULL, 0,
2905 GPRS_SAPI_GMM, sgsn_nu++,
2906 dtap_identity_req, sizeof(dtap_identity_req));
2907
2908 dump_peers(stdout, 0, 0, &gbcfg);
2909
2910 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2911 foreign_bss_tlli2, &rai_bss, cell_id,
2912 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck2bb45432014-09-17 12:05:08 +02002913 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002914
2915 dump_peers(stdout, 0, 0, &gbcfg);
2916
2917 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2918 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2919 GPRS_SAPI_GMM, sgsn_nu++,
2920 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2921
2922 dump_peers(stdout, 0, 0, &gbcfg);
2923
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002924 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2925 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2926 OSMO_ASSERT(link_info);
2927 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2928 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2929 OSMO_ASSERT(!link_info->tlli.bss_validated);
2930 OSMO_ASSERT(!link_info->tlli.net_validated);
2931 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2932 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2933 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
2934 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2935 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2936 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002937
2938 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2939 local_bss_tlli2, &rai_bss, cell_id,
2940 GPRS_SAPI_GMM, bss_nu++,
2941 dtap_attach_complete, sizeof(dtap_attach_complete));
2942
2943 dump_peers(stdout, 0, 0, &gbcfg);
2944
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002945 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2946 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
2947 OSMO_ASSERT(link_info);
2948 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2949 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2950 OSMO_ASSERT(link_info->tlli.bss_validated);
2951 OSMO_ASSERT(!link_info->tlli.net_validated);
2952 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2953 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
2954 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2955 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002956
2957 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2958 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2959 GPRS_SAPI_GMM, sgsn_nu++,
2960 dtap_gmm_information, sizeof(dtap_gmm_information));
2961
2962 dump_peers(stdout, 0, 0, &gbcfg);
2963
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02002964 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
2965 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
2966 OSMO_ASSERT(link_info);
2967 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
2968 OSMO_ASSERT(link_info->tlli.assigned == 0);
2969 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
2970 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002971
2972 /* Non-DTAP */
2973 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2974 local_bss_tlli2, &rai_bss, cell_id,
2975 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2976
2977 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2978 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2979 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2980
2981 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2982 local_bss_tlli2, &rai_bss, cell_id,
2983 llc_ui_ll11_dns_query_ul,
2984 sizeof(llc_ui_ll11_dns_query_ul));
2985
2986 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2987 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2988 llc_ui_ll11_dns_resp_dl,
2989 sizeof(llc_ui_ll11_dns_resp_dl));
2990
2991 dump_peers(stdout, 0, 0, &gbcfg);
2992
2993 /* Other messages */
2994 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2995 local_bss_tlli2, 1, 12);
2996
2997 dump_peers(stdout, 0, 0, &gbcfg);
2998
2999 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3000 local_sgsn_tlli2, 1, 12);
3001
3002 dump_peers(stdout, 0, 0, &gbcfg);
3003
3004 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3005
3006 dump_peers(stdout, 0, 0, &gbcfg);
3007
3008 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3009
3010 dump_peers(stdout, 0, 0, &gbcfg);
3011
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003012 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3013
3014 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3015 foreign_bss_tlli3, &rai_unknown, cell_id,
3016 GPRS_SAPI_GMM, bss_nu++,
3017 dtap_attach_req, sizeof(dtap_attach_req));
3018
3019 dump_peers(stdout, 0, 0, &gbcfg);
3020
3021 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3022 foreign_bss_tlli3, &rai_bss, cell_id,
3023 GPRS_SAPI_GMM, bss_nu++,
3024 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3025
3026 dump_peers(stdout, 0, 0, &gbcfg);
3027
3028 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3029 random_sgsn_tlli3, 0, NULL, 0,
3030 GPRS_SAPI_GMM, sgsn_nu++,
3031 dtap_identity_req, sizeof(dtap_identity_req));
3032
3033 dump_peers(stdout, 0, 0, &gbcfg);
3034
3035 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3036 foreign_bss_tlli3, &rai_bss, cell_id,
3037 GPRS_SAPI_GMM, bss_nu++,
3038 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3039
3040 dump_peers(stdout, 0, 0, &gbcfg);
3041
3042 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3043 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3044 GPRS_SAPI_GMM, sgsn_nu++,
3045 dtap_attach_acc, sizeof(dtap_attach_acc));
3046
3047 dump_peers(stdout, 0, 0, &gbcfg);
3048
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003049 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3050 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3051 OSMO_ASSERT(link_info);
3052 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3053 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3054 OSMO_ASSERT(!link_info->tlli.bss_validated);
3055 OSMO_ASSERT(!link_info->tlli.net_validated);
3056 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3057 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3058 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3059 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3060 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3061 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003062
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003063 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3064 local_bss_tlli3, &rai_bss, cell_id,
3065 GPRS_SAPI_GMM, bss_nu++,
3066 dtap_attach_complete, sizeof(dtap_attach_complete));
3067
3068 dump_peers(stdout, 0, 0, &gbcfg);
3069
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003070 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003071 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003072 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3073 OSMO_ASSERT(link_info);
3074 OSMO_ASSERT(link_info != other_info);
3075 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3076 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3077 OSMO_ASSERT(link_info->tlli.bss_validated);
3078 OSMO_ASSERT(!link_info->tlli.net_validated);
3079 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3080 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3081 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3082 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003083
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003084 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3085 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3086 GPRS_SAPI_GMM, sgsn_nu++,
3087 dtap_gmm_information, sizeof(dtap_gmm_information));
3088
3089 dump_peers(stdout, 0, 0, &gbcfg);
3090
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003091 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003092 OSMO_ASSERT(other_info);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003093 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3094 OSMO_ASSERT(link_info);
3095 OSMO_ASSERT(link_info != other_info);
3096 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3097 OSMO_ASSERT(link_info->tlli.assigned == 0);
3098 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3099 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck91a0e862014-09-17 10:56:38 +02003100
3101
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003102 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3103
3104 /* Detach */
3105 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3106 local_bss_tlli, &rai_bss, cell_id,
3107 GPRS_SAPI_GMM, bss_nu++,
3108 dtap_detach_req, sizeof(dtap_detach_req));
3109
3110 dump_peers(stdout, 0, 0, &gbcfg);
3111
3112 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3113 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3114 GPRS_SAPI_GMM, sgsn_nu++,
3115 dtap_detach_acc, sizeof(dtap_detach_acc));
3116
3117 dump_peers(stdout, 0, 0, &gbcfg);
3118
3119 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3120
3121 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3122 local_bss_tlli2, &rai_bss, cell_id,
3123 GPRS_SAPI_GMM, bss_nu++,
3124 dtap_detach_req, sizeof(dtap_detach_req));
3125
3126 dump_peers(stdout, 0, 0, &gbcfg);
3127
3128 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3129 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3130 GPRS_SAPI_GMM, sgsn_nu++,
3131 dtap_detach_acc, sizeof(dtap_detach_acc));
3132
3133 dump_peers(stdout, 0, 0, &gbcfg);
3134
Jacob Erlbeckaf952ba2014-09-17 12:09:25 +02003135 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3136
3137 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3138 local_bss_tlli3, &rai_bss, cell_id,
3139 GPRS_SAPI_GMM, bss_nu++,
3140 dtap_detach_req, sizeof(dtap_detach_req));
3141
3142 dump_peers(stdout, 0, 0, &gbcfg);
3143
3144 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3145 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3146 GPRS_SAPI_GMM, sgsn_nu++,
3147 dtap_detach_acc, sizeof(dtap_detach_acc));
3148
3149 dump_peers(stdout, 0, 0, &gbcfg);
3150
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003151 dump_global(stdout, 0);
3152
3153 gbprox_reset(&gbcfg);
3154 gprs_ns_destroy(nsi);
3155 nsi = NULL;
3156}
3157
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003158static void test_gbproxy_keep_info()
3159{
3160 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3161 struct sockaddr_in bss_peer[1] = {{0},};
3162 struct sockaddr_in sgsn_peer= {0};
3163 struct gprs_ra_id rai_bss =
3164 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3165 uint16_t cell_id = 0x1234;
3166
3167 const uint32_t ptmsi = 0xefe2b700;
3168 const uint32_t local_tlli = 0xefe2b700;
3169 const uint32_t foreign_tlli = 0xafe2b700;
3170
3171 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003172 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003173 struct gbproxy_peer *peer;
3174 unsigned bss_nu = 0;
3175 unsigned sgsn_nu = 0;
3176
3177 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3178
3179 bssgp_nsi = nsi;
3180 gbcfg.nsi = bssgp_nsi;
3181 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3182 gbcfg.patch_ptmsi = 0;
3183 gbcfg.acquire_imsi = 1;
3184 gbcfg.bss_ptmsi_state = 0;
3185 gbcfg.sgsn_tlli_state = 1;
3186 gbcfg.core_mcc = 0;
3187 gbcfg.core_mnc = 0;
3188 gbcfg.core_apn = NULL;
3189 gbcfg.core_apn_size = 0;
3190 gbcfg.route_to_sgsn2 = 0;
3191 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003192 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003193
3194 configure_sgsn_peer(&sgsn_peer);
3195 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3196
3197 printf("=== %s ===\n", __func__);
3198 printf("--- Initialise SGSN ---\n\n");
3199
3200 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3201
3202 printf("--- Initialise BSS 1 ---\n\n");
3203
3204 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3205 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3206
3207 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3208 OSMO_ASSERT(peer != NULL);
3209
3210 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3211
3212 gprs_dump_nsi(nsi);
3213 dump_global(stdout, 0);
3214 dump_peers(stdout, 0, 0, &gbcfg);
3215
3216 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3217
3218 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3219 foreign_tlli, &rai_bss, cell_id,
3220 GPRS_SAPI_GMM, bss_nu++,
3221 dtap_attach_req, sizeof(dtap_attach_req));
3222
3223 dump_peers(stdout, 0, 0, &gbcfg);
3224
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003225 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3226 OSMO_ASSERT(link_info);
3227 OSMO_ASSERT(link_info->imsi_len == 0);
3228 OSMO_ASSERT(!link_info->is_deregistered);
3229 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003230
3231 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3232 foreign_tlli, &rai_bss, cell_id,
3233 GPRS_SAPI_GMM, bss_nu++,
3234 dtap_identity_resp, sizeof(dtap_identity_resp));
3235
3236 dump_peers(stdout, 0, 0, &gbcfg);
3237
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003238 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3239 OSMO_ASSERT(link_info);
3240 OSMO_ASSERT(link_info->imsi_len > 0);
3241 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003242
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003243 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3244 foreign_tlli, 0, NULL, 0,
3245 GPRS_SAPI_GMM, sgsn_nu++,
3246 dtap_identity_req, sizeof(dtap_identity_req));
3247
3248 dump_peers(stdout, 0, 0, &gbcfg);
3249
3250 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3251 foreign_tlli, &rai_bss, cell_id,
3252 GPRS_SAPI_GMM, bss_nu++,
3253 dtap_identity_resp, sizeof(dtap_identity_resp));
3254
3255 dump_peers(stdout, 0, 0, &gbcfg);
3256
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003257 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3258 OSMO_ASSERT(link_info);
3259 OSMO_ASSERT(link_info->imsi_len > 0);
3260 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003261
3262 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3263 foreign_tlli, 1, imsi, sizeof(imsi),
3264 GPRS_SAPI_GMM, sgsn_nu++,
3265 dtap_attach_acc, sizeof(dtap_attach_acc));
3266
3267 dump_peers(stdout, 0, 0, &gbcfg);
3268
3269 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3270 local_tlli, &rai_bss, cell_id,
3271 GPRS_SAPI_GMM, bss_nu++,
3272 dtap_attach_complete, sizeof(dtap_attach_complete));
3273
3274 dump_peers(stdout, 0, 0, &gbcfg);
3275
3276 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3277 local_tlli, 1, imsi, sizeof(imsi),
3278 GPRS_SAPI_GMM, sgsn_nu++,
3279 dtap_gmm_information, sizeof(dtap_gmm_information));
3280
3281 dump_peers(stdout, 0, 0, &gbcfg);
3282
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003283 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3284 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003285
3286 /* Detach (MO) */
3287 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3288 local_tlli, &rai_bss, cell_id,
3289 GPRS_SAPI_GMM, bss_nu++,
3290 dtap_detach_req, sizeof(dtap_detach_req));
3291
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003292 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3293 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003294
3295 dump_peers(stdout, 0, 0, &gbcfg);
3296
3297 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3298 local_tlli, 1, imsi, sizeof(imsi),
3299 GPRS_SAPI_GMM, sgsn_nu++,
3300 dtap_detach_acc, sizeof(dtap_detach_acc));
3301
3302 dump_peers(stdout, 0, 0, &gbcfg);
3303
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003304 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3305 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3306 OSMO_ASSERT(link_info);
3307 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003308
3309 /* Re-Attach */
3310 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3311 foreign_tlli, &rai_bss, cell_id,
3312 GPRS_SAPI_GMM, bss_nu++,
3313 dtap_attach_req3, sizeof(dtap_attach_req3));
3314
3315 dump_peers(stdout, 0, 0, &gbcfg);
3316
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003317 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3318 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3319 OSMO_ASSERT(link_info);
3320 OSMO_ASSERT(link_info == link_info2);
3321 OSMO_ASSERT(link_info->imsi_len != 0);
3322 OSMO_ASSERT(!link_info->is_deregistered);
3323 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003324
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003325 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3326 foreign_tlli, 1, imsi, sizeof(imsi),
3327 GPRS_SAPI_GMM, sgsn_nu++,
3328 dtap_attach_acc, sizeof(dtap_attach_acc));
3329
3330 dump_peers(stdout, 0, 0, &gbcfg);
3331
3332 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3333 local_tlli, &rai_bss, cell_id,
3334 GPRS_SAPI_GMM, bss_nu++,
3335 dtap_attach_complete, sizeof(dtap_attach_complete));
3336
3337 dump_peers(stdout, 0, 0, &gbcfg);
3338
3339 /* Detach (MT) */
3340 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3341 local_tlli, 1, imsi, sizeof(imsi),
3342 GPRS_SAPI_GMM, sgsn_nu++,
3343 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3344
3345 dump_peers(stdout, 0, 0, &gbcfg);
3346
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003347 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3348 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003349
3350 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3351 local_tlli, &rai_bss, cell_id,
3352 GPRS_SAPI_GMM, bss_nu++,
3353 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3354
3355 dump_peers(stdout, 0, 0, &gbcfg);
3356
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003357 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3358 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3359 OSMO_ASSERT(link_info);
3360 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003361
3362 /* Re-Attach */
3363 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3364 foreign_tlli, &rai_bss, cell_id,
3365 GPRS_SAPI_GMM, bss_nu++,
3366 dtap_attach_req3, sizeof(dtap_attach_req3));
3367
3368 dump_peers(stdout, 0, 0, &gbcfg);
3369
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003370 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3371 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3372 OSMO_ASSERT(link_info);
3373 OSMO_ASSERT(link_info == link_info2);
3374 OSMO_ASSERT(link_info->imsi_len != 0);
3375 OSMO_ASSERT(!link_info->is_deregistered);
3376 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003377
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003378 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3379 foreign_tlli, 1, imsi, sizeof(imsi),
3380 GPRS_SAPI_GMM, sgsn_nu++,
3381 dtap_attach_acc, sizeof(dtap_attach_acc));
3382
3383 dump_peers(stdout, 0, 0, &gbcfg);
3384
3385 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3386 local_tlli, &rai_bss, cell_id,
3387 GPRS_SAPI_GMM, bss_nu++,
3388 dtap_attach_complete, sizeof(dtap_attach_complete));
3389
3390 dump_peers(stdout, 0, 0, &gbcfg);
3391
3392 /* Detach (MT) */
3393 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3394 local_tlli, 1, imsi, sizeof(imsi),
3395 GPRS_SAPI_GMM, sgsn_nu++,
3396 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3397
3398 dump_peers(stdout, 0, 0, &gbcfg);
3399
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003400 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3401 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003402
3403 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3404 local_tlli, &rai_bss, cell_id,
3405 GPRS_SAPI_GMM, bss_nu++,
3406 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3407
3408 dump_peers(stdout, 0, 0, &gbcfg);
3409
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003410 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3411 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3412 OSMO_ASSERT(link_info);
3413 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003414
3415 /* Re-Attach */
3416 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3417 foreign_tlli, &rai_bss, cell_id,
3418 GPRS_SAPI_GMM, bss_nu++,
3419 dtap_attach_req3, sizeof(dtap_attach_req3));
3420
3421 dump_peers(stdout, 0, 0, &gbcfg);
3422
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003423 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3424 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3425 OSMO_ASSERT(link_info);
3426 OSMO_ASSERT(link_info == link_info2);
3427 OSMO_ASSERT(link_info->imsi_len != 0);
3428 OSMO_ASSERT(!link_info->is_deregistered);
3429 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003430
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003431 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3432 foreign_tlli, 1, imsi, sizeof(imsi),
3433 GPRS_SAPI_GMM, sgsn_nu++,
3434 dtap_attach_acc, sizeof(dtap_attach_acc));
3435
3436 dump_peers(stdout, 0, 0, &gbcfg);
3437
3438 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3439 local_tlli, &rai_bss, cell_id,
3440 GPRS_SAPI_GMM, bss_nu++,
3441 dtap_attach_complete, sizeof(dtap_attach_complete));
3442
3443 dump_peers(stdout, 0, 0, &gbcfg);
3444
3445 /* RA update procedure (reject -> Detach) */
3446 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3447 local_tlli, &rai_bss, 0x7080,
3448 GPRS_SAPI_GMM, bss_nu++,
3449 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3450
3451 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3452 local_tlli, 1, imsi, sizeof(imsi),
3453 GPRS_SAPI_GMM, sgsn_nu++,
3454 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3455
3456 dump_peers(stdout, 0, 0, &gbcfg);
3457
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003458 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3459 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3460 OSMO_ASSERT(link_info);
3461 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003462
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003463 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3464 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3465 foreign_tlli, &rai_bss, cell_id,
3466 GPRS_SAPI_GMM, bss_nu++,
3467 dtap_attach_req, sizeof(dtap_attach_req));
3468
3469 dump_peers(stdout, 0, 0, &gbcfg);
3470
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003471 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3472 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3473 OSMO_ASSERT(link_info);
3474 OSMO_ASSERT(link_info != link_info2);
3475 OSMO_ASSERT(link_info->imsi_len == 0);
3476 OSMO_ASSERT(!link_info->is_deregistered);
3477 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003478
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003479 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3480 foreign_tlli, &rai_bss, cell_id,
3481 GPRS_SAPI_GMM, bss_nu++,
3482 dtap_identity_resp, sizeof(dtap_identity_resp));
3483
3484 dump_peers(stdout, 0, 0, &gbcfg);
3485
3486 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3487 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3488 OSMO_ASSERT(link_info);
3489 OSMO_ASSERT(link_info == link_info2);
3490 OSMO_ASSERT(link_info->imsi_len != 0);
3491 OSMO_ASSERT(!link_info->is_deregistered);
3492 OSMO_ASSERT(!link_info->imsi_acq_pending);
3493
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003494 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3495 foreign_tlli, 1, imsi, sizeof(imsi),
3496 GPRS_SAPI_GMM, sgsn_nu++,
3497 dtap_attach_acc, sizeof(dtap_attach_acc));
3498
3499 dump_peers(stdout, 0, 0, &gbcfg);
3500
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003501 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3502 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3503 OSMO_ASSERT(link_info);
3504 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeckea71b482014-09-22 09:28:27 +02003505 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003506
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003507 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3508 local_tlli, &rai_bss, cell_id,
3509 GPRS_SAPI_GMM, bss_nu++,
3510 dtap_attach_complete, sizeof(dtap_attach_complete));
3511
3512 dump_peers(stdout, 0, 0, &gbcfg);
3513
3514 /* Detach (MT) */
3515 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3516 local_tlli, 1, imsi, sizeof(imsi),
3517 GPRS_SAPI_GMM, sgsn_nu++,
3518 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3519
3520 dump_peers(stdout, 0, 0, &gbcfg);
3521
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003522 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3523 OSMO_ASSERT(link_info);
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003524
3525 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3526 local_tlli, &rai_bss, cell_id,
3527 GPRS_SAPI_GMM, bss_nu++,
3528 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3529
3530 dump_peers(stdout, 0, 0, &gbcfg);
3531
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003532 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3533 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3534 OSMO_ASSERT(link_info);
3535 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck7430da62014-09-12 15:09:56 +02003536
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003537 /* Attach rejected */
3538
3539 gbproxy_delete_link_infos(peer);
3540
3541 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3542 foreign_tlli, &rai_bss, cell_id,
3543 GPRS_SAPI_GMM, bss_nu++,
3544 dtap_attach_req, sizeof(dtap_attach_req));
3545
3546 dump_peers(stdout, 0, 0, &gbcfg);
3547
3548 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3549 OSMO_ASSERT(link_info);
3550 OSMO_ASSERT(link_info->imsi_len == 0);
3551 OSMO_ASSERT(!link_info->is_deregistered);
3552 OSMO_ASSERT(link_info->imsi_acq_pending);
3553
3554 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3555 foreign_tlli, &rai_bss, cell_id,
3556 GPRS_SAPI_GMM, bss_nu++,
3557 dtap_identity_resp, sizeof(dtap_identity_resp));
3558
3559 dump_peers(stdout, 0, 0, &gbcfg);
3560
3561 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3562 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3563 OSMO_ASSERT(link_info);
3564 OSMO_ASSERT(link_info == link_info2);
3565 OSMO_ASSERT(link_info->imsi_len != 0);
3566 OSMO_ASSERT(!link_info->is_deregistered);
3567 OSMO_ASSERT(!link_info->imsi_acq_pending);
3568
3569 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3570 foreign_tlli, 1, imsi, sizeof(imsi),
3571 GPRS_SAPI_GMM, sgsn_nu++,
3572 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3573
3574 dump_peers(stdout, 0, 0, &gbcfg);
3575
Jacob Erlbeck9c65c812014-09-22 10:42:05 +02003576 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3577
Jacob Erlbeck2bf32612014-09-22 11:26:58 +02003578 /* Attach (incomplete) and Detach (MO) */
3579
3580 gbproxy_delete_link_infos(peer);
3581
3582 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3583 foreign_tlli, &rai_bss, cell_id,
3584 GPRS_SAPI_GMM, bss_nu++,
3585 dtap_attach_req, sizeof(dtap_attach_req));
3586
3587 dump_peers(stdout, 0, 0, &gbcfg);
3588
3589 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3590 OSMO_ASSERT(link_info);
3591 OSMO_ASSERT(link_info->imsi_len == 0);
3592 OSMO_ASSERT(!link_info->is_deregistered);
3593 OSMO_ASSERT(link_info->imsi_acq_pending);
3594
3595 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3596 foreign_tlli, &rai_bss, cell_id,
3597 GPRS_SAPI_GMM, bss_nu++,
3598 dtap_detach_req, sizeof(dtap_detach_req));
3599
3600 dump_peers(stdout, 0, 0, &gbcfg);
3601
3602 /* Attach (incomplete) and Detach (MT) */
3603
3604 gbproxy_delete_link_infos(peer);
3605
3606 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3607 foreign_tlli, &rai_bss, cell_id,
3608 GPRS_SAPI_GMM, bss_nu++,
3609 dtap_attach_req, sizeof(dtap_attach_req));
3610
3611 dump_peers(stdout, 0, 0, &gbcfg);
3612
3613 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3614 OSMO_ASSERT(link_info);
3615 OSMO_ASSERT(link_info->imsi_len == 0);
3616 OSMO_ASSERT(!link_info->is_deregistered);
3617 OSMO_ASSERT(link_info->imsi_acq_pending);
3618
3619 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3620 foreign_tlli, 1, imsi, sizeof(imsi),
3621 GPRS_SAPI_GMM, sgsn_nu++,
3622 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3623
3624 dump_peers(stdout, 0, 0, &gbcfg);
3625
3626 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3627 OSMO_ASSERT(link_info);
3628
3629 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3630 foreign_tlli, &rai_bss, cell_id,
3631 GPRS_SAPI_GMM, bss_nu++,
3632 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3633
3634 dump_peers(stdout, 0, 0, &gbcfg);
3635
3636 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3637 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3638 OSMO_ASSERT(link_info);
3639 OSMO_ASSERT(link_info->is_deregistered);
3640
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02003641 dump_global(stdout, 0);
3642
3643 gbprox_reset(&gbcfg);
3644 gprs_ns_destroy(nsi);
3645 nsi = NULL;
3646}
3647
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003648/* TODO: Move tlv testing to libosmocore */
3649int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3650int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3651 uint8_t **value);
3652int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3653 size_t *value_len);
3654int lv_shift(uint8_t **data, size_t *data_len,
3655 uint8_t **value, size_t *value_len);
3656
3657static void check_tlv_match(uint8_t **data, size_t *data_len,
3658 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3659{
3660 uint8_t *value;
3661 size_t value_len;
3662 int rc;
3663
3664 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3665 OSMO_ASSERT(rc == 0);
3666
3667 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003668 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003669 OSMO_ASSERT(value_len == exp_len);
3670 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3671}
3672
3673static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3674 uint8_t tag, size_t len, const uint8_t *exp_val)
3675{
3676 uint8_t *value;
3677 int rc;
3678
3679 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3680 OSMO_ASSERT(rc == 0);
3681
3682 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003683 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003684 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3685}
3686
3687static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3688 size_t len, const uint8_t *exp_val)
3689{
3690 uint8_t *value;
3691 int rc;
3692
3693 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003694 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003695 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3696}
3697
3698static void check_lv_shift(uint8_t **data, size_t *data_len,
3699 size_t exp_len, const uint8_t *exp_val)
3700{
3701 uint8_t *value;
3702 size_t value_len;
3703 int rc;
3704
3705 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003706 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003707 OSMO_ASSERT(value_len == exp_len);
3708 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3709}
3710
3711static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3712 const uint8_t *test_data)
3713{
3714 uint8_t buf[300] = {0};
3715
3716 uint8_t *unchanged_ptr = buf - 1;
3717 size_t unchanged_len = 0xdead;
3718 size_t tmp_data_len = data_len;
3719 uint8_t *value = unchanged_ptr;
3720 size_t value_len = unchanged_len;
3721 uint8_t *data = buf;
3722
3723 OSMO_ASSERT(data_len <= sizeof(buf));
3724
3725 tlv_put(data, tag, len, test_data);
3726 if (data_len < len + 2) {
3727 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3728 tag, &value, &value_len));
3729 OSMO_ASSERT(tmp_data_len == 0);
3730 OSMO_ASSERT(data == buf + data_len);
3731 OSMO_ASSERT(value == unchanged_ptr);
3732 OSMO_ASSERT(value_len == unchanged_len);
3733 } else {
3734 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3735 tag, &value, &value_len));
3736 OSMO_ASSERT(value != unchanged_ptr);
3737 OSMO_ASSERT(value_len != unchanged_len);
3738 }
3739}
3740
3741static void check_tv_fixed_match_data_len(size_t data_len,
3742 uint8_t tag, size_t len,
3743 const uint8_t *test_data)
3744{
3745 uint8_t buf[300] = {0};
3746
3747 uint8_t *unchanged_ptr = buf - 1;
3748 size_t tmp_data_len = data_len;
3749 uint8_t *value = unchanged_ptr;
3750 uint8_t *data = buf;
3751
3752 OSMO_ASSERT(data_len <= sizeof(buf));
3753
3754 tv_fixed_put(data, tag, len, test_data);
3755
3756 if (data_len < len + 1) {
3757 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3758 tag, len, &value));
3759 OSMO_ASSERT(tmp_data_len == 0);
3760 OSMO_ASSERT(data == buf + data_len);
3761 OSMO_ASSERT(value == unchanged_ptr);
3762 } else {
3763 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3764 tag, len, &value));
3765 OSMO_ASSERT(value != unchanged_ptr);
3766 }
3767}
3768
3769static void check_v_fixed_shift_data_len(size_t data_len,
3770 size_t len, const uint8_t *test_data)
3771{
3772 uint8_t buf[300] = {0};
3773
3774 uint8_t *unchanged_ptr = buf - 1;
3775 size_t tmp_data_len = data_len;
3776 uint8_t *value = unchanged_ptr;
3777 uint8_t *data = buf;
3778
3779 OSMO_ASSERT(data_len <= sizeof(buf));
3780
3781 memcpy(data, test_data, len);
3782
3783 if (data_len < len) {
3784 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3785 len, &value));
3786 OSMO_ASSERT(tmp_data_len == 0);
3787 OSMO_ASSERT(data == buf + data_len);
3788 OSMO_ASSERT(value == unchanged_ptr);
3789 } else {
3790 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3791 len, &value));
3792 OSMO_ASSERT(value != unchanged_ptr);
3793 }
3794}
3795
3796static void check_lv_shift_data_len(size_t data_len,
3797 size_t len, const uint8_t *test_data)
3798{
3799 uint8_t buf[300] = {0};
3800
3801 uint8_t *unchanged_ptr = buf - 1;
3802 size_t unchanged_len = 0xdead;
3803 size_t tmp_data_len = data_len;
3804 uint8_t *value = unchanged_ptr;
3805 size_t value_len = unchanged_len;
3806 uint8_t *data = buf;
3807
3808 lv_put(data, len, test_data);
3809 if (data_len < len + 1) {
3810 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3811 &value, &value_len));
3812 OSMO_ASSERT(tmp_data_len == 0);
3813 OSMO_ASSERT(data == buf + data_len);
3814 OSMO_ASSERT(value == unchanged_ptr);
3815 OSMO_ASSERT(value_len == unchanged_len);
3816 } else {
3817 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3818 &value, &value_len));
3819 OSMO_ASSERT(value != unchanged_ptr);
3820 OSMO_ASSERT(value_len != unchanged_len);
3821 }
3822}
3823
3824static void test_tlv_shift_functions()
3825{
3826 uint8_t test_data[1024];
3827 uint8_t buf[1024];
3828 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003829 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003830 uint8_t *data;
3831 size_t data_len;
3832 const uint8_t tag = 0x1a;
3833
3834 printf("Test shift functions\n");
3835
3836 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3837 test_data[i] = (uint8_t)i;
3838
3839 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02003840 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003841
3842 memset(buf, 0xee, sizeof(buf));
3843 data_end = data = buf;
3844
3845 for (i = 0; i < iterations; i++) {
3846 data_end = tlv_put(data_end, tag, len, test_data);
3847 data_end = tv_fixed_put(data_end, tag, len, test_data);
3848 /* v_fixed_put */
3849 memcpy(data_end, test_data, len);
3850 data_end += len;
3851 data_end = lv_put(data_end, len, test_data);
3852 }
3853
3854 data_len = data_end - data;
3855 OSMO_ASSERT(data_len <= sizeof(buf));
3856
3857 for (i = 0; i < iterations; i++) {
3858 check_tlv_match(&data, &data_len, tag, len, test_data);
3859 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3860 check_v_fixed_shift(&data, &data_len, len, test_data);
3861 check_lv_shift(&data, &data_len, len, test_data);
3862 }
3863
3864 OSMO_ASSERT(data == data_end);
3865
3866 /* Test at end of data */
3867
3868 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3869 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3870 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3871 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3872
3873 /* Test invalid data_len */
3874 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3875 check_tlv_match_data_len(data_len, tag, len, test_data);
3876 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3877 check_v_fixed_shift_data_len(data_len, len, test_data);
3878 check_lv_shift_data_len(data_len, len, test_data);
3879 }
3880 }
3881}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003882
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003883struct gbproxy_link_info *register_tlli(
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003884 struct gbproxy_peer *peer, uint32_t tlli,
3885 const uint8_t *imsi, size_t imsi_len, time_t now)
3886{
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003887 struct gbproxy_link_info *link_info;
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003888 int imsi_matches = -1;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003889 int tlli_already_known = 0;
3890
3891 /* Check, whether the IMSI matches */
3892 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003893 imsi_matches = gbproxy_check_imsi(peer, imsi, imsi_len);
3894 if (imsi_matches < 0)
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003895 return NULL;
3896 }
3897
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003898 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003899
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003900 if (!link_info) {
3901 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003902
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003903 if (link_info) {
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003904 /* TLLI has changed somehow, adjust it */
3905 LOGP(DGPRS, LOGL_INFO,
3906 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003907 link_info->tlli.current, tlli);
3908 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003909 }
3910 }
3911
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003912 if (!link_info) {
3913 link_info = gbproxy_link_info_alloc(peer);
3914 link_info->tlli.current = tlli;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003915 } else {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003916 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003917 tlli_already_known = 1;
3918 }
3919
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003920 OSMO_ASSERT(link_info != NULL);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003921
3922 if (!tlli_already_known)
3923 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3924
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003925 gbproxy_attach_link_info(peer, now, link_info);
3926 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003927
Jacob Erlbeck8992f302014-09-19 13:17:55 +02003928 if (imsi_matches >= 0)
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003929 link_info->imsi_matches = imsi_matches;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003930
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003931 return link_info;
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02003932}
3933
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003934static void test_gbproxy_tlli_expire(void)
3935{
3936 struct gbproxy_config cfg = {0};
3937 struct gbproxy_peer *peer;
3938 const char *err_msg = NULL;
3939 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3940 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003941 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003942 const uint32_t tlli1 = 1234 | 0xc0000000;
3943 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02003944 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003945 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003946 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003947
3948 printf("Test TLLI info expiry\n\n");
3949
3950 gbproxy_init_config(&cfg);
3951
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003952 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003953 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3954 err_msg);
3955 OSMO_ASSERT(err_msg == NULL);
3956 }
3957
3958 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003959 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003960
3961 printf("Test TLLI replacement:\n");
3962
3963 cfg.tlli_max_len = 0;
3964 cfg.tlli_max_age = 0;
3965 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003966 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003967
3968 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003969 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003970 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003971 OSMO_ASSERT(link_info);
3972 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003973 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003974
3975 /* replace the old entry */
3976 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003977 link_info = register_tlli(peer, tlli2,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003978 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003979 OSMO_ASSERT(link_info);
3980 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02003981 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003982
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02003983 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003984
3985 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003986 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
3987 OSMO_ASSERT(link_info);
3988 OSMO_ASSERT(link_info->tlli.current == tlli2);
3989 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
3990 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003991
3992 printf("\n");
3993
3994 gbproxy_peer_free(peer);
3995 }
3996
3997 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02003998 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003999
4000 printf("Test IMSI replacement:\n");
4001
4002 cfg.tlli_max_len = 0;
4003 cfg.tlli_max_age = 0;
4004 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004005 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004006
4007 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004008 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004009 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004010 OSMO_ASSERT(link_info);
4011 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004012 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004013
4014 /* try to replace the old entry */
4015 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004016 link_info = register_tlli(peer, tlli1,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004017 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004018 OSMO_ASSERT(link_info);
4019 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004020 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004021
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004022 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004023
4024 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004025 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4026 OSMO_ASSERT(!link_info);
4027 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4028 OSMO_ASSERT(link_info);
4029 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004030
4031 printf("\n");
4032
4033 gbproxy_peer_free(peer);
4034 }
4035
4036 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004037 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004038 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004039
4040 printf("Test TLLI expiry, max_len == 1:\n");
4041
4042 cfg.tlli_max_len = 1;
4043 cfg.tlli_max_age = 0;
4044 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004045 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004046
4047 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004048 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004049 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004050
4051 /* replace the old entry */
4052 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004053 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004054 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004055
Jacob Erlbeck51fde082014-09-19 16:40:21 +02004056 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004057 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004058 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004059
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02004060 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004061
4062 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004063 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4064 OSMO_ASSERT(!link_info);
4065 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4066 OSMO_ASSERT(link_info);
4067 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004068
4069 printf("\n");
4070
4071 gbproxy_peer_free(peer);
4072 }
4073
4074 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004075 struct gbproxy_link_info *link_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02004076 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004077
4078 printf("Test TLLI expiry, max_age == 1:\n");
4079
4080 cfg.tlli_max_len = 0;
4081 cfg.tlli_max_age = 1;
4082 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004083 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004084
4085 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004086 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004087 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004088
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004089 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004090 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004091 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004092 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004093
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004094 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004095 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004096 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004097
4098 dump_peers(stdout, 2, now + 2, &cfg);
4099
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004100 /* verify that 5678 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004101 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4102 OSMO_ASSERT(!link_info);
4103 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4104 OSMO_ASSERT(link_info);
4105 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004106
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004107 printf("\n");
4108
4109 gbproxy_peer_free(peer);
4110 }
4111
4112 {
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004113 struct gbproxy_link_info *link_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004114 int num_removed;
4115
4116 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4117
4118 cfg.tlli_max_len = 0;
4119 cfg.tlli_max_age = 1;
4120 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004121 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004122
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004123 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004124 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004125 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004126
4127 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004128 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004129 now + 1);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004130 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004131
4132 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbecka42fe9f2014-09-12 14:15:02 +02004133 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004134 now + 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004135 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004136
4137 dump_peers(stdout, 2, now + 2, &cfg);
4138
4139 printf(" Remove stale TLLIs\n");
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004140 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004141 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeckf8562e32014-09-19 16:03:07 +02004142 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02004143
4144 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004145
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004146 /* verify that tlli3 has survived */
Jacob Erlbeck91d2f8a2014-09-19 15:07:27 +02004147 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4148 OSMO_ASSERT(!link_info);
4149 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4150 OSMO_ASSERT(!link_info);
4151 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4152 OSMO_ASSERT(link_info);
4153 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02004154
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004155 printf("\n");
4156
4157 gbproxy_peer_free(peer);
4158 }
4159}
4160
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004161static void test_gbproxy_imsi_matching(void)
4162{
4163 struct gbproxy_config cfg = {0};
4164 struct gbproxy_peer *peer;
4165 const char *err_msg = NULL;
4166 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4167 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4168 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4169 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4170 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4171 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4172 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4173 const char *filter_re1 = ".*";
4174 const char *filter_re2 = "^1234";
4175 const char *filter_re3 = "^4321";
4176 const char *filter_re4_bad = "^12[";
4177
4178 printf("=== Test IMSI/TMSI matching ===\n\n");
4179
4180 gbproxy_init_config(&cfg);
4181 OSMO_ASSERT(cfg.check_imsi == 0);
4182
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004183 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004184 OSMO_ASSERT(cfg.check_imsi == 1);
4185
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004186 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004187 OSMO_ASSERT(cfg.check_imsi == 1);
4188
4189 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004190 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004191 OSMO_ASSERT(err_msg != NULL);
4192 OSMO_ASSERT(cfg.check_imsi == 0);
4193
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004194 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004195 OSMO_ASSERT(cfg.check_imsi == 1);
4196
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004197 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004198 OSMO_ASSERT(cfg.check_imsi == 0);
4199
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004200 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004201 OSMO_ASSERT(cfg.check_imsi == 1);
4202
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004203 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02004204 OSMO_ASSERT(cfg.check_imsi == 0);
4205
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004206 peer = gbproxy_peer_alloc(&cfg, 20);
4207
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004208 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004209 OSMO_ASSERT(cfg.check_imsi == 1);
4210
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004211 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
4212 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004213 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004214 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004215 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004216 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4217 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4218 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4219 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
4220 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004221
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004222 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004223 OSMO_ASSERT(cfg.check_imsi == 1);
4224
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02004225 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
4226 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
4227 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4228 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4229 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4230 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
4231 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004232
4233 /* TODO: Check correct length but wrong type with is_mi_tmsi */
4234
4235 gbproxy_peer_free(peer);
4236}
4237
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004238static struct log_info_cat gprs_categories[] = {
4239 [DGPRS] = {
4240 .name = "DGPRS",
4241 .description = "GPRS Packet Service",
4242 .enabled = 1, .loglevel = LOGL_DEBUG,
4243 },
4244 [DNS] = {
4245 .name = "DNS",
4246 .description = "GPRS Network Service (NS)",
4247 .enabled = 1, .loglevel = LOGL_INFO,
4248 },
4249 [DBSSGP] = {
4250 .name = "DBSSGP",
4251 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4252 .enabled = 1, .loglevel = LOGL_DEBUG,
4253 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004254};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004255
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004256static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004257 .cat = gprs_categories,
4258 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02004259};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004260
4261int main(int argc, char **argv)
4262{
4263 osmo_init_logging(&info);
4264 log_set_use_color(osmo_stderr_target, 0);
4265 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02004266 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004267
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004268 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02004269 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4270 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004271
4272 rate_ctr_init(NULL);
4273
4274 setlinebuf(stdout);
4275
4276 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02004277 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02004278 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004279 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004280 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02004281 test_gbproxy_imsi_matching();
Jacob Erlbeck04f679b2014-09-18 09:21:20 +02004282 test_gbproxy_ptmsi_assignment();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02004283 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02004284 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02004285 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02004286 test_gbproxy_secondary_sgsn();
Jacob Erlbeck772a22b2014-09-15 14:18:09 +02004287 test_gbproxy_keep_info();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02004288 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02004289 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02004290
4291 exit(EXIT_SUCCESS);
4292}