blob: 9d5b849696d5489f5abb68cc18ec2aeb5a430e55 [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 Erlbeck7fb42db2014-07-07 10:46:01 +020036#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020037
38#define REMOTE_BSS_ADDR 0x01020304
39#define REMOTE_SGSN_ADDR 0x05060708
40
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020041#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020042
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020043#define REMOTE_SGSN2_ADDR 0x15161718
44#define SGSN2_NSEI 0x0102
45
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020046struct gbproxy_config gbcfg = {0};
47
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020048static int dump_global(FILE *stream, int indent)
49{
50 unsigned int i;
51 const struct rate_ctr_group_desc *desc;
52 int rc;
53
54 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
55 if (rc < 0)
56 return rc;
57
58 desc = gbcfg.ctrg->desc;
59
60 for (i = 0; i < desc->num_ctr; i++) {
61 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
62 if (ctr->current) {
63 rc = fprintf(stream, "%*s %s: %llu\n",
64 indent, "",
65 desc->ctr_desc[i].description,
66 (long long)ctr->current);
67
68 if (rc < 0)
69 return rc;
70 }
71 }
72
73 return 0;
74}
75
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020076static int dump_peers(FILE *stream, int indent, time_t now,
77 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020078{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020079 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020080 struct gprs_ra_id raid;
81 unsigned int i;
82 const struct rate_ctr_group_desc *desc;
83 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084
85 rc = fprintf(stream, "%*sPeers:\n", indent, "");
86 if (rc < 0)
87 return rc;
88
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020089 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020090 struct gbproxy_tlli_info *tlli_info;
91 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020092 gsm48_parse_ra(&raid, peer->ra);
93
94 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
95 "RAI %u-%u-%u-%u\n",
96 indent, "",
97 peer->nsei, peer->bvci,
98 peer->blocked ? "" : "not ",
99 raid.mcc, raid.mnc, raid.lac, raid.rac);
100
101 if (rc < 0)
102 return rc;
103
104 desc = peer->ctrg->desc;
105
106 for (i = 0; i < desc->num_ctr; i++) {
107 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
108 if (ctr->current) {
109 rc = fprintf(stream, "%*s %s: %llu\n",
110 indent, "",
111 desc->ctr_desc[i].description,
112 (long long)ctr->current);
113
114 if (rc < 0)
115 return rc;
116 }
117 }
118
119 fprintf(stream, "%*s TLLI-Cache: %d\n",
120 indent, "", state->enabled_tllis_count);
121 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
122 char mi_buf[200];
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200123 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200124 if (tlli_info->mi_data_len > 0) {
125 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
126 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
127 tlli_info->mi_data,
128 tlli_info->mi_data_len);
129 } else {
130 snprintf(mi_buf, sizeof(mi_buf), "(none)");
131 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200132 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200133 indent, "", tlli_info->tlli.current);
134 if (tlli_info->tlli.assigned)
135 fprintf(stream, "/%08x", tlli_info->tlli.assigned);
136 if (tlli_info->sgsn_tlli.current) {
137 fprintf(stream, " -> %08x",
138 tlli_info->sgsn_tlli.current);
139 if (tlli_info->sgsn_tlli.assigned)
140 fprintf(stream, "/%08x",
141 tlli_info->sgsn_tlli.assigned);
142 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200143 fprintf(stream, ", IMSI %s, AGE %d",
144 mi_buf, (int)age);
145
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200146 if (cfg->check_imsi && tlli_info->enable_patching)
147 fprintf(stream, ", IMSI matches");
148
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200149 if (tlli_info->imsi_acq_pending)
150 fprintf(stream, ", IMSI acquisition in progress");
151
152 if (!llist_empty(&tlli_info->stored_msgs))
153 fprintf(stream, ", stored messages");
154
155 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200156 if (rc < 0)
157 return rc;
158 }
159 }
160
161 return 0;
162}
163
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200164/* DTAP - Attach Request */
165static const unsigned char dtap_attach_req[] = {
166 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
167 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
168 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
169 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
170 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
171 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200172};
173
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200174/* DTAP - Identity Request */
175static const unsigned char dtap_identity_req[] = {
176 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200177};
178
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200179/* DTAP - Identity Response */
180static const unsigned char dtap_identity_resp[] = {
181 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
182 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200183};
184
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200185/* DTAP - Identity Response, IMSI 2 */
186static const unsigned char dtap_identity2_resp[] = {
187 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
188 0x16, 0x17, 0x18
189};
190
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200191/* DTAP - Attach Accept */
192static const unsigned char dtap_attach_acc[] = {
193 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
194 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
195 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200196};
197
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200198/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200199static const unsigned char dtap_attach_acc2[] = {
200 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
201 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
202 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
203};
204
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200205/* DTAP - Attach Complete */
206static const unsigned char dtap_attach_complete[] = {
207 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200208};
209
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200210/* DTAP - GMM Information */
211static const unsigned char dtap_gmm_information[] = {
212 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200213};
214
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200215/* DTAP - Routing Area Update Request */
216static const unsigned char dtap_ra_upd_req[] = {
217 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
218 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
219 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
220 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
221 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
222 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
223 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200224};
225
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200226/* DTAP - Routing Area Update Accept */
227static const unsigned char dtap_ra_upd_acc[] = {
228 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
229 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
230 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200231};
232
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200233/* DTAP - Routing Area Update Accept, P-TMSI 2 */
234static const unsigned char dtap_ra_upd_acc2[] = {
235 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
236 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
237 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
238};
239
240/* DTAP - Routing Area Update Accept, P-TMSI 3 */
241static const unsigned char dtap_ra_upd_acc3[] = {
242 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
243 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
244 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
245};
246
247/* DTAP - Routing Area Update Complete */
248static const unsigned char dtap_ra_upd_complete[] = {
249 0x08, 0x0a
250};
251
252
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200253/* DTAP - Activate PDP Context Request */
254static const unsigned char dtap_act_pdp_ctx_req[] = {
255 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200256 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
258 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
259 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
260 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200261 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200262};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200263
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200264/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200265/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200266static const unsigned char dtap_detach_po_req[] = {
267 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
268 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200269};
270
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200271/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200272/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200273static const unsigned char dtap_detach_req[] = {
274 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
275 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200276};
277
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200278/* DTAP - Detach Accept */
279static const unsigned char dtap_detach_acc[] = {
280 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200281};
282
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200283/* GPRS-LLC - SAPI: LLGMM, U, XID */
284static const unsigned char llc_u_xid_ul[] = {
285 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
286 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
287};
288
289/* GPRS-LLC - SAPI: LLGMM, U, XID */
290static const unsigned char llc_u_xid_dl[] = {
291 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
292 0xe4, 0xa9, 0x1a, 0x9e
293};
294
295/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
296static const unsigned char llc_ui_ll11_dns_query_ul[] = {
297 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
298 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
299 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
300 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
301 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
302 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
303 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
304 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
305 0x8f, 0x07
306};
307
308/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
309static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
310 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
311 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
312 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
313 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
314 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
315 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
316 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
317 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
318 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
319 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
320 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
321 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
322 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
323 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
324 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
325 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
326 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
327 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
328 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
329 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
330 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
331 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
332 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
333 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
334 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
335 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
336};
337
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200338static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
339 struct sockaddr_in *peer, const unsigned char* data,
340 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200341
342static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
343 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
344{
345 /* GPRS Network Service, PDU type: NS_RESET,
346 */
347 unsigned char msg[12] = {
348 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
349 0x04, 0x82, 0x11, 0x22
350 };
351
352 msg[3] = cause;
353 msg[6] = nsvci / 256;
354 msg[7] = nsvci % 256;
355 msg[10] = nsei / 256;
356 msg[11] = nsei % 256;
357
358 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
359}
360
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200361static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
362 uint16_t nsvci, uint16_t nsei)
363{
364 /* GPRS Network Service, PDU type: NS_RESET_ACK,
365 */
366 unsigned char msg[9] = {
367 0x03, 0x01, 0x82, 0x11, 0x22,
368 0x04, 0x82, 0x11, 0x22
369 };
370
371 msg[3] = nsvci / 256;
372 msg[4] = nsvci % 256;
373 msg[7] = nsei / 256;
374 msg[8] = nsei % 256;
375
376 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
377}
378
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200379static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
380{
381 /* GPRS Network Service, PDU type: NS_ALIVE */
382 unsigned char msg[1] = {
383 0x0a
384 };
385
386 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
387}
388
389static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
390{
391 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
392 unsigned char msg[1] = {
393 0x0b
394 };
395
396 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
397}
398
399static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
400{
401 /* GPRS Network Service, PDU type: NS_UNBLOCK */
402 unsigned char msg[1] = {
403 0x06
404 };
405
406 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
407}
408
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200409static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
410{
411 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
412 unsigned char msg[1] = {
413 0x07
414 };
415
416 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
417}
418
419static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
420 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200421 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
422{
423 /* GPRS Network Service, PDU type: NS_UNITDATA */
424 unsigned char msg[4096] = {
425 0x00, 0x00, 0x00, 0x00
426 };
427
428 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
429
430 msg[2] = nsbvci / 256;
431 msg[3] = nsbvci % 256;
432 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
433
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200434 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200435}
436
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200437static void send_bssgp_ul_unitdata(
438 struct gprs_ns_inst *nsi, const char *text,
439 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
440 struct gprs_ra_id *raid, uint16_t cell_id,
441 const uint8_t *llc_msg, size_t llc_msg_size)
442{
443 /* GPRS Network Service, PDU type: NS_UNITDATA */
444 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
445 unsigned char msg[4096] = {
446 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
447 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
448 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
449 };
450
451 size_t bssgp_msg_size = 23 + llc_msg_size;
452
453 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
454
455 gsm48_construct_ra(msg + 10, raid);
456 msg[1] = (uint8_t)(tlli >> 24);
457 msg[2] = (uint8_t)(tlli >> 16);
458 msg[3] = (uint8_t)(tlli >> 8);
459 msg[4] = (uint8_t)(tlli >> 0);
460 msg[16] = cell_id / 256;
461 msg[17] = cell_id % 256;
462 msg[21] = llc_msg_size / 256;
463 msg[22] = llc_msg_size % 256;
464 memcpy(msg + 23, llc_msg, llc_msg_size);
465
466 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
467 src_addr, nsbvci, msg, bssgp_msg_size);
468}
469
470static void send_bssgp_dl_unitdata(
471 struct gprs_ns_inst *nsi, const char *text,
472 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
473 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
474 const uint8_t *llc_msg, size_t llc_msg_size)
475{
476 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
477 unsigned char msg[4096] = {
478 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
479 0x16, 0x82, 0x02, 0x58,
480 };
481 unsigned char racap_drx[] = {
482 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
483 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
484 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
485 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
486 };
487
488 size_t bssgp_msg_size = 0;
489
490 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
491
492 msg[1] = (uint8_t)(tlli >> 24);
493 msg[2] = (uint8_t)(tlli >> 16);
494 msg[3] = (uint8_t)(tlli >> 8);
495 msg[4] = (uint8_t)(tlli >> 0);
496
497 bssgp_msg_size = 12;
498
499 if (with_racap_drx) {
500 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
501 bssgp_msg_size += sizeof(racap_drx);
502 }
503
504 if (imsi) {
505 OSMO_ASSERT(imsi_size <= 127);
506 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
507 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
508 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
509 bssgp_msg_size += 2 + imsi_size;
510 }
511
512 if ((bssgp_msg_size % 4) != 0) {
513 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
514 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
515 msg[bssgp_msg_size + 1] = 0x80 | abytes;
516 memset(msg + bssgp_msg_size + 2, 0, abytes);
517 bssgp_msg_size += 2 + abytes;
518 }
519
520 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
521 if (llc_msg_size < 128) {
522 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
523 bssgp_msg_size += 2;
524 } else {
525 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
526 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
527 bssgp_msg_size += 3;
528 }
529 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
530 bssgp_msg_size += llc_msg_size;
531
532
533 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
534 src_addr, nsbvci, msg, bssgp_msg_size);
535}
536
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200537static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
538 uint16_t bvci)
539{
540 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
541 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200542 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200543 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200544 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
545 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200546 };
547
548 msg[3] = bvci / 256;
549 msg[4] = bvci % 256;
550
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200551 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
552}
553
554static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
555 struct sockaddr_in *src_addr, uint16_t bvci)
556{
557 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
558 * BSSGP RESET_ACK */
559 static unsigned char msg[5] = {
560 0x23, 0x04, 0x82, 0x00,
561 0x00
562 };
563
564 msg[3] = bvci / 256;
565 msg[4] = bvci % 256;
566
567 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200568}
569
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200570static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
571 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200572 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200573 struct gprs_ra_id *raid)
574{
575 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
576 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200577 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
578 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200579 };
580
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200581 msg[3] = (uint8_t)(tlli >> 24);
582 msg[4] = (uint8_t)(tlli >> 16);
583 msg[5] = (uint8_t)(tlli >> 8);
584 msg[6] = (uint8_t)(tlli >> 0);
585
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200586 gsm48_construct_ra(msg + 9, raid);
587
588 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
589}
590
591static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
592 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200593 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200594 struct gprs_ra_id *raid)
595{
596 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
597 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200598 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
599 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200600 0x81, 0x01
601 };
602
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200603 msg[3] = (uint8_t)(tlli >> 24);
604 msg[4] = (uint8_t)(tlli >> 16);
605 msg[5] = (uint8_t)(tlli >> 8);
606 msg[6] = (uint8_t)(tlli >> 0);
607
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200608 gsm48_construct_ra(msg + 9, raid);
609
610 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
611}
612
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200613static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
614 struct sockaddr_in *src_addr,
615 uint16_t bvci, uint32_t tlli,
616 unsigned n_frames, unsigned n_octets)
617{
618 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
619 unsigned char msg[] = {
620 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
621 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
622 /* n octets */ 0xff, 0xff, 0xff
623 };
624
625 msg[3] = (uint8_t)(tlli >> 24);
626 msg[4] = (uint8_t)(tlli >> 16);
627 msg[5] = (uint8_t)(tlli >> 8);
628 msg[6] = (uint8_t)(tlli >> 0);
629 msg[9] = (uint8_t)(n_frames);
630 msg[12] = (uint8_t)(bvci >> 8);
631 msg[13] = (uint8_t)(bvci >> 0);
632 msg[16] = (uint8_t)(n_octets >> 16);
633 msg[17] = (uint8_t)(n_octets >> 8);
634 msg[18] = (uint8_t)(n_octets >> 0);
635
636 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
637}
638
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200639static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
640 struct sockaddr_in *src_addr,
641 uint16_t bvci, uint8_t tag)
642{
643 /* GPRS Network Service, PDU type: NS_UNITDATA,
644 * BSSGP FLOW_CONTROL_BVC */
645 unsigned char msg[] = {
646 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
647 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
648 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
649 };
650
651 msg[3] = tag;
652
653 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
654 msg, sizeof(msg));
655}
656
657static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
658 struct sockaddr_in *src_addr,
659 uint16_t bvci, uint8_t tag)
660{
661 /* GPRS Network Service, PDU type: NS_UNITDATA,
662 * BSSGP FLOW_CONTROL_BVC_ACK */
663 unsigned char msg[] = {
664 0x27, 0x1e, 0x81, /* Tag */ 0xce
665 };
666
667 msg[3] = tag;
668
669 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
670 msg, sizeof(msg));
671}
672
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200673static void send_llc_ul_ui(
674 struct gprs_ns_inst *nsi, const char *text,
675 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
676 struct gprs_ra_id *raid, uint16_t cell_id,
677 unsigned sapi, unsigned nu,
678 const uint8_t *msg, size_t msg_size)
679{
680 unsigned char llc_msg[4096] = {
681 0x00, 0xc0, 0x01
682 };
683
684 size_t llc_msg_size = 3 + msg_size + 3;
685 uint8_t e_bit = 0;
686 uint8_t pm_bit = 1;
687 unsigned fcs;
688
689 nu &= 0x01ff;
690
691 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
692
693 llc_msg[0] = (sapi & 0x0f);
694 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
695 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
696
697 memcpy(llc_msg + 3, msg, msg_size);
698
699 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
700 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
701 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
702 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
703
704 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
705 src_addr, nsbvci, tlli, raid, cell_id,
706 llc_msg, llc_msg_size);
707}
708
709static void send_llc_dl_ui(
710 struct gprs_ns_inst *nsi, const char *text,
711 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
712 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
713 unsigned sapi, unsigned nu,
714 const uint8_t *msg, size_t msg_size)
715{
716 /* GPRS Network Service, PDU type: NS_UNITDATA */
717 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
718 unsigned char llc_msg[4096] = {
719 0x00, 0x00, 0x01
720 };
721
722 size_t llc_msg_size = 3 + msg_size + 3;
723 uint8_t e_bit = 0;
724 uint8_t pm_bit = 1;
725 unsigned fcs;
726
727 nu &= 0x01ff;
728
729 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
730
731 llc_msg[0] = 0x40 | (sapi & 0x0f);
732 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
733 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
734
735 memcpy(llc_msg + 3, msg, msg_size);
736
737 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
738 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
739 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
740 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
741
742 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
743 src_addr, nsbvci, tlli,
744 with_racap_drx, imsi, imsi_size,
745 llc_msg, llc_msg_size);
746}
747
748
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200749static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
750 uint16_t nsvci, uint16_t nsei)
751{
752 printf("Setup NS-VC: remote 0x%08x:%d, "
753 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
754 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
755 nsvci, nsvci, nsei, nsei);
756
757 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
758 send_ns_alive(nsi, src_addr);
759 send_ns_unblock(nsi, src_addr);
760 send_ns_alive_ack(nsi, src_addr);
761}
762
763static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
764 uint16_t bvci)
765{
766 printf("Setup BSSGP: remote 0x%08x:%d, "
767 "BVCI 0x%04x(%d)\n\n",
768 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
769 bvci, bvci);
770
771 send_bssgp_reset(nsi, src_addr, bvci);
772}
773
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200774static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
775 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200776{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200777 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
778 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200779 send_ns_alive_ack(nsi, sgsn_peer);
780 send_ns_unblock_ack(nsi, sgsn_peer);
781 send_ns_alive(nsi, sgsn_peer);
782}
783
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200784static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
785{
786 sgsn_peer->sin_family = AF_INET;
787 sgsn_peer->sin_port = htons(32000);
788 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
789}
790
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200791static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
792{
793 sgsn_peer->sin_family = AF_INET;
794 sgsn_peer->sin_port = htons(32001);
795 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
796}
797
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200798static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
799{
800 size_t i;
801
802 for (i = 0; i < size; ++i) {
803 bss_peers[i].sin_family = AF_INET;
804 bss_peers[i].sin_port = htons((i + 1) * 1111);
805 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
806 }
807}
808
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200809int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
810 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
811
812/* override */
813int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
814 struct msgb *msg, uint16_t bvci)
815{
816 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
817 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200818 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200819
820 switch (event) {
821 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200822 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200823 default:
824 break;
825 }
826 return 0;
827}
828
829/* override */
830ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
831 const struct sockaddr *dest_addr, socklen_t addrlen)
832{
833 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
834 const struct sockaddr *, socklen_t);
835 static sendto_t real_sendto = NULL;
836 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200837 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200838
839 if (!real_sendto)
840 real_sendto = dlsym(RTLD_NEXT, "sendto");
841
842 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200843 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
844 dest_host, dest_port,
845 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200846 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200847 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
848 dest_host, dest_port,
849 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200850 else if (dest_host == REMOTE_SGSN2_ADDR)
851 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
852 dest_host, dest_port,
853 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200854 else
855 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
856
857 return len;
858}
859
860/* override */
861int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
862{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200863 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
864 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200865 uint16_t bvci = msgb_bvci(msg);
866 uint16_t nsei = msgb_nsei(msg);
867
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200868 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200869
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200870 if (!real_gprs_ns_sendmsg)
871 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
872
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200873 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200874 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
875 "msg length %d (%s)\n",
876 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200877 else if (nsei == SGSN2_NSEI)
878 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
879 "msg length %d (%s)\n",
880 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200881 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200882 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
883 "msg length %d (%s)\n",
884 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200885
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200886 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200887}
888
889static void dump_rate_ctr_group(FILE *stream, const char *prefix,
890 struct rate_ctr_group *ctrg)
891{
892 unsigned int i;
893
894 for (i = 0; i < ctrg->desc->num_ctr; i++) {
895 struct rate_ctr *ctr = &ctrg->ctr[i];
896 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
897 fprintf(stream, " %s%s: %llu%s",
898 prefix, ctrg->desc->ctr_desc[i].description,
899 (long long)ctr->current,
900 "\n");
901 };
902}
903
904/* Signal handler for signals from NS layer */
905static int test_signal(unsigned int subsys, unsigned int signal,
906 void *handler_data, void *signal_data)
907{
908 struct ns_signal_data *nssd = signal_data;
909 int rc;
910
911 if (subsys != SS_L_NS)
912 return 0;
913
914 switch (signal) {
915 case S_NS_RESET:
916 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
917 nssd->nsvc->nsvci,
918 gprs_ns_ll_str(nssd->nsvc));
919 break;
920
921 case S_NS_ALIVE_EXP:
922 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
923 nssd->nsvc->nsvci,
924 gprs_ns_ll_str(nssd->nsvc));
925 break;
926
927 case S_NS_BLOCK:
928 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
929 nssd->nsvc->nsvci,
930 gprs_ns_ll_str(nssd->nsvc));
931 break;
932
933 case S_NS_UNBLOCK:
934 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
935 nssd->nsvc->nsvci,
936 gprs_ns_ll_str(nssd->nsvc));
937 break;
938
939 case S_NS_REPLACED:
940 printf("==> got signal NS_REPLACED: 0x%04x/%s",
941 nssd->nsvc->nsvci,
942 gprs_ns_ll_str(nssd->nsvc));
943 printf(" -> 0x%04x/%s\n",
944 nssd->old_nsvc->nsvci,
945 gprs_ns_ll_str(nssd->old_nsvc));
946 break;
947
948 default:
949 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
950 nssd->nsvc->nsvci,
951 gprs_ns_ll_str(nssd->nsvc));
952 break;
953 }
954 printf("\n");
955 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
956 return rc;
957}
958
959static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
960{
961 struct msgb *msg;
962 int ret;
963 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
964 fprintf(stderr, "message too long: %d\n", data_len);
965 return -1;
966 }
967
968 msg = gprs_ns_msgb_alloc();
969 memmove(msg->data, data, data_len);
970 msg->l2h = msg->data;
971 msgb_put(msg, data_len);
972
973 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
974 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
975 osmo_hexdump(data, data_len));
976
977 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
978
979 printf("result (%s) = %d\n\n", text, ret);
980
981 msgb_free(msg);
982
983 return ret;
984}
985
986static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
987{
988 struct gprs_nsvc *nsvc;
989
990 printf("Current NS-VCIs:\n");
991 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
992 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200993 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200994 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200995 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
996 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
997 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200998 );
999 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1000 }
1001 printf("\n");
1002}
1003
1004static void test_gbproxy()
1005{
1006 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1007 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001008 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001009
1010 bssgp_nsi = nsi;
1011 gbcfg.nsi = bssgp_nsi;
1012 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1013
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001014 configure_sgsn_peer(&sgsn_peer);
1015 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001016
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001017 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001018 printf("--- Initialise SGSN ---\n\n");
1019
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001020 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001021 gprs_dump_nsi(nsi);
1022
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001023 printf("--- Initialise BSS 1 ---\n\n");
1024
1025 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1026 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1027 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001028 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001029
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001030 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1031
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001032 printf("--- Initialise BSS 2 ---\n\n");
1033
1034 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1035 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1036 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001037 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001038
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001039 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1040
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001041 printf("--- Move BSS 1 to new port ---\n\n");
1042
1043 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1044 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001045 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001046
1047 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1048
1049 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1050 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001051 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001052
1053 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1054
1055 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1056 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001057 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001058
1059 printf("--- Move BSS 2 to new port ---\n\n");
1060
1061 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1062 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001063 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001064
1065 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1066
1067 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1068 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001069 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001070
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001071 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1072
1073 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1074 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001075 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001076
1077 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1078
1079 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1080 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001081 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001082
1083 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1084
1085 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1086
1087 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1088 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001089 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001090
1091 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1092
1093 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1094
1095 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1096 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001097 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001098
1099 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1100
1101 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1102
1103 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1104
1105 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1106
1107 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1108
1109 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1110
1111 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1112
1113 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1114
1115 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1116
1117 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1118
1119 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1120
1121 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1122
1123 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1124
1125 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1126
1127 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1128 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001129 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001130
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001131 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001132
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001133 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1134
1135 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1136
1137 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1138
1139 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1140
1141 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1142
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001143 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1144
1145 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1146
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001147 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001148
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001149 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001150 gprs_ns_destroy(nsi);
1151 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001152}
1153
1154static void test_gbproxy_ident_changes()
1155{
1156 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1157 struct sockaddr_in bss_peer[1] = {{0},};
1158 struct sockaddr_in sgsn_peer= {0};
1159 uint16_t nsei[2] = {0x1000, 0x2000};
1160 uint16_t nsvci[2] = {0x1001, 0x2001};
1161 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1162
1163 bssgp_nsi = nsi;
1164 gbcfg.nsi = bssgp_nsi;
1165 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1166
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001167 configure_sgsn_peer(&sgsn_peer);
1168 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001169
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001170 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001171 printf("--- Initialise SGSN ---\n\n");
1172
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001173 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001174 gprs_dump_nsi(nsi);
1175
1176 printf("--- Initialise BSS 1 ---\n\n");
1177
1178 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1179 gprs_dump_nsi(nsi);
1180
1181 printf("--- Setup BVCI 1 ---\n\n");
1182
1183 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1184 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001185 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001186
1187 printf("--- Setup BVCI 2 ---\n\n");
1188
1189 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1190 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001191 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001192
1193 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1194
1195 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1196 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1197
1198 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1199
1200 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1201 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1202
1203 printf("--- Change NSEI ---\n\n");
1204
1205 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1206 gprs_dump_nsi(nsi);
1207
1208 printf("--- Setup BVCI 1 ---\n\n");
1209
1210 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1211 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001212 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001213
1214 printf("--- Setup BVCI 3 ---\n\n");
1215
1216 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1217 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001218 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001219
1220 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1221
1222 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1223 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1224
1225 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1226 " (should fail) ---\n\n");
1227
1228 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001229 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001230 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001231 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001232
1233 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1234
1235 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1236 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1237
1238 printf("--- Change NSVCI ---\n\n");
1239
1240 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1241 gprs_dump_nsi(nsi);
1242
1243 printf("--- Setup BVCI 1 ---\n\n");
1244
1245 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1246 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001247 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001248
1249 printf("--- Setup BVCI 4 ---\n\n");
1250
1251 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1252 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001253 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001254
1255 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1256
1257 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1258 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1259
1260 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1261 " (should fail) ---\n\n");
1262
1263 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001264 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001265 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001266 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001267
1268 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1269
1270 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1271 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1272
1273 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1274
1275 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1276 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1277
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001278 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001279 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001280
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001281 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001282 gprs_ns_destroy(nsi);
1283 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001284}
1285
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001286static void test_gbproxy_ra_patching()
1287{
1288 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1289 struct sockaddr_in bss_peer[1] = {{0},};
1290 struct sockaddr_in sgsn_peer= {0};
1291 struct gprs_ra_id rai_bss =
1292 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1293 struct gprs_ra_id rai_sgsn =
1294 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1295 struct gprs_ra_id rai_unknown =
1296 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001297 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001298 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001299 const uint32_t ptmsi = 0xefe2b700;
1300 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001301 const uint32_t foreign_tlli = 0xbbc54679;
1302 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001303 struct gbproxy_tlli_info *tlli_info;
1304 struct gbproxy_peer *peer;
1305
1306 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001307
1308 bssgp_nsi = nsi;
1309 gbcfg.nsi = bssgp_nsi;
1310 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001311 gbcfg.core_mcc = 123;
1312 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001313 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001314 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001315 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001316
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001317 configure_sgsn_peer(&sgsn_peer);
1318 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001319
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001320 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001321 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001322 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1323 gbcfg.match_re, err_msg);
1324 exit(1);
1325 }
1326
1327
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001328 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001329 printf("--- Initialise SGSN ---\n\n");
1330
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001331 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001332 gprs_dump_nsi(nsi);
1333
1334 printf("--- Initialise BSS 1 ---\n\n");
1335
1336 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1337 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1338 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001339 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001340
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001341 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001342 OSMO_ASSERT(peer != NULL);
1343
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001344 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1345
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001346 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1347 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001348
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001349 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001350 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001351
1352 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1353
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001354 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1355 foreign_tlli, &rai_bss, cell_id,
1356 GPRS_SAPI_GMM, 0,
1357 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001358
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001359 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1360 foreign_tlli, 0, NULL, 0,
1361 GPRS_SAPI_GMM, 0,
1362 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001363
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001364 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1365 foreign_tlli, &rai_bss, cell_id,
1366 GPRS_SAPI_GMM, 3,
1367 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001368
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001369 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1370 foreign_tlli, 1, imsi, sizeof(imsi),
1371 GPRS_SAPI_GMM, 1,
1372 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001373
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001374 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001375 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001376 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1377 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1378 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1379 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1380 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1381 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1382 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1383 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001384
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001385 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1386 local_tlli, &rai_bss, cell_id,
1387 GPRS_SAPI_GMM, 4,
1388 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001389
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001390 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001391 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001392 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1393 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1394 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1395 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1396 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1397 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1398 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1399 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001400
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001401 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001402 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1403 local_tlli, &rai_bss, cell_id,
1404 GPRS_SAPI_GMM, 3,
1405 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001406
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001407 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001408 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001409 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1410 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1411 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1412 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1413 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1414 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1415 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1416 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001417
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001418 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1419 local_tlli, 1, imsi, sizeof(imsi),
1420 GPRS_SAPI_GMM, 2,
1421 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001422
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001423 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001424 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001425 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1426 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1427 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1428 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001429
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001430 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001431 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1432 local_tlli, &rai_bss, cell_id,
1433 GPRS_SAPI_GMM, 3,
1434 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001435
Jacob Erlbeck73685282014-05-23 20:48:07 +02001436 gbcfg.core_apn[0] = 0;
1437 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001438
1439 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001440 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1441 local_tlli, &rai_bss, cell_id,
1442 GPRS_SAPI_GMM, 3,
1443 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001444
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001445 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001446
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001447 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001448 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1449 local_tlli, &rai_bss, cell_id,
1450 GPRS_SAPI_GMM, 6,
1451 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001452
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001453 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1454 local_tlli, 1, imsi, sizeof(imsi),
1455 GPRS_SAPI_GMM, 5,
1456 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001457
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001458 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001459
1460 printf("--- RA update ---\n\n");
1461
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001462 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1463 foreign_tlli, &rai_bss, 0x7080,
1464 GPRS_SAPI_GMM, 5,
1465 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001466
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001467 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1468 foreign_tlli, 1, imsi, sizeof(imsi),
1469 GPRS_SAPI_GMM, 6,
1470 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001471
1472 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001473 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1474 local_tlli, &rai_bss, cell_id,
1475 GPRS_SAPI_GMM, 3,
1476 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001477
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001478 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001479
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001480 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001481 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1482 local_tlli, &rai_bss, cell_id,
1483 GPRS_SAPI_GMM, 6,
1484 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001485
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001486 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001487 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001488
1489 printf("--- Bad cases ---\n\n");
1490
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001491 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001492 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1493 local_tlli, &rai_bss, cell_id,
1494 GPRS_SAPI_GMM, 3,
1495 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001496
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001497 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001498 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001499
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001500 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001501 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001502
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001503 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001504 gprs_ns_destroy(nsi);
1505 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001506}
1507
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001508static void test_gbproxy_ptmsi_patching()
1509{
1510 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1511 struct sockaddr_in bss_peer[1] = {{0},};
1512 struct sockaddr_in sgsn_peer= {0};
1513 struct gprs_ra_id rai_bss =
1514 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1515 struct gprs_ra_id rai_sgsn =
1516 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001517 struct gprs_ra_id rai_wrong_mcc_sgsn =
1518 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001519 struct gprs_ra_id rai_unknown =
1520 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1521 uint16_t cell_id = 0x1234;
1522
1523 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001524 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1525 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001526 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001527 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1528 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001529 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1530
1531 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001532 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1533 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001534 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001535 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1536 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001537 const uint32_t foreign_bss_tlli = 0x8000dead;
1538
1539 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1540 struct gbproxy_tlli_info *tlli_info;
1541 struct gbproxy_peer *peer;
1542 unsigned bss_nu = 0;
1543 unsigned sgsn_nu = 0;
1544
1545 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001546 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1547 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1548 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1549 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1550 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001551
1552 bssgp_nsi = nsi;
1553 gbcfg.nsi = bssgp_nsi;
1554 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1555 gbcfg.core_mcc = 123;
1556 gbcfg.core_mnc = 456;
1557 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1558 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1559 gbcfg.patch_ptmsi = 1;
1560 gbcfg.bss_ptmsi_state = 0;
1561 gbcfg.sgsn_tlli_state = 1;
1562
1563 configure_sgsn_peer(&sgsn_peer);
1564 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1565
1566 printf("=== %s ===\n", __func__);
1567 printf("--- Initialise SGSN ---\n\n");
1568
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001569 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001570
1571 printf("--- Initialise BSS 1 ---\n\n");
1572
1573 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1574 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1575
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001576 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001577 OSMO_ASSERT(peer != NULL);
1578
1579 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1580
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001581 gprs_dump_nsi(nsi);
1582 dump_global(stdout, 0);
1583 dump_peers(stdout, 0, 0, &gbcfg);
1584
1585 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1586
1587 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1588 foreign_bss_tlli, &rai_unknown, cell_id,
1589 GPRS_SAPI_GMM, bss_nu++,
1590 dtap_attach_req, sizeof(dtap_attach_req));
1591
1592 dump_peers(stdout, 0, 0, &gbcfg);
1593
1594 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1595 random_sgsn_tlli, 0, NULL, 0,
1596 GPRS_SAPI_GMM, sgsn_nu++,
1597 dtap_identity_req, sizeof(dtap_identity_req));
1598
1599 dump_peers(stdout, 0, 0, &gbcfg);
1600
1601 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1602 foreign_bss_tlli, &rai_bss, cell_id,
1603 GPRS_SAPI_GMM, bss_nu++,
1604 dtap_identity_resp, sizeof(dtap_identity_resp));
1605
1606 dump_peers(stdout, 0, 0, &gbcfg);
1607
1608 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1609 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1610 GPRS_SAPI_GMM, sgsn_nu++,
1611 dtap_attach_acc, sizeof(dtap_attach_acc));
1612
1613 dump_peers(stdout, 0, 0, &gbcfg);
1614
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001615 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001616 OSMO_ASSERT(tlli_info);
1617 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1618 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1619 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1620 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1621 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1622 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1623 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1624 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1625 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1626 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1627
1628 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1629 local_bss_tlli, &rai_bss, cell_id,
1630 GPRS_SAPI_GMM, bss_nu++,
1631 dtap_attach_complete, sizeof(dtap_attach_complete));
1632
1633 dump_peers(stdout, 0, 0, &gbcfg);
1634
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001635 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001636 OSMO_ASSERT(tlli_info);
1637 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1638 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1639 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1640 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1641 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1642 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1643 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1644 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1645
1646 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1647 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1648 GPRS_SAPI_GMM, sgsn_nu++,
1649 dtap_gmm_information, sizeof(dtap_gmm_information));
1650
1651 dump_peers(stdout, 0, 0, &gbcfg);
1652
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001653 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001654 OSMO_ASSERT(tlli_info);
1655 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1656 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1657 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1658 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1659
Jacob Erlbeck82add782014-09-05 18:08:12 +02001660 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1661 local_bss_tlli, &rai_bss, cell_id,
1662 GPRS_SAPI_GMM, bss_nu++,
1663 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1664
1665 dump_peers(stdout, 0, 0, &gbcfg);
1666
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001667 /* Non-DTAP */
1668 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1669 local_bss_tlli, &rai_bss, cell_id,
1670 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1671
1672 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1673 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1674 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1675
1676 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1677 local_bss_tlli, &rai_bss, cell_id,
1678 llc_ui_ll11_dns_query_ul,
1679 sizeof(llc_ui_ll11_dns_query_ul));
1680
1681 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1682 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1683 llc_ui_ll11_dns_resp_dl,
1684 sizeof(llc_ui_ll11_dns_resp_dl));
1685
1686 dump_peers(stdout, 0, 0, &gbcfg);
1687
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001688 /* Repeated RA Update Requests */
1689 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1690 local_bss_tlli, &rai_bss, 0x7080,
1691 GPRS_SAPI_GMM, bss_nu++,
1692 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1693
1694 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1695 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1696 GPRS_SAPI_GMM, sgsn_nu++,
1697 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1698
1699 dump_peers(stdout, 0, 0, &gbcfg);
1700
1701 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1702 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1703 OSMO_ASSERT(tlli_info);
1704 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1705 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1706 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1707 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1708 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1709 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1710 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1711 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1712 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1713 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1714
1715 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1716 local_bss_tlli2, &rai_bss, 0x7080,
1717 GPRS_SAPI_GMM, bss_nu++,
1718 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1719
1720 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1721 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1722 GPRS_SAPI_GMM, sgsn_nu++,
1723 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1724
1725 dump_peers(stdout, 0, 0, &gbcfg);
1726
1727 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1728 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1729 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1730 OSMO_ASSERT(tlli_info);
1731 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1732 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1733 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1734 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1735 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1736 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1737 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1738 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1739 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1740 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1741
1742 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1743 local_bss_tlli3, &rai_bss, 0x7080,
1744 GPRS_SAPI_GMM, bss_nu++,
1745 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1746
1747 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1748
1749 OSMO_ASSERT(tlli_info);
1750 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1751 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1752 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1753 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1754
1755 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1756 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1757 GPRS_SAPI_GMM, sgsn_nu++,
1758 dtap_gmm_information, sizeof(dtap_gmm_information));
1759
1760 dump_peers(stdout, 0, 0, &gbcfg);
1761
1762 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1763 OSMO_ASSERT(tlli_info);
1764 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1765 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1766 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1767 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1768
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001769 /* Other messages */
1770 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001771 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001772
1773 dump_peers(stdout, 0, 0, &gbcfg);
1774
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001775 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001776
1777 dump_peers(stdout, 0, 0, &gbcfg);
1778
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001779 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001780
1781 dump_peers(stdout, 0, 0, &gbcfg);
1782
1783 /* Bad case: Invalid BVCI */
1784 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001785 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001786 dump_global(stdout, 0);
1787
1788 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001789 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001790
1791 dump_global(stdout, 0);
1792
1793 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001794 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001795 &rai_wrong_mcc_sgsn);
1796
1797 dump_global(stdout, 0);
1798
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001799 /* Detach */
1800 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001801 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001802 GPRS_SAPI_GMM, bss_nu++,
1803 dtap_detach_req, sizeof(dtap_detach_req));
1804
1805 dump_peers(stdout, 0, 0, &gbcfg);
1806
1807 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001808 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001809 GPRS_SAPI_GMM, sgsn_nu++,
1810 dtap_detach_acc, sizeof(dtap_detach_acc));
1811
1812 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001813
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001814 dump_global(stdout, 0);
1815
1816 gbprox_reset(&gbcfg);
1817 gprs_ns_destroy(nsi);
1818 nsi = NULL;
1819}
1820
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001821static void test_gbproxy_imsi_acquisition()
1822{
1823 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1824 struct sockaddr_in bss_peer[1] = {{0},};
1825 struct sockaddr_in sgsn_peer= {0};
1826 struct gprs_ra_id rai_bss =
1827 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1828 struct gprs_ra_id rai_sgsn =
1829 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1830 struct gprs_ra_id rai_wrong_mcc_sgsn =
1831 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1832 struct gprs_ra_id rai_unknown =
1833 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1834 uint16_t cell_id = 0x1234;
1835
1836 const uint32_t sgsn_ptmsi = 0xefe2b700;
1837 const uint32_t local_sgsn_tlli = 0xefe2b700;
1838 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1839
1840 const uint32_t bss_ptmsi = 0xc00f7304;
1841 const uint32_t local_bss_tlli = 0xc00f7304;
1842 const uint32_t foreign_bss_tlli = 0x8000dead;
1843
1844 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1845 struct gbproxy_tlli_info *tlli_info;
1846 struct gbproxy_peer *peer;
1847 unsigned bss_nu = 0;
1848 unsigned sgsn_nu = 0;
1849
1850 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1851
1852 bssgp_nsi = nsi;
1853 gbcfg.nsi = bssgp_nsi;
1854 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1855 gbcfg.core_mcc = 123;
1856 gbcfg.core_mnc = 456;
1857 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1858 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1859 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001860 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001861 gbcfg.bss_ptmsi_state = 0;
1862 gbcfg.sgsn_tlli_state = 1;
1863
1864 configure_sgsn_peer(&sgsn_peer);
1865 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1866
1867 printf("=== %s ===\n", __func__);
1868 printf("--- Initialise SGSN ---\n\n");
1869
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001870 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001871
1872 printf("--- Initialise BSS 1 ---\n\n");
1873
1874 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1875 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1876
1877 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1878 OSMO_ASSERT(peer != NULL);
1879
1880 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1881
1882 gprs_dump_nsi(nsi);
1883 dump_global(stdout, 0);
1884 dump_peers(stdout, 0, 0, &gbcfg);
1885
1886 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1887
1888 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1889 foreign_bss_tlli, &rai_unknown, cell_id,
1890 GPRS_SAPI_GMM, bss_nu++,
1891 dtap_attach_req, sizeof(dtap_attach_req));
1892
1893 dump_peers(stdout, 0, 0, &gbcfg);
1894
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001895 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1896 foreign_bss_tlli, &rai_bss, cell_id,
1897 GPRS_SAPI_GMM, bss_nu++,
1898 dtap_identity_resp, sizeof(dtap_identity_resp));
1899
1900 dump_peers(stdout, 0, 0, &gbcfg);
1901
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001902 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1903 random_sgsn_tlli, 0, NULL, 0,
1904 GPRS_SAPI_GMM, sgsn_nu++,
1905 dtap_identity_req, sizeof(dtap_identity_req));
1906
1907 dump_peers(stdout, 0, 0, &gbcfg);
1908
1909 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1910 foreign_bss_tlli, &rai_bss, cell_id,
1911 GPRS_SAPI_GMM, bss_nu++,
1912 dtap_identity_resp, sizeof(dtap_identity_resp));
1913
1914 dump_peers(stdout, 0, 0, &gbcfg);
1915
1916 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1917 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1918 GPRS_SAPI_GMM, sgsn_nu++,
1919 dtap_attach_acc, sizeof(dtap_attach_acc));
1920
1921 dump_peers(stdout, 0, 0, &gbcfg);
1922
1923 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1924 OSMO_ASSERT(tlli_info);
1925 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1926 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1927 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1928 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1929 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1930 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1931 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1932 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1933 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1934 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1935
1936 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1937 local_bss_tlli, &rai_bss, cell_id,
1938 GPRS_SAPI_GMM, bss_nu++,
1939 dtap_attach_complete, sizeof(dtap_attach_complete));
1940
1941 dump_peers(stdout, 0, 0, &gbcfg);
1942
1943 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1944 OSMO_ASSERT(tlli_info);
1945 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1946 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1947 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1948 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1949 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1950 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1951 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1952 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1953
1954 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1955 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1956 GPRS_SAPI_GMM, sgsn_nu++,
1957 dtap_gmm_information, sizeof(dtap_gmm_information));
1958
1959 dump_peers(stdout, 0, 0, &gbcfg);
1960
1961 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1962 OSMO_ASSERT(tlli_info);
1963 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1964 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1965 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1966 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1967
1968 /* Non-DTAP */
1969 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1970 local_bss_tlli, &rai_bss, cell_id,
1971 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1972
1973 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1974 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1975 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1976
1977 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1978 local_bss_tlli, &rai_bss, cell_id,
1979 llc_ui_ll11_dns_query_ul,
1980 sizeof(llc_ui_ll11_dns_query_ul));
1981
1982 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1983 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1984 llc_ui_ll11_dns_resp_dl,
1985 sizeof(llc_ui_ll11_dns_resp_dl));
1986
1987 dump_peers(stdout, 0, 0, &gbcfg);
1988
1989 /* Other messages */
1990 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1991 local_bss_tlli, 1, 12);
1992
1993 dump_peers(stdout, 0, 0, &gbcfg);
1994
1995 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
1996 local_sgsn_tlli, 1, 12);
1997
1998 dump_peers(stdout, 0, 0, &gbcfg);
1999
2000 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2001
2002 dump_peers(stdout, 0, 0, &gbcfg);
2003
2004 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2005
2006 dump_peers(stdout, 0, 0, &gbcfg);
2007
2008 /* Bad case: Invalid BVCI */
2009 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2010 local_bss_tlli, 1, 12);
2011 dump_global(stdout, 0);
2012
2013 /* Bad case: Invalid RAI */
2014 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2015
2016 dump_global(stdout, 0);
2017
2018 /* Bad case: Invalid MCC (LAC ok) */
2019 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2020 &rai_wrong_mcc_sgsn);
2021
2022 dump_global(stdout, 0);
2023
2024 /* Detach */
2025 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2026 local_bss_tlli, &rai_bss, cell_id,
2027 GPRS_SAPI_GMM, bss_nu++,
2028 dtap_detach_req, sizeof(dtap_detach_req));
2029
2030 dump_peers(stdout, 0, 0, &gbcfg);
2031
2032 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2033 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2034 GPRS_SAPI_GMM, sgsn_nu++,
2035 dtap_detach_acc, sizeof(dtap_detach_acc));
2036
2037 dump_peers(stdout, 0, 0, &gbcfg);
2038
2039 dump_global(stdout, 0);
2040
2041 gbprox_reset(&gbcfg);
2042 gprs_ns_destroy(nsi);
2043 nsi = NULL;
2044}
2045
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002046static void test_gbproxy_secondary_sgsn()
2047{
2048 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2049 struct sockaddr_in bss_peer[1] = {{0},};
2050 struct sockaddr_in sgsn_peer[2]= {{0},};
2051 struct gprs_ra_id rai_bss =
2052 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2053 struct gprs_ra_id rai_sgsn =
2054 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2055 struct gprs_ra_id rai_unknown =
2056 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2057 uint16_t cell_id = 0x1234;
2058
2059 const uint32_t sgsn_ptmsi = 0xefe2b700;
2060 const uint32_t local_sgsn_tlli = 0xefe2b700;
2061 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2062
2063 const uint32_t bss_ptmsi = 0xc00f7304;
2064 const uint32_t local_bss_tlli = 0xc00f7304;
2065 const uint32_t foreign_bss_tlli = 0x8000dead;
2066
2067 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2068 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2069 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2070 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2071 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2072 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2073
2074 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2075 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2076 struct gbproxy_tlli_info *tlli_info;
2077 struct gbproxy_peer *peer;
2078 unsigned bss_nu = 0;
2079 unsigned sgsn_nu = 0;
2080
2081 const char *err_msg = NULL;
2082 const char *filter_re = "999999";
2083
2084 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2085 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2086
2087 bssgp_nsi = nsi;
2088 gbcfg.nsi = bssgp_nsi;
2089 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2090 gbcfg.core_mcc = 123;
2091 gbcfg.core_mnc = 456;
2092 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2093 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2094 gbcfg.patch_ptmsi = 1;
2095 gbcfg.acquire_imsi = 1;
2096 gbcfg.bss_ptmsi_state = 0;
2097 gbcfg.sgsn_tlli_state = 1;
2098 gbcfg.route_to_sgsn2 = 1;
2099 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2100
2101 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2102 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2103 err_msg);
2104 OSMO_ASSERT(err_msg == NULL);
2105 }
2106
2107 configure_sgsn_peer(&sgsn_peer[0]);
2108 configure_sgsn2_peer(&sgsn_peer[1]);
2109 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2110
2111 printf("=== %s ===\n", __func__);
2112 printf("--- Initialise SGSN 1 ---\n\n");
2113
2114 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2115
2116 printf("--- Initialise SGSN 2 ---\n\n");
2117
2118 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2119
2120 printf("--- Initialise BSS 1 ---\n\n");
2121
2122 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2123 setup_bssgp(nsi, &bss_peer[0], 0x0);
2124 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2125 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2126 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2127 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2128
2129 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2130 OSMO_ASSERT(peer != NULL);
2131
2132 gprs_dump_nsi(nsi);
2133 dump_global(stdout, 0);
2134 dump_peers(stdout, 0, 0, &gbcfg);
2135
2136 printf("--- Flow control ---\n\n");
2137
2138 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2139 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2140 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2141
2142 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2143
2144 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2145 foreign_bss_tlli, &rai_unknown, cell_id,
2146 GPRS_SAPI_GMM, bss_nu++,
2147 dtap_attach_req, sizeof(dtap_attach_req));
2148
2149 dump_peers(stdout, 0, 0, &gbcfg);
2150
2151 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2152 foreign_bss_tlli, &rai_bss, cell_id,
2153 GPRS_SAPI_GMM, bss_nu++,
2154 dtap_identity_resp, sizeof(dtap_identity_resp));
2155
2156 dump_peers(stdout, 0, 0, &gbcfg);
2157
2158 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2159 random_sgsn_tlli, 0, NULL, 0,
2160 GPRS_SAPI_GMM, sgsn_nu++,
2161 dtap_identity_req, sizeof(dtap_identity_req));
2162
2163 dump_peers(stdout, 0, 0, &gbcfg);
2164
2165 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2166 foreign_bss_tlli, &rai_bss, cell_id,
2167 GPRS_SAPI_GMM, bss_nu++,
2168 dtap_identity_resp, sizeof(dtap_identity_resp));
2169
2170 dump_peers(stdout, 0, 0, &gbcfg);
2171
2172 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2173 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2174 GPRS_SAPI_GMM, sgsn_nu++,
2175 dtap_attach_acc, sizeof(dtap_attach_acc));
2176
2177 dump_peers(stdout, 0, 0, &gbcfg);
2178
2179 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2180 OSMO_ASSERT(tlli_info);
2181 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2182 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2183 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2184 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2185 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2186 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2187 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2188 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2189 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2190 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2191
2192 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2193 local_bss_tlli, &rai_bss, cell_id,
2194 GPRS_SAPI_GMM, bss_nu++,
2195 dtap_attach_complete, sizeof(dtap_attach_complete));
2196
2197 dump_peers(stdout, 0, 0, &gbcfg);
2198
2199 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2200 OSMO_ASSERT(tlli_info);
2201 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2202 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2203 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2204 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2205 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2206 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2207 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2208 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2209
2210 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2211 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2212 GPRS_SAPI_GMM, sgsn_nu++,
2213 dtap_gmm_information, sizeof(dtap_gmm_information));
2214
2215 dump_peers(stdout, 0, 0, &gbcfg);
2216
2217 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2218 OSMO_ASSERT(tlli_info);
2219 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2220 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2221 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2222 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2223
2224 /* Non-DTAP */
2225 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2226 local_bss_tlli, &rai_bss, cell_id,
2227 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2228
2229 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2230 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2231 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2232
2233 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2234 local_bss_tlli, &rai_bss, cell_id,
2235 llc_ui_ll11_dns_query_ul,
2236 sizeof(llc_ui_ll11_dns_query_ul));
2237
2238 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2239 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2240 llc_ui_ll11_dns_resp_dl,
2241 sizeof(llc_ui_ll11_dns_resp_dl));
2242
2243 dump_peers(stdout, 0, 0, &gbcfg);
2244
2245 /* Other messages */
2246 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2247 local_bss_tlli, 1, 12);
2248
2249 dump_peers(stdout, 0, 0, &gbcfg);
2250
2251 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2252 local_sgsn_tlli, 1, 12);
2253
2254 dump_peers(stdout, 0, 0, &gbcfg);
2255
2256 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2257
2258 dump_peers(stdout, 0, 0, &gbcfg);
2259
2260 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2261
2262 dump_peers(stdout, 0, 0, &gbcfg);
2263
2264 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2265
2266 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2267 foreign_bss_tlli2, &rai_unknown, cell_id,
2268 GPRS_SAPI_GMM, bss_nu++,
2269 dtap_attach_req, sizeof(dtap_attach_req));
2270
2271 dump_peers(stdout, 0, 0, &gbcfg);
2272
2273 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2274 foreign_bss_tlli2, &rai_bss, cell_id,
2275 GPRS_SAPI_GMM, bss_nu++,
2276 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2277
2278 dump_peers(stdout, 0, 0, &gbcfg);
2279
2280 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2281 random_sgsn_tlli2, 0, NULL, 0,
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_identity_req, sizeof(dtap_identity_req));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
2287 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2288 foreign_bss_tlli2, &rai_bss, cell_id,
2289 GPRS_SAPI_GMM, bss_nu++,
2290 dtap_identity_resp, sizeof(dtap_identity_resp));
2291
2292 dump_peers(stdout, 0, 0, &gbcfg);
2293
2294 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2295 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2296 GPRS_SAPI_GMM, sgsn_nu++,
2297 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2298
2299 dump_peers(stdout, 0, 0, &gbcfg);
2300
2301 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2302 OSMO_ASSERT(tlli_info);
2303 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2304 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2305 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2306 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2307 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2308 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2309 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2310 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2311 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2312 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2313
2314 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2315 local_bss_tlli2, &rai_bss, cell_id,
2316 GPRS_SAPI_GMM, bss_nu++,
2317 dtap_attach_complete, sizeof(dtap_attach_complete));
2318
2319 dump_peers(stdout, 0, 0, &gbcfg);
2320
2321 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2322 OSMO_ASSERT(tlli_info);
2323 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2324 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2325 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2326 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2327 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2328 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2329 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2330 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2331
2332 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2333 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2334 GPRS_SAPI_GMM, sgsn_nu++,
2335 dtap_gmm_information, sizeof(dtap_gmm_information));
2336
2337 dump_peers(stdout, 0, 0, &gbcfg);
2338
2339 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2340 OSMO_ASSERT(tlli_info);
2341 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2342 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2343 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2344 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2345
2346 /* Non-DTAP */
2347 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2348 local_bss_tlli2, &rai_bss, cell_id,
2349 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2350
2351 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2352 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2353 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2354
2355 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2356 local_bss_tlli2, &rai_bss, cell_id,
2357 llc_ui_ll11_dns_query_ul,
2358 sizeof(llc_ui_ll11_dns_query_ul));
2359
2360 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2361 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2362 llc_ui_ll11_dns_resp_dl,
2363 sizeof(llc_ui_ll11_dns_resp_dl));
2364
2365 dump_peers(stdout, 0, 0, &gbcfg);
2366
2367 /* Other messages */
2368 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2369 local_bss_tlli2, 1, 12);
2370
2371 dump_peers(stdout, 0, 0, &gbcfg);
2372
2373 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2374 local_sgsn_tlli2, 1, 12);
2375
2376 dump_peers(stdout, 0, 0, &gbcfg);
2377
2378 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2379
2380 dump_peers(stdout, 0, 0, &gbcfg);
2381
2382 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2383
2384 dump_peers(stdout, 0, 0, &gbcfg);
2385
2386 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2387
2388 /* Detach */
2389 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2390 local_bss_tlli, &rai_bss, cell_id,
2391 GPRS_SAPI_GMM, bss_nu++,
2392 dtap_detach_req, sizeof(dtap_detach_req));
2393
2394 dump_peers(stdout, 0, 0, &gbcfg);
2395
2396 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2397 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2398 GPRS_SAPI_GMM, sgsn_nu++,
2399 dtap_detach_acc, sizeof(dtap_detach_acc));
2400
2401 dump_peers(stdout, 0, 0, &gbcfg);
2402
2403 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2404
2405 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2406 local_bss_tlli2, &rai_bss, cell_id,
2407 GPRS_SAPI_GMM, bss_nu++,
2408 dtap_detach_req, sizeof(dtap_detach_req));
2409
2410 dump_peers(stdout, 0, 0, &gbcfg);
2411
2412 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2413 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2414 GPRS_SAPI_GMM, sgsn_nu++,
2415 dtap_detach_acc, sizeof(dtap_detach_acc));
2416
2417 dump_peers(stdout, 0, 0, &gbcfg);
2418
2419 dump_global(stdout, 0);
2420
2421 gbprox_reset(&gbcfg);
2422 gprs_ns_destroy(nsi);
2423 nsi = NULL;
2424}
2425
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002426/* TODO: Move tlv testing to libosmocore */
2427int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2428int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2429 uint8_t **value);
2430int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2431 size_t *value_len);
2432int lv_shift(uint8_t **data, size_t *data_len,
2433 uint8_t **value, size_t *value_len);
2434
2435static void check_tlv_match(uint8_t **data, size_t *data_len,
2436 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2437{
2438 uint8_t *value;
2439 size_t value_len;
2440 int rc;
2441
2442 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2443 OSMO_ASSERT(rc == 0);
2444
2445 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002446 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002447 OSMO_ASSERT(value_len == exp_len);
2448 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2449}
2450
2451static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2452 uint8_t tag, size_t len, const uint8_t *exp_val)
2453{
2454 uint8_t *value;
2455 int rc;
2456
2457 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2458 OSMO_ASSERT(rc == 0);
2459
2460 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002461 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002462 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2463}
2464
2465static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2466 size_t len, const uint8_t *exp_val)
2467{
2468 uint8_t *value;
2469 int rc;
2470
2471 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002472 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002473 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2474}
2475
2476static void check_lv_shift(uint8_t **data, size_t *data_len,
2477 size_t exp_len, const uint8_t *exp_val)
2478{
2479 uint8_t *value;
2480 size_t value_len;
2481 int rc;
2482
2483 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002484 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002485 OSMO_ASSERT(value_len == exp_len);
2486 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2487}
2488
2489static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2490 const uint8_t *test_data)
2491{
2492 uint8_t buf[300] = {0};
2493
2494 uint8_t *unchanged_ptr = buf - 1;
2495 size_t unchanged_len = 0xdead;
2496 size_t tmp_data_len = data_len;
2497 uint8_t *value = unchanged_ptr;
2498 size_t value_len = unchanged_len;
2499 uint8_t *data = buf;
2500
2501 OSMO_ASSERT(data_len <= sizeof(buf));
2502
2503 tlv_put(data, tag, len, test_data);
2504 if (data_len < len + 2) {
2505 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2506 tag, &value, &value_len));
2507 OSMO_ASSERT(tmp_data_len == 0);
2508 OSMO_ASSERT(data == buf + data_len);
2509 OSMO_ASSERT(value == unchanged_ptr);
2510 OSMO_ASSERT(value_len == unchanged_len);
2511 } else {
2512 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2513 tag, &value, &value_len));
2514 OSMO_ASSERT(value != unchanged_ptr);
2515 OSMO_ASSERT(value_len != unchanged_len);
2516 }
2517}
2518
2519static void check_tv_fixed_match_data_len(size_t data_len,
2520 uint8_t tag, size_t len,
2521 const uint8_t *test_data)
2522{
2523 uint8_t buf[300] = {0};
2524
2525 uint8_t *unchanged_ptr = buf - 1;
2526 size_t tmp_data_len = data_len;
2527 uint8_t *value = unchanged_ptr;
2528 uint8_t *data = buf;
2529
2530 OSMO_ASSERT(data_len <= sizeof(buf));
2531
2532 tv_fixed_put(data, tag, len, test_data);
2533
2534 if (data_len < len + 1) {
2535 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2536 tag, len, &value));
2537 OSMO_ASSERT(tmp_data_len == 0);
2538 OSMO_ASSERT(data == buf + data_len);
2539 OSMO_ASSERT(value == unchanged_ptr);
2540 } else {
2541 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2542 tag, len, &value));
2543 OSMO_ASSERT(value != unchanged_ptr);
2544 }
2545}
2546
2547static void check_v_fixed_shift_data_len(size_t data_len,
2548 size_t len, const uint8_t *test_data)
2549{
2550 uint8_t buf[300] = {0};
2551
2552 uint8_t *unchanged_ptr = buf - 1;
2553 size_t tmp_data_len = data_len;
2554 uint8_t *value = unchanged_ptr;
2555 uint8_t *data = buf;
2556
2557 OSMO_ASSERT(data_len <= sizeof(buf));
2558
2559 memcpy(data, test_data, len);
2560
2561 if (data_len < len) {
2562 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2563 len, &value));
2564 OSMO_ASSERT(tmp_data_len == 0);
2565 OSMO_ASSERT(data == buf + data_len);
2566 OSMO_ASSERT(value == unchanged_ptr);
2567 } else {
2568 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2569 len, &value));
2570 OSMO_ASSERT(value != unchanged_ptr);
2571 }
2572}
2573
2574static void check_lv_shift_data_len(size_t data_len,
2575 size_t len, const uint8_t *test_data)
2576{
2577 uint8_t buf[300] = {0};
2578
2579 uint8_t *unchanged_ptr = buf - 1;
2580 size_t unchanged_len = 0xdead;
2581 size_t tmp_data_len = data_len;
2582 uint8_t *value = unchanged_ptr;
2583 size_t value_len = unchanged_len;
2584 uint8_t *data = buf;
2585
2586 lv_put(data, len, test_data);
2587 if (data_len < len + 1) {
2588 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2589 &value, &value_len));
2590 OSMO_ASSERT(tmp_data_len == 0);
2591 OSMO_ASSERT(data == buf + data_len);
2592 OSMO_ASSERT(value == unchanged_ptr);
2593 OSMO_ASSERT(value_len == unchanged_len);
2594 } else {
2595 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2596 &value, &value_len));
2597 OSMO_ASSERT(value != unchanged_ptr);
2598 OSMO_ASSERT(value_len != unchanged_len);
2599 }
2600}
2601
2602static void test_tlv_shift_functions()
2603{
2604 uint8_t test_data[1024];
2605 uint8_t buf[1024];
2606 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002607 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002608 uint8_t *data;
2609 size_t data_len;
2610 const uint8_t tag = 0x1a;
2611
2612 printf("Test shift functions\n");
2613
2614 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2615 test_data[i] = (uint8_t)i;
2616
2617 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002618 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002619
2620 memset(buf, 0xee, sizeof(buf));
2621 data_end = data = buf;
2622
2623 for (i = 0; i < iterations; i++) {
2624 data_end = tlv_put(data_end, tag, len, test_data);
2625 data_end = tv_fixed_put(data_end, tag, len, test_data);
2626 /* v_fixed_put */
2627 memcpy(data_end, test_data, len);
2628 data_end += len;
2629 data_end = lv_put(data_end, len, test_data);
2630 }
2631
2632 data_len = data_end - data;
2633 OSMO_ASSERT(data_len <= sizeof(buf));
2634
2635 for (i = 0; i < iterations; i++) {
2636 check_tlv_match(&data, &data_len, tag, len, test_data);
2637 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2638 check_v_fixed_shift(&data, &data_len, len, test_data);
2639 check_lv_shift(&data, &data_len, len, test_data);
2640 }
2641
2642 OSMO_ASSERT(data == data_end);
2643
2644 /* Test at end of data */
2645
2646 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2647 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2648 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2649 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2650
2651 /* Test invalid data_len */
2652 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2653 check_tlv_match_data_len(data_len, tag, len, test_data);
2654 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2655 check_v_fixed_shift_data_len(data_len, len, test_data);
2656 check_lv_shift_data_len(data_len, len, test_data);
2657 }
2658 }
2659}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002660
2661static void test_gbproxy_tlli_expire(void)
2662{
2663 struct gbproxy_config cfg = {0};
2664 struct gbproxy_peer *peer;
2665 const char *err_msg = NULL;
2666 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2667 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002668 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002669 const uint32_t tlli1 = 1234 | 0xc0000000;
2670 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002671 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002672 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002673 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002674
2675 printf("Test TLLI info expiry\n\n");
2676
2677 gbproxy_init_config(&cfg);
2678
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002679 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002680 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2681 err_msg);
2682 OSMO_ASSERT(err_msg == NULL);
2683 }
2684
2685 {
2686 struct gbproxy_tlli_info *tlli_info;
2687
2688 printf("Test TLLI replacement:\n");
2689
2690 cfg.tlli_max_len = 0;
2691 cfg.tlli_max_age = 0;
2692 peer = gbproxy_peer_alloc(&cfg, 20);
2693 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2694
2695 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002696 tlli_info = gbproxy_register_tlli(peer, tlli1,
2697 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002698 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002699 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002700 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2701
2702 /* replace the old entry */
2703 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002704 tlli_info = gbproxy_register_tlli(peer, tlli2,
2705 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002706 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002707 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002708 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2709
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002710 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002711
2712 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002713 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002714 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002715 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002716 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002717 OSMO_ASSERT(!tlli_info);
2718
2719 printf("\n");
2720
2721 gbproxy_peer_free(peer);
2722 }
2723
2724 {
2725 struct gbproxy_tlli_info *tlli_info;
2726
2727 printf("Test IMSI replacement:\n");
2728
2729 cfg.tlli_max_len = 0;
2730 cfg.tlli_max_age = 0;
2731 peer = gbproxy_peer_alloc(&cfg, 20);
2732 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2733
2734 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002735 tlli_info = gbproxy_register_tlli(peer, tlli1,
2736 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002737 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002738 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002739 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2740
2741 /* try to replace the old entry */
2742 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002743 tlli_info = gbproxy_register_tlli(peer, tlli1,
2744 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002745 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002746 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002747 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2748
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002749 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002750
2751 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002752 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002753 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002754 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002755 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002756 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002757
2758 printf("\n");
2759
2760 gbproxy_peer_free(peer);
2761 }
2762
2763 {
2764 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002765 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002766
2767 printf("Test TLLI expiry, max_len == 1:\n");
2768
2769 cfg.tlli_max_len = 1;
2770 cfg.tlli_max_age = 0;
2771 peer = gbproxy_peer_alloc(&cfg, 20);
2772 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2773
2774 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002775 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002776 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2777
2778 /* replace the old entry */
2779 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002780 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002781 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2782
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002783 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002784 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002785 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2786
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002787 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002788
2789 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002790 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002791 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002792 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002793 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002794 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002795
2796 printf("\n");
2797
2798 gbproxy_peer_free(peer);
2799 }
2800
2801 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002802 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002803 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002804
2805 printf("Test TLLI expiry, max_age == 1:\n");
2806
2807 cfg.tlli_max_len = 0;
2808 cfg.tlli_max_age = 1;
2809 peer = gbproxy_peer_alloc(&cfg, 20);
2810 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2811
2812 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002813 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002814 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2815
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002816 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002817 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002818 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002819 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2820
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002821 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002822 OSMO_ASSERT(num_removed == 1);
2823 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2824
2825 dump_peers(stdout, 2, now + 2, &cfg);
2826
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002827 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002828 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002829 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002830 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002831 OSMO_ASSERT(tlli_info);
2832 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2833
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002834 printf("\n");
2835
2836 gbproxy_peer_free(peer);
2837 }
2838
2839 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002840 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002841 int num_removed;
2842
2843 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2844
2845 cfg.tlli_max_len = 0;
2846 cfg.tlli_max_age = 1;
2847 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002848 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2849
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002850 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002851 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002852 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2853
2854 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002855 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002856 now + 1);
2857 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2858
2859 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002860 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2861 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002862 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2863
2864 dump_peers(stdout, 2, now + 2, &cfg);
2865
2866 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002867 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002868 OSMO_ASSERT(num_removed == 2);
2869 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2870
2871 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002872
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002873 /* verify that tlli3 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002874 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002875 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002876 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002877 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002878 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002879 OSMO_ASSERT(tlli_info);
2880 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2881
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002882 printf("\n");
2883
2884 gbproxy_peer_free(peer);
2885 }
2886}
2887
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002888static void test_gbproxy_imsi_matching(void)
2889{
2890 struct gbproxy_config cfg = {0};
2891 struct gbproxy_peer *peer;
2892 const char *err_msg = NULL;
2893 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2894 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2895 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2896 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2897 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2898 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2899 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2900 const char *filter_re1 = ".*";
2901 const char *filter_re2 = "^1234";
2902 const char *filter_re3 = "^4321";
2903 const char *filter_re4_bad = "^12[";
2904
2905 printf("=== Test IMSI/TMSI matching ===\n\n");
2906
2907 gbproxy_init_config(&cfg);
2908 OSMO_ASSERT(cfg.check_imsi == 0);
2909
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002910 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002911 OSMO_ASSERT(cfg.check_imsi == 1);
2912
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002913 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002914 OSMO_ASSERT(cfg.check_imsi == 1);
2915
2916 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002917 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002918 OSMO_ASSERT(err_msg != NULL);
2919 OSMO_ASSERT(cfg.check_imsi == 0);
2920
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002921 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002922 OSMO_ASSERT(cfg.check_imsi == 1);
2923
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002924 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002925 OSMO_ASSERT(cfg.check_imsi == 0);
2926
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002927 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002928 OSMO_ASSERT(cfg.check_imsi == 1);
2929
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002930 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002931 OSMO_ASSERT(cfg.check_imsi == 0);
2932
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002933 peer = gbproxy_peer_alloc(&cfg, 20);
2934
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002935 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002936 OSMO_ASSERT(cfg.check_imsi == 1);
2937
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002938 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2939 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002940 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002941 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002942 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002943 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2944 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2945 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2946 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2947 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002948
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002949 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002950 OSMO_ASSERT(cfg.check_imsi == 1);
2951
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002952 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2953 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2954 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2955 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2956 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2957 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2958 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002959
2960 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2961
2962 gbproxy_peer_free(peer);
2963}
2964
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002965static struct log_info_cat gprs_categories[] = {
2966 [DGPRS] = {
2967 .name = "DGPRS",
2968 .description = "GPRS Packet Service",
2969 .enabled = 1, .loglevel = LOGL_DEBUG,
2970 },
2971 [DNS] = {
2972 .name = "DNS",
2973 .description = "GPRS Network Service (NS)",
2974 .enabled = 1, .loglevel = LOGL_INFO,
2975 },
2976 [DBSSGP] = {
2977 .name = "DBSSGP",
2978 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2979 .enabled = 1, .loglevel = LOGL_DEBUG,
2980 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002981};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002982
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002983static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002984 .cat = gprs_categories,
2985 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002986};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002987
2988int main(int argc, char **argv)
2989{
2990 osmo_init_logging(&info);
2991 log_set_use_color(osmo_stderr_target, 0);
2992 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02002993 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002994
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002995 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002996 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
2997 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002998
2999 rate_ctr_init(NULL);
3000
3001 setlinebuf(stdout);
3002
3003 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003004 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003005 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003006 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003007 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003008 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003009 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003010 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003011 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003012 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003013 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003014 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003015
3016 exit(EXIT_SUCCESS);
3017}