blob: 514881e6f816ec501cfd7263c9b74c50a7808770 [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 Erlbeckf181f9e2014-08-27 12:44:25 +0200198/* DTAP - Attach Accept, IMSI 2 */
199static 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 Erlbeckc53f2a62014-08-15 14:56:28 +0200233/* DTAP - Activate PDP Context Request */
234static const unsigned char dtap_act_pdp_ctx_req[] = {
235 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200236 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
238 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
239 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
240 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200241 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200242};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200243
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200244/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200245/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200246static const unsigned char dtap_detach_po_req[] = {
247 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
248 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200249};
250
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200251/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200252/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200253static const unsigned char dtap_detach_req[] = {
254 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
255 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200256};
257
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200258/* DTAP - Detach Accept */
259static const unsigned char dtap_detach_acc[] = {
260 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200261};
262
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200263/* GPRS-LLC - SAPI: LLGMM, U, XID */
264static const unsigned char llc_u_xid_ul[] = {
265 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
266 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
267};
268
269/* GPRS-LLC - SAPI: LLGMM, U, XID */
270static const unsigned char llc_u_xid_dl[] = {
271 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
272 0xe4, 0xa9, 0x1a, 0x9e
273};
274
275/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
276static const unsigned char llc_ui_ll11_dns_query_ul[] = {
277 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
278 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
279 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
280 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
281 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
282 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
283 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
284 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
285 0x8f, 0x07
286};
287
288/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
289static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
290 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
291 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
292 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
293 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
294 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
295 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
296 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
297 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
298 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
299 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
300 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
301 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
302 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
303 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
304 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
305 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
306 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
307 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
308 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
309 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
310 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
311 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
312 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
313 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
314 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
315 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
316};
317
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200318static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
319 struct sockaddr_in *peer, const unsigned char* data,
320 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200321
322static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
323 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
324{
325 /* GPRS Network Service, PDU type: NS_RESET,
326 */
327 unsigned char msg[12] = {
328 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
329 0x04, 0x82, 0x11, 0x22
330 };
331
332 msg[3] = cause;
333 msg[6] = nsvci / 256;
334 msg[7] = nsvci % 256;
335 msg[10] = nsei / 256;
336 msg[11] = nsei % 256;
337
338 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
339}
340
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200341static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
342 uint16_t nsvci, uint16_t nsei)
343{
344 /* GPRS Network Service, PDU type: NS_RESET_ACK,
345 */
346 unsigned char msg[9] = {
347 0x03, 0x01, 0x82, 0x11, 0x22,
348 0x04, 0x82, 0x11, 0x22
349 };
350
351 msg[3] = nsvci / 256;
352 msg[4] = nsvci % 256;
353 msg[7] = nsei / 256;
354 msg[8] = nsei % 256;
355
356 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
357}
358
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200359static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
360{
361 /* GPRS Network Service, PDU type: NS_ALIVE */
362 unsigned char msg[1] = {
363 0x0a
364 };
365
366 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
367}
368
369static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
370{
371 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
372 unsigned char msg[1] = {
373 0x0b
374 };
375
376 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
377}
378
379static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
380{
381 /* GPRS Network Service, PDU type: NS_UNBLOCK */
382 unsigned char msg[1] = {
383 0x06
384 };
385
386 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
387}
388
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200389static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
390{
391 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
392 unsigned char msg[1] = {
393 0x07
394 };
395
396 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
397}
398
399static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
400 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200401 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
402{
403 /* GPRS Network Service, PDU type: NS_UNITDATA */
404 unsigned char msg[4096] = {
405 0x00, 0x00, 0x00, 0x00
406 };
407
408 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
409
410 msg[2] = nsbvci / 256;
411 msg[3] = nsbvci % 256;
412 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
413
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200414 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200415}
416
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200417static void send_bssgp_ul_unitdata(
418 struct gprs_ns_inst *nsi, const char *text,
419 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
420 struct gprs_ra_id *raid, uint16_t cell_id,
421 const uint8_t *llc_msg, size_t llc_msg_size)
422{
423 /* GPRS Network Service, PDU type: NS_UNITDATA */
424 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
425 unsigned char msg[4096] = {
426 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
427 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
428 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
429 };
430
431 size_t bssgp_msg_size = 23 + llc_msg_size;
432
433 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
434
435 gsm48_construct_ra(msg + 10, raid);
436 msg[1] = (uint8_t)(tlli >> 24);
437 msg[2] = (uint8_t)(tlli >> 16);
438 msg[3] = (uint8_t)(tlli >> 8);
439 msg[4] = (uint8_t)(tlli >> 0);
440 msg[16] = cell_id / 256;
441 msg[17] = cell_id % 256;
442 msg[21] = llc_msg_size / 256;
443 msg[22] = llc_msg_size % 256;
444 memcpy(msg + 23, llc_msg, llc_msg_size);
445
446 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
447 src_addr, nsbvci, msg, bssgp_msg_size);
448}
449
450static void send_bssgp_dl_unitdata(
451 struct gprs_ns_inst *nsi, const char *text,
452 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
453 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
454 const uint8_t *llc_msg, size_t llc_msg_size)
455{
456 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
457 unsigned char msg[4096] = {
458 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
459 0x16, 0x82, 0x02, 0x58,
460 };
461 unsigned char racap_drx[] = {
462 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
463 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
464 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
465 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
466 };
467
468 size_t bssgp_msg_size = 0;
469
470 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
471
472 msg[1] = (uint8_t)(tlli >> 24);
473 msg[2] = (uint8_t)(tlli >> 16);
474 msg[3] = (uint8_t)(tlli >> 8);
475 msg[4] = (uint8_t)(tlli >> 0);
476
477 bssgp_msg_size = 12;
478
479 if (with_racap_drx) {
480 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
481 bssgp_msg_size += sizeof(racap_drx);
482 }
483
484 if (imsi) {
485 OSMO_ASSERT(imsi_size <= 127);
486 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
487 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
488 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
489 bssgp_msg_size += 2 + imsi_size;
490 }
491
492 if ((bssgp_msg_size % 4) != 0) {
493 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
494 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
495 msg[bssgp_msg_size + 1] = 0x80 | abytes;
496 memset(msg + bssgp_msg_size + 2, 0, abytes);
497 bssgp_msg_size += 2 + abytes;
498 }
499
500 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
501 if (llc_msg_size < 128) {
502 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
503 bssgp_msg_size += 2;
504 } else {
505 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
506 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
507 bssgp_msg_size += 3;
508 }
509 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
510 bssgp_msg_size += llc_msg_size;
511
512
513 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
514 src_addr, nsbvci, msg, bssgp_msg_size);
515}
516
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200517static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
518 uint16_t bvci)
519{
520 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
521 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200522 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200523 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200524 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
525 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200526 };
527
528 msg[3] = bvci / 256;
529 msg[4] = bvci % 256;
530
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200531 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
532}
533
534static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
535 struct sockaddr_in *src_addr, uint16_t bvci)
536{
537 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
538 * BSSGP RESET_ACK */
539 static unsigned char msg[5] = {
540 0x23, 0x04, 0x82, 0x00,
541 0x00
542 };
543
544 msg[3] = bvci / 256;
545 msg[4] = bvci % 256;
546
547 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200548}
549
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200550static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
551 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200552 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200553 struct gprs_ra_id *raid)
554{
555 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
556 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200557 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
558 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200559 };
560
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200561 msg[3] = (uint8_t)(tlli >> 24);
562 msg[4] = (uint8_t)(tlli >> 16);
563 msg[5] = (uint8_t)(tlli >> 8);
564 msg[6] = (uint8_t)(tlli >> 0);
565
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200566 gsm48_construct_ra(msg + 9, raid);
567
568 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
569}
570
571static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
572 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200573 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200574 struct gprs_ra_id *raid)
575{
576 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
577 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200578 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
579 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200580 0x81, 0x01
581 };
582
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200583 msg[3] = (uint8_t)(tlli >> 24);
584 msg[4] = (uint8_t)(tlli >> 16);
585 msg[5] = (uint8_t)(tlli >> 8);
586 msg[6] = (uint8_t)(tlli >> 0);
587
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200588 gsm48_construct_ra(msg + 9, raid);
589
590 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
591}
592
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200593static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
594 struct sockaddr_in *src_addr,
595 uint16_t bvci, uint32_t tlli,
596 unsigned n_frames, unsigned n_octets)
597{
598 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
599 unsigned char msg[] = {
600 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
601 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
602 /* n octets */ 0xff, 0xff, 0xff
603 };
604
605 msg[3] = (uint8_t)(tlli >> 24);
606 msg[4] = (uint8_t)(tlli >> 16);
607 msg[5] = (uint8_t)(tlli >> 8);
608 msg[6] = (uint8_t)(tlli >> 0);
609 msg[9] = (uint8_t)(n_frames);
610 msg[12] = (uint8_t)(bvci >> 8);
611 msg[13] = (uint8_t)(bvci >> 0);
612 msg[16] = (uint8_t)(n_octets >> 16);
613 msg[17] = (uint8_t)(n_octets >> 8);
614 msg[18] = (uint8_t)(n_octets >> 0);
615
616 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
617}
618
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200619static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
620 struct sockaddr_in *src_addr,
621 uint16_t bvci, uint8_t tag)
622{
623 /* GPRS Network Service, PDU type: NS_UNITDATA,
624 * BSSGP FLOW_CONTROL_BVC */
625 unsigned char msg[] = {
626 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
627 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
628 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
629 };
630
631 msg[3] = tag;
632
633 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
634 msg, sizeof(msg));
635}
636
637static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
638 struct sockaddr_in *src_addr,
639 uint16_t bvci, uint8_t tag)
640{
641 /* GPRS Network Service, PDU type: NS_UNITDATA,
642 * BSSGP FLOW_CONTROL_BVC_ACK */
643 unsigned char msg[] = {
644 0x27, 0x1e, 0x81, /* Tag */ 0xce
645 };
646
647 msg[3] = tag;
648
649 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
650 msg, sizeof(msg));
651}
652
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200653static void send_llc_ul_ui(
654 struct gprs_ns_inst *nsi, const char *text,
655 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
656 struct gprs_ra_id *raid, uint16_t cell_id,
657 unsigned sapi, unsigned nu,
658 const uint8_t *msg, size_t msg_size)
659{
660 unsigned char llc_msg[4096] = {
661 0x00, 0xc0, 0x01
662 };
663
664 size_t llc_msg_size = 3 + msg_size + 3;
665 uint8_t e_bit = 0;
666 uint8_t pm_bit = 1;
667 unsigned fcs;
668
669 nu &= 0x01ff;
670
671 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
672
673 llc_msg[0] = (sapi & 0x0f);
674 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
675 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
676
677 memcpy(llc_msg + 3, msg, msg_size);
678
679 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
680 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
681 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
682 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
683
684 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
685 src_addr, nsbvci, tlli, raid, cell_id,
686 llc_msg, llc_msg_size);
687}
688
689static void send_llc_dl_ui(
690 struct gprs_ns_inst *nsi, const char *text,
691 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
692 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
693 unsigned sapi, unsigned nu,
694 const uint8_t *msg, size_t msg_size)
695{
696 /* GPRS Network Service, PDU type: NS_UNITDATA */
697 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
698 unsigned char llc_msg[4096] = {
699 0x00, 0x00, 0x01
700 };
701
702 size_t llc_msg_size = 3 + msg_size + 3;
703 uint8_t e_bit = 0;
704 uint8_t pm_bit = 1;
705 unsigned fcs;
706
707 nu &= 0x01ff;
708
709 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
710
711 llc_msg[0] = 0x40 | (sapi & 0x0f);
712 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
713 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
714
715 memcpy(llc_msg + 3, msg, msg_size);
716
717 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
718 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
719 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
720 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
721
722 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
723 src_addr, nsbvci, tlli,
724 with_racap_drx, imsi, imsi_size,
725 llc_msg, llc_msg_size);
726}
727
728
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200729static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
730 uint16_t nsvci, uint16_t nsei)
731{
732 printf("Setup NS-VC: remote 0x%08x:%d, "
733 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
734 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
735 nsvci, nsvci, nsei, nsei);
736
737 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
738 send_ns_alive(nsi, src_addr);
739 send_ns_unblock(nsi, src_addr);
740 send_ns_alive_ack(nsi, src_addr);
741}
742
743static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
744 uint16_t bvci)
745{
746 printf("Setup BSSGP: remote 0x%08x:%d, "
747 "BVCI 0x%04x(%d)\n\n",
748 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
749 bvci, bvci);
750
751 send_bssgp_reset(nsi, src_addr, bvci);
752}
753
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200754static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
755 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200756{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200757 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
758 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200759 send_ns_alive_ack(nsi, sgsn_peer);
760 send_ns_unblock_ack(nsi, sgsn_peer);
761 send_ns_alive(nsi, sgsn_peer);
762}
763
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200764static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
765{
766 sgsn_peer->sin_family = AF_INET;
767 sgsn_peer->sin_port = htons(32000);
768 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
769}
770
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200771static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
772{
773 sgsn_peer->sin_family = AF_INET;
774 sgsn_peer->sin_port = htons(32001);
775 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
776}
777
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200778static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
779{
780 size_t i;
781
782 for (i = 0; i < size; ++i) {
783 bss_peers[i].sin_family = AF_INET;
784 bss_peers[i].sin_port = htons((i + 1) * 1111);
785 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
786 }
787}
788
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200789int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
790 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
791
792/* override */
793int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
794 struct msgb *msg, uint16_t bvci)
795{
796 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
797 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200798 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200799
800 switch (event) {
801 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200802 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200803 default:
804 break;
805 }
806 return 0;
807}
808
809/* override */
810ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
811 const struct sockaddr *dest_addr, socklen_t addrlen)
812{
813 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
814 const struct sockaddr *, socklen_t);
815 static sendto_t real_sendto = NULL;
816 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200817 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200818
819 if (!real_sendto)
820 real_sendto = dlsym(RTLD_NEXT, "sendto");
821
822 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200823 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
824 dest_host, dest_port,
825 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200826 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200827 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
828 dest_host, dest_port,
829 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200830 else if (dest_host == REMOTE_SGSN2_ADDR)
831 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
832 dest_host, dest_port,
833 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200834 else
835 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
836
837 return len;
838}
839
840/* override */
841int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
842{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200843 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
844 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200845 uint16_t bvci = msgb_bvci(msg);
846 uint16_t nsei = msgb_nsei(msg);
847
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200848 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200849
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200850 if (!real_gprs_ns_sendmsg)
851 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
852
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200853 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200854 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
855 "msg length %d (%s)\n",
856 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200857 else if (nsei == SGSN2_NSEI)
858 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
859 "msg length %d (%s)\n",
860 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200861 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200862 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
863 "msg length %d (%s)\n",
864 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200865
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200866 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200867}
868
869static void dump_rate_ctr_group(FILE *stream, const char *prefix,
870 struct rate_ctr_group *ctrg)
871{
872 unsigned int i;
873
874 for (i = 0; i < ctrg->desc->num_ctr; i++) {
875 struct rate_ctr *ctr = &ctrg->ctr[i];
876 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
877 fprintf(stream, " %s%s: %llu%s",
878 prefix, ctrg->desc->ctr_desc[i].description,
879 (long long)ctr->current,
880 "\n");
881 };
882}
883
884/* Signal handler for signals from NS layer */
885static int test_signal(unsigned int subsys, unsigned int signal,
886 void *handler_data, void *signal_data)
887{
888 struct ns_signal_data *nssd = signal_data;
889 int rc;
890
891 if (subsys != SS_L_NS)
892 return 0;
893
894 switch (signal) {
895 case S_NS_RESET:
896 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
897 nssd->nsvc->nsvci,
898 gprs_ns_ll_str(nssd->nsvc));
899 break;
900
901 case S_NS_ALIVE_EXP:
902 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
903 nssd->nsvc->nsvci,
904 gprs_ns_ll_str(nssd->nsvc));
905 break;
906
907 case S_NS_BLOCK:
908 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
909 nssd->nsvc->nsvci,
910 gprs_ns_ll_str(nssd->nsvc));
911 break;
912
913 case S_NS_UNBLOCK:
914 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
915 nssd->nsvc->nsvci,
916 gprs_ns_ll_str(nssd->nsvc));
917 break;
918
919 case S_NS_REPLACED:
920 printf("==> got signal NS_REPLACED: 0x%04x/%s",
921 nssd->nsvc->nsvci,
922 gprs_ns_ll_str(nssd->nsvc));
923 printf(" -> 0x%04x/%s\n",
924 nssd->old_nsvc->nsvci,
925 gprs_ns_ll_str(nssd->old_nsvc));
926 break;
927
928 default:
929 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
930 nssd->nsvc->nsvci,
931 gprs_ns_ll_str(nssd->nsvc));
932 break;
933 }
934 printf("\n");
935 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
936 return rc;
937}
938
939static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
940{
941 struct msgb *msg;
942 int ret;
943 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
944 fprintf(stderr, "message too long: %d\n", data_len);
945 return -1;
946 }
947
948 msg = gprs_ns_msgb_alloc();
949 memmove(msg->data, data, data_len);
950 msg->l2h = msg->data;
951 msgb_put(msg, data_len);
952
953 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
954 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
955 osmo_hexdump(data, data_len));
956
957 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
958
959 printf("result (%s) = %d\n\n", text, ret);
960
961 msgb_free(msg);
962
963 return ret;
964}
965
966static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
967{
968 struct gprs_nsvc *nsvc;
969
970 printf("Current NS-VCIs:\n");
971 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
972 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200973 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200974 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200975 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
976 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
977 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978 );
979 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
980 }
981 printf("\n");
982}
983
984static void test_gbproxy()
985{
986 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
987 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200988 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200989
990 bssgp_nsi = nsi;
991 gbcfg.nsi = bssgp_nsi;
992 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
993
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200994 configure_sgsn_peer(&sgsn_peer);
995 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200996
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200997 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200998 printf("--- Initialise SGSN ---\n\n");
999
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001000 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001001 gprs_dump_nsi(nsi);
1002
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001003 printf("--- Initialise BSS 1 ---\n\n");
1004
1005 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1006 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1007 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001008 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001009
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001010 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1011
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001012 printf("--- Initialise BSS 2 ---\n\n");
1013
1014 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1015 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1016 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001017 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001018
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001019 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1020
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001021 printf("--- Move BSS 1 to new port ---\n\n");
1022
1023 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1024 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001025 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001026
1027 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1028
1029 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1030 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001031 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001032
1033 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1034
1035 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
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
1039 printf("--- Move BSS 2 to new port ---\n\n");
1040
1041 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1042 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001043 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001044
1045 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1046
1047 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1048 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001049 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001050
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001051 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1052
1053 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1054 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001055 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001056
1057 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1058
1059 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1060 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001061 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001062
1063 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1064
1065 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1066
1067 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1068 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001069 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001070
1071 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1072
1073 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1074
1075 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1076 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001077 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001078
1079 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1080
1081 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1082
1083 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1084
1085 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1086
1087 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1088
1089 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1090
1091 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1092
1093 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1094
1095 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1096
1097 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1098
1099 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1100
1101 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1102
1103 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1104
1105 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1106
1107 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1108 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001109 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001110
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001111 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001112
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001113 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1114
1115 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1116
1117 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1118
1119 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1120
1121 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1122
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001123 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1124
1125 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1126
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001127 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001128
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001129 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001130 gprs_ns_destroy(nsi);
1131 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001132}
1133
1134static void test_gbproxy_ident_changes()
1135{
1136 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1137 struct sockaddr_in bss_peer[1] = {{0},};
1138 struct sockaddr_in sgsn_peer= {0};
1139 uint16_t nsei[2] = {0x1000, 0x2000};
1140 uint16_t nsvci[2] = {0x1001, 0x2001};
1141 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1142
1143 bssgp_nsi = nsi;
1144 gbcfg.nsi = bssgp_nsi;
1145 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1146
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001147 configure_sgsn_peer(&sgsn_peer);
1148 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001149
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001150 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001151 printf("--- Initialise SGSN ---\n\n");
1152
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001153 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001154 gprs_dump_nsi(nsi);
1155
1156 printf("--- Initialise BSS 1 ---\n\n");
1157
1158 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1159 gprs_dump_nsi(nsi);
1160
1161 printf("--- Setup BVCI 1 ---\n\n");
1162
1163 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1164 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001165 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001166
1167 printf("--- Setup BVCI 2 ---\n\n");
1168
1169 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1170 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001171 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001172
1173 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1174
1175 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1176 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1177
1178 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1179
1180 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1181 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1182
1183 printf("--- Change NSEI ---\n\n");
1184
1185 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1186 gprs_dump_nsi(nsi);
1187
1188 printf("--- Setup BVCI 1 ---\n\n");
1189
1190 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1191 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001192 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001193
1194 printf("--- Setup BVCI 3 ---\n\n");
1195
1196 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1197 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001198 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001199
1200 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1201
1202 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1203 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1204
1205 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1206 " (should fail) ---\n\n");
1207
1208 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001209 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001210 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001211 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001212
1213 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1214
1215 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1216 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1217
1218 printf("--- Change NSVCI ---\n\n");
1219
1220 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1221 gprs_dump_nsi(nsi);
1222
1223 printf("--- Setup BVCI 1 ---\n\n");
1224
1225 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1226 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001227 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001228
1229 printf("--- Setup BVCI 4 ---\n\n");
1230
1231 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1232 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001233 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001234
1235 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1236
1237 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1238 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1239
1240 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1241 " (should fail) ---\n\n");
1242
1243 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001244 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001245 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001246 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001247
1248 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1249
1250 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1251 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1252
1253 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1254
1255 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1256 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1257
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001258 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001259 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001260
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001261 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001262 gprs_ns_destroy(nsi);
1263 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001264}
1265
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001266static void test_gbproxy_ra_patching()
1267{
1268 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1269 struct sockaddr_in bss_peer[1] = {{0},};
1270 struct sockaddr_in sgsn_peer= {0};
1271 struct gprs_ra_id rai_bss =
1272 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1273 struct gprs_ra_id rai_sgsn =
1274 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1275 struct gprs_ra_id rai_unknown =
1276 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001277 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001278 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001279 const uint32_t ptmsi = 0xefe2b700;
1280 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001281 const uint32_t foreign_tlli = 0xbbc54679;
1282 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001283 struct gbproxy_tlli_info *tlli_info;
1284 struct gbproxy_peer *peer;
1285
1286 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001287
1288 bssgp_nsi = nsi;
1289 gbcfg.nsi = bssgp_nsi;
1290 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001291 gbcfg.core_mcc = 123;
1292 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001293 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001294 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001295 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001296
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001297 configure_sgsn_peer(&sgsn_peer);
1298 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001299
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001300 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001301 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001302 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1303 gbcfg.match_re, err_msg);
1304 exit(1);
1305 }
1306
1307
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001308 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001309 printf("--- Initialise SGSN ---\n\n");
1310
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001311 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001312 gprs_dump_nsi(nsi);
1313
1314 printf("--- Initialise BSS 1 ---\n\n");
1315
1316 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1317 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1318 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001319 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001320
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001321 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001322 OSMO_ASSERT(peer != NULL);
1323
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001324 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1325
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001326 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1327 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001328
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001329 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001330 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001331
1332 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1333
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001334 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1335 foreign_tlli, &rai_bss, cell_id,
1336 GPRS_SAPI_GMM, 0,
1337 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001338
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001339 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1340 foreign_tlli, 0, NULL, 0,
1341 GPRS_SAPI_GMM, 0,
1342 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001343
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001344 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1345 foreign_tlli, &rai_bss, cell_id,
1346 GPRS_SAPI_GMM, 3,
1347 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001348
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001349 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1350 foreign_tlli, 1, imsi, sizeof(imsi),
1351 GPRS_SAPI_GMM, 1,
1352 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001353
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001354 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001355 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001356 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1357 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1358 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1359 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1360 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1361 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1362 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1363 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001364
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001365 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1366 local_tlli, &rai_bss, cell_id,
1367 GPRS_SAPI_GMM, 4,
1368 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001369
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001370 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001371 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001372 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1373 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1374 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1375 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1376 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1377 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1378 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1379 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001380
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001381 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001382 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1383 local_tlli, &rai_bss, cell_id,
1384 GPRS_SAPI_GMM, 3,
1385 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001386
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001387 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001388 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001389 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1390 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1391 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1392 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1393 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1394 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1395 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1396 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001397
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001398 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1399 local_tlli, 1, imsi, sizeof(imsi),
1400 GPRS_SAPI_GMM, 2,
1401 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001402
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001403 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001404 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001405 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1406 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1407 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1408 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001409
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001410 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001411 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1412 local_tlli, &rai_bss, cell_id,
1413 GPRS_SAPI_GMM, 3,
1414 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001415
Jacob Erlbeck73685282014-05-23 20:48:07 +02001416 gbcfg.core_apn[0] = 0;
1417 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001418
1419 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001420 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1421 local_tlli, &rai_bss, cell_id,
1422 GPRS_SAPI_GMM, 3,
1423 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001424
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001425 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001426
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001427 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001428 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1429 local_tlli, &rai_bss, cell_id,
1430 GPRS_SAPI_GMM, 6,
1431 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001432
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001433 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1434 local_tlli, 1, imsi, sizeof(imsi),
1435 GPRS_SAPI_GMM, 5,
1436 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001437
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001438 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001439
1440 printf("--- RA update ---\n\n");
1441
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001442 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1443 foreign_tlli, &rai_bss, 0x7080,
1444 GPRS_SAPI_GMM, 5,
1445 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001446
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001447 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1448 foreign_tlli, 1, imsi, sizeof(imsi),
1449 GPRS_SAPI_GMM, 6,
1450 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001451
1452 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001453 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1454 local_tlli, &rai_bss, cell_id,
1455 GPRS_SAPI_GMM, 3,
1456 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001457
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001458 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001459
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001460 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001461 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1462 local_tlli, &rai_bss, cell_id,
1463 GPRS_SAPI_GMM, 6,
1464 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001465
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001466 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001467 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001468
1469 printf("--- Bad cases ---\n\n");
1470
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001471 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001472 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1473 local_tlli, &rai_bss, cell_id,
1474 GPRS_SAPI_GMM, 3,
1475 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001476
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001477 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001478 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001479
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001480 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001481 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001482
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001483 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001484 gprs_ns_destroy(nsi);
1485 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001486}
1487
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001488static void test_gbproxy_ptmsi_patching()
1489{
1490 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1491 struct sockaddr_in bss_peer[1] = {{0},};
1492 struct sockaddr_in sgsn_peer= {0};
1493 struct gprs_ra_id rai_bss =
1494 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1495 struct gprs_ra_id rai_sgsn =
1496 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001497 struct gprs_ra_id rai_wrong_mcc_sgsn =
1498 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001499 struct gprs_ra_id rai_unknown =
1500 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1501 uint16_t cell_id = 0x1234;
1502
1503 const uint32_t sgsn_ptmsi = 0xefe2b700;
1504 const uint32_t local_sgsn_tlli = 0xefe2b700;
1505 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1506
1507 const uint32_t bss_ptmsi = 0xc00f7304;
1508 const uint32_t local_bss_tlli = 0xc00f7304;
1509 const uint32_t foreign_bss_tlli = 0x8000dead;
1510
1511 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1512 struct gbproxy_tlli_info *tlli_info;
1513 struct gbproxy_peer *peer;
1514 unsigned bss_nu = 0;
1515 unsigned sgsn_nu = 0;
1516
1517 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1518
1519 bssgp_nsi = nsi;
1520 gbcfg.nsi = bssgp_nsi;
1521 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1522 gbcfg.core_mcc = 123;
1523 gbcfg.core_mnc = 456;
1524 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1525 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1526 gbcfg.patch_ptmsi = 1;
1527 gbcfg.bss_ptmsi_state = 0;
1528 gbcfg.sgsn_tlli_state = 1;
1529
1530 configure_sgsn_peer(&sgsn_peer);
1531 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1532
1533 printf("=== %s ===\n", __func__);
1534 printf("--- Initialise SGSN ---\n\n");
1535
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001536 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001537
1538 printf("--- Initialise BSS 1 ---\n\n");
1539
1540 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1541 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1542
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001543 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001544 OSMO_ASSERT(peer != NULL);
1545
1546 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1547
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001548 gprs_dump_nsi(nsi);
1549 dump_global(stdout, 0);
1550 dump_peers(stdout, 0, 0, &gbcfg);
1551
1552 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1553
1554 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1555 foreign_bss_tlli, &rai_unknown, cell_id,
1556 GPRS_SAPI_GMM, bss_nu++,
1557 dtap_attach_req, sizeof(dtap_attach_req));
1558
1559 dump_peers(stdout, 0, 0, &gbcfg);
1560
1561 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1562 random_sgsn_tlli, 0, NULL, 0,
1563 GPRS_SAPI_GMM, sgsn_nu++,
1564 dtap_identity_req, sizeof(dtap_identity_req));
1565
1566 dump_peers(stdout, 0, 0, &gbcfg);
1567
1568 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1569 foreign_bss_tlli, &rai_bss, cell_id,
1570 GPRS_SAPI_GMM, bss_nu++,
1571 dtap_identity_resp, sizeof(dtap_identity_resp));
1572
1573 dump_peers(stdout, 0, 0, &gbcfg);
1574
1575 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1576 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1577 GPRS_SAPI_GMM, sgsn_nu++,
1578 dtap_attach_acc, sizeof(dtap_attach_acc));
1579
1580 dump_peers(stdout, 0, 0, &gbcfg);
1581
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001582 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001583 OSMO_ASSERT(tlli_info);
1584 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1585 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1586 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1587 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1588 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1589 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1590 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1591 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1592 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1593 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1594
1595 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1596 local_bss_tlli, &rai_bss, cell_id,
1597 GPRS_SAPI_GMM, bss_nu++,
1598 dtap_attach_complete, sizeof(dtap_attach_complete));
1599
1600 dump_peers(stdout, 0, 0, &gbcfg);
1601
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001602 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001603 OSMO_ASSERT(tlli_info);
1604 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1605 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1606 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1607 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1608 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1609 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1610 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1611 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1612
1613 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1614 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1615 GPRS_SAPI_GMM, sgsn_nu++,
1616 dtap_gmm_information, sizeof(dtap_gmm_information));
1617
1618 dump_peers(stdout, 0, 0, &gbcfg);
1619
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001620 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001621 OSMO_ASSERT(tlli_info);
1622 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1623 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1624 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1625 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1626
Jacob Erlbeck82add782014-09-05 18:08:12 +02001627 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1628 local_bss_tlli, &rai_bss, cell_id,
1629 GPRS_SAPI_GMM, bss_nu++,
1630 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1631
1632 dump_peers(stdout, 0, 0, &gbcfg);
1633
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001634 /* Non-DTAP */
1635 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1636 local_bss_tlli, &rai_bss, cell_id,
1637 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1638
1639 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1640 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1641 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1642
1643 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1644 local_bss_tlli, &rai_bss, cell_id,
1645 llc_ui_ll11_dns_query_ul,
1646 sizeof(llc_ui_ll11_dns_query_ul));
1647
1648 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1649 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1650 llc_ui_ll11_dns_resp_dl,
1651 sizeof(llc_ui_ll11_dns_resp_dl));
1652
1653 dump_peers(stdout, 0, 0, &gbcfg);
1654
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001655 /* Other messages */
1656 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1657 local_bss_tlli, 1, 12);
1658
1659 dump_peers(stdout, 0, 0, &gbcfg);
1660
1661 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1662
1663 dump_peers(stdout, 0, 0, &gbcfg);
1664
1665 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1666
1667 dump_peers(stdout, 0, 0, &gbcfg);
1668
1669 /* Bad case: Invalid BVCI */
1670 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1671 local_bss_tlli, 1, 12);
1672 dump_global(stdout, 0);
1673
1674 /* Bad case: Invalid RAI */
1675 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1676
1677 dump_global(stdout, 0);
1678
1679 /* Bad case: Invalid MCC (LAC ok) */
1680 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1681 &rai_wrong_mcc_sgsn);
1682
1683 dump_global(stdout, 0);
1684
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001685 /* Detach */
1686 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1687 local_bss_tlli, &rai_bss, cell_id,
1688 GPRS_SAPI_GMM, bss_nu++,
1689 dtap_detach_req, sizeof(dtap_detach_req));
1690
1691 dump_peers(stdout, 0, 0, &gbcfg);
1692
1693 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1694 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1695 GPRS_SAPI_GMM, sgsn_nu++,
1696 dtap_detach_acc, sizeof(dtap_detach_acc));
1697
1698 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001699
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001700 dump_global(stdout, 0);
1701
1702 gbprox_reset(&gbcfg);
1703 gprs_ns_destroy(nsi);
1704 nsi = NULL;
1705}
1706
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001707static void test_gbproxy_imsi_acquisition()
1708{
1709 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1710 struct sockaddr_in bss_peer[1] = {{0},};
1711 struct sockaddr_in sgsn_peer= {0};
1712 struct gprs_ra_id rai_bss =
1713 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1714 struct gprs_ra_id rai_sgsn =
1715 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1716 struct gprs_ra_id rai_wrong_mcc_sgsn =
1717 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1718 struct gprs_ra_id rai_unknown =
1719 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1720 uint16_t cell_id = 0x1234;
1721
1722 const uint32_t sgsn_ptmsi = 0xefe2b700;
1723 const uint32_t local_sgsn_tlli = 0xefe2b700;
1724 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1725
1726 const uint32_t bss_ptmsi = 0xc00f7304;
1727 const uint32_t local_bss_tlli = 0xc00f7304;
1728 const uint32_t foreign_bss_tlli = 0x8000dead;
1729
1730 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1731 struct gbproxy_tlli_info *tlli_info;
1732 struct gbproxy_peer *peer;
1733 unsigned bss_nu = 0;
1734 unsigned sgsn_nu = 0;
1735
1736 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1737
1738 bssgp_nsi = nsi;
1739 gbcfg.nsi = bssgp_nsi;
1740 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1741 gbcfg.core_mcc = 123;
1742 gbcfg.core_mnc = 456;
1743 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1744 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1745 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001746 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001747 gbcfg.bss_ptmsi_state = 0;
1748 gbcfg.sgsn_tlli_state = 1;
1749
1750 configure_sgsn_peer(&sgsn_peer);
1751 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1752
1753 printf("=== %s ===\n", __func__);
1754 printf("--- Initialise SGSN ---\n\n");
1755
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001756 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001757
1758 printf("--- Initialise BSS 1 ---\n\n");
1759
1760 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1761 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1762
1763 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1764 OSMO_ASSERT(peer != NULL);
1765
1766 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1767
1768 gprs_dump_nsi(nsi);
1769 dump_global(stdout, 0);
1770 dump_peers(stdout, 0, 0, &gbcfg);
1771
1772 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1773
1774 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1775 foreign_bss_tlli, &rai_unknown, cell_id,
1776 GPRS_SAPI_GMM, bss_nu++,
1777 dtap_attach_req, sizeof(dtap_attach_req));
1778
1779 dump_peers(stdout, 0, 0, &gbcfg);
1780
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001781 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1782 foreign_bss_tlli, &rai_bss, cell_id,
1783 GPRS_SAPI_GMM, bss_nu++,
1784 dtap_identity_resp, sizeof(dtap_identity_resp));
1785
1786 dump_peers(stdout, 0, 0, &gbcfg);
1787
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001788 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1789 random_sgsn_tlli, 0, NULL, 0,
1790 GPRS_SAPI_GMM, sgsn_nu++,
1791 dtap_identity_req, sizeof(dtap_identity_req));
1792
1793 dump_peers(stdout, 0, 0, &gbcfg);
1794
1795 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1796 foreign_bss_tlli, &rai_bss, cell_id,
1797 GPRS_SAPI_GMM, bss_nu++,
1798 dtap_identity_resp, sizeof(dtap_identity_resp));
1799
1800 dump_peers(stdout, 0, 0, &gbcfg);
1801
1802 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1803 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1804 GPRS_SAPI_GMM, sgsn_nu++,
1805 dtap_attach_acc, sizeof(dtap_attach_acc));
1806
1807 dump_peers(stdout, 0, 0, &gbcfg);
1808
1809 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1810 OSMO_ASSERT(tlli_info);
1811 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1812 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1813 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1814 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1815 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1816 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1817 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1818 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1819 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1820 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1821
1822 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1823 local_bss_tlli, &rai_bss, cell_id,
1824 GPRS_SAPI_GMM, bss_nu++,
1825 dtap_attach_complete, sizeof(dtap_attach_complete));
1826
1827 dump_peers(stdout, 0, 0, &gbcfg);
1828
1829 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1830 OSMO_ASSERT(tlli_info);
1831 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1832 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1833 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1834 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1835 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1836 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1837 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1838 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1839
1840 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1841 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1842 GPRS_SAPI_GMM, sgsn_nu++,
1843 dtap_gmm_information, sizeof(dtap_gmm_information));
1844
1845 dump_peers(stdout, 0, 0, &gbcfg);
1846
1847 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1848 OSMO_ASSERT(tlli_info);
1849 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1850 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1851 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1852 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1853
1854 /* Non-DTAP */
1855 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1856 local_bss_tlli, &rai_bss, cell_id,
1857 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1858
1859 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1860 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1861 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1862
1863 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1864 local_bss_tlli, &rai_bss, cell_id,
1865 llc_ui_ll11_dns_query_ul,
1866 sizeof(llc_ui_ll11_dns_query_ul));
1867
1868 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1869 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1870 llc_ui_ll11_dns_resp_dl,
1871 sizeof(llc_ui_ll11_dns_resp_dl));
1872
1873 dump_peers(stdout, 0, 0, &gbcfg);
1874
1875 /* Other messages */
1876 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1877 local_bss_tlli, 1, 12);
1878
1879 dump_peers(stdout, 0, 0, &gbcfg);
1880
1881 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
1882 local_sgsn_tlli, 1, 12);
1883
1884 dump_peers(stdout, 0, 0, &gbcfg);
1885
1886 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1887
1888 dump_peers(stdout, 0, 0, &gbcfg);
1889
1890 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1891
1892 dump_peers(stdout, 0, 0, &gbcfg);
1893
1894 /* Bad case: Invalid BVCI */
1895 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1896 local_bss_tlli, 1, 12);
1897 dump_global(stdout, 0);
1898
1899 /* Bad case: Invalid RAI */
1900 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1901
1902 dump_global(stdout, 0);
1903
1904 /* Bad case: Invalid MCC (LAC ok) */
1905 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1906 &rai_wrong_mcc_sgsn);
1907
1908 dump_global(stdout, 0);
1909
1910 /* Detach */
1911 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1912 local_bss_tlli, &rai_bss, cell_id,
1913 GPRS_SAPI_GMM, bss_nu++,
1914 dtap_detach_req, sizeof(dtap_detach_req));
1915
1916 dump_peers(stdout, 0, 0, &gbcfg);
1917
1918 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1919 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1920 GPRS_SAPI_GMM, sgsn_nu++,
1921 dtap_detach_acc, sizeof(dtap_detach_acc));
1922
1923 dump_peers(stdout, 0, 0, &gbcfg);
1924
1925 dump_global(stdout, 0);
1926
1927 gbprox_reset(&gbcfg);
1928 gprs_ns_destroy(nsi);
1929 nsi = NULL;
1930}
1931
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001932static void test_gbproxy_secondary_sgsn()
1933{
1934 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1935 struct sockaddr_in bss_peer[1] = {{0},};
1936 struct sockaddr_in sgsn_peer[2]= {{0},};
1937 struct gprs_ra_id rai_bss =
1938 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1939 struct gprs_ra_id rai_sgsn =
1940 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1941 struct gprs_ra_id rai_unknown =
1942 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1943 uint16_t cell_id = 0x1234;
1944
1945 const uint32_t sgsn_ptmsi = 0xefe2b700;
1946 const uint32_t local_sgsn_tlli = 0xefe2b700;
1947 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1948
1949 const uint32_t bss_ptmsi = 0xc00f7304;
1950 const uint32_t local_bss_tlli = 0xc00f7304;
1951 const uint32_t foreign_bss_tlli = 0x8000dead;
1952
1953 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1954 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1955 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
1956 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1957 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1958 const uint32_t foreign_bss_tlli2 = 0x8000beef;
1959
1960 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1961 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1962 struct gbproxy_tlli_info *tlli_info;
1963 struct gbproxy_peer *peer;
1964 unsigned bss_nu = 0;
1965 unsigned sgsn_nu = 0;
1966
1967 const char *err_msg = NULL;
1968 const char *filter_re = "999999";
1969
1970 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1971 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1972
1973 bssgp_nsi = nsi;
1974 gbcfg.nsi = bssgp_nsi;
1975 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1976 gbcfg.core_mcc = 123;
1977 gbcfg.core_mnc = 456;
1978 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1979 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1980 gbcfg.patch_ptmsi = 1;
1981 gbcfg.acquire_imsi = 1;
1982 gbcfg.bss_ptmsi_state = 0;
1983 gbcfg.sgsn_tlli_state = 1;
1984 gbcfg.route_to_sgsn2 = 1;
1985 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
1986
1987 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
1988 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
1989 err_msg);
1990 OSMO_ASSERT(err_msg == NULL);
1991 }
1992
1993 configure_sgsn_peer(&sgsn_peer[0]);
1994 configure_sgsn2_peer(&sgsn_peer[1]);
1995 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1996
1997 printf("=== %s ===\n", __func__);
1998 printf("--- Initialise SGSN 1 ---\n\n");
1999
2000 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2001
2002 printf("--- Initialise SGSN 2 ---\n\n");
2003
2004 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2005
2006 printf("--- Initialise BSS 1 ---\n\n");
2007
2008 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2009 setup_bssgp(nsi, &bss_peer[0], 0x0);
2010 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2011 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2012 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2013 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2014
2015 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2016 OSMO_ASSERT(peer != NULL);
2017
2018 gprs_dump_nsi(nsi);
2019 dump_global(stdout, 0);
2020 dump_peers(stdout, 0, 0, &gbcfg);
2021
2022 printf("--- Flow control ---\n\n");
2023
2024 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2025 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2026 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2027
2028 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2029
2030 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2031 foreign_bss_tlli, &rai_unknown, cell_id,
2032 GPRS_SAPI_GMM, bss_nu++,
2033 dtap_attach_req, sizeof(dtap_attach_req));
2034
2035 dump_peers(stdout, 0, 0, &gbcfg);
2036
2037 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2038 foreign_bss_tlli, &rai_bss, cell_id,
2039 GPRS_SAPI_GMM, bss_nu++,
2040 dtap_identity_resp, sizeof(dtap_identity_resp));
2041
2042 dump_peers(stdout, 0, 0, &gbcfg);
2043
2044 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2045 random_sgsn_tlli, 0, NULL, 0,
2046 GPRS_SAPI_GMM, sgsn_nu++,
2047 dtap_identity_req, sizeof(dtap_identity_req));
2048
2049 dump_peers(stdout, 0, 0, &gbcfg);
2050
2051 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2052 foreign_bss_tlli, &rai_bss, cell_id,
2053 GPRS_SAPI_GMM, bss_nu++,
2054 dtap_identity_resp, sizeof(dtap_identity_resp));
2055
2056 dump_peers(stdout, 0, 0, &gbcfg);
2057
2058 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2059 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2060 GPRS_SAPI_GMM, sgsn_nu++,
2061 dtap_attach_acc, sizeof(dtap_attach_acc));
2062
2063 dump_peers(stdout, 0, 0, &gbcfg);
2064
2065 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2066 OSMO_ASSERT(tlli_info);
2067 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2068 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2069 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2070 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2071 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2072 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2073 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2074 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2075 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2076 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2077
2078 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2079 local_bss_tlli, &rai_bss, cell_id,
2080 GPRS_SAPI_GMM, bss_nu++,
2081 dtap_attach_complete, sizeof(dtap_attach_complete));
2082
2083 dump_peers(stdout, 0, 0, &gbcfg);
2084
2085 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2086 OSMO_ASSERT(tlli_info);
2087 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2088 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2089 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2090 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2091 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2092 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2093 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2094 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2095
2096 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2097 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2098 GPRS_SAPI_GMM, sgsn_nu++,
2099 dtap_gmm_information, sizeof(dtap_gmm_information));
2100
2101 dump_peers(stdout, 0, 0, &gbcfg);
2102
2103 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2104 OSMO_ASSERT(tlli_info);
2105 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2106 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2107 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2108 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2109
2110 /* Non-DTAP */
2111 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2112 local_bss_tlli, &rai_bss, cell_id,
2113 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2114
2115 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2116 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2117 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2118
2119 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2120 local_bss_tlli, &rai_bss, cell_id,
2121 llc_ui_ll11_dns_query_ul,
2122 sizeof(llc_ui_ll11_dns_query_ul));
2123
2124 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2125 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2126 llc_ui_ll11_dns_resp_dl,
2127 sizeof(llc_ui_ll11_dns_resp_dl));
2128
2129 dump_peers(stdout, 0, 0, &gbcfg);
2130
2131 /* Other messages */
2132 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2133 local_bss_tlli, 1, 12);
2134
2135 dump_peers(stdout, 0, 0, &gbcfg);
2136
2137 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2138 local_sgsn_tlli, 1, 12);
2139
2140 dump_peers(stdout, 0, 0, &gbcfg);
2141
2142 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2143
2144 dump_peers(stdout, 0, 0, &gbcfg);
2145
2146 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2147
2148 dump_peers(stdout, 0, 0, &gbcfg);
2149
2150 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2151
2152 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2153 foreign_bss_tlli2, &rai_unknown, cell_id,
2154 GPRS_SAPI_GMM, bss_nu++,
2155 dtap_attach_req, sizeof(dtap_attach_req));
2156
2157 dump_peers(stdout, 0, 0, &gbcfg);
2158
2159 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2160 foreign_bss_tlli2, &rai_bss, cell_id,
2161 GPRS_SAPI_GMM, bss_nu++,
2162 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2163
2164 dump_peers(stdout, 0, 0, &gbcfg);
2165
2166 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2167 random_sgsn_tlli2, 0, NULL, 0,
2168 GPRS_SAPI_GMM, sgsn_nu++,
2169 dtap_identity_req, sizeof(dtap_identity_req));
2170
2171 dump_peers(stdout, 0, 0, &gbcfg);
2172
2173 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2174 foreign_bss_tlli2, &rai_bss, cell_id,
2175 GPRS_SAPI_GMM, bss_nu++,
2176 dtap_identity_resp, sizeof(dtap_identity_resp));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
2180 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2181 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2182 GPRS_SAPI_GMM, sgsn_nu++,
2183 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2184
2185 dump_peers(stdout, 0, 0, &gbcfg);
2186
2187 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2188 OSMO_ASSERT(tlli_info);
2189 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2190 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2191 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2192 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2193 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2194 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2195 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2196 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2197 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2198 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2199
2200 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2201 local_bss_tlli2, &rai_bss, cell_id,
2202 GPRS_SAPI_GMM, bss_nu++,
2203 dtap_attach_complete, sizeof(dtap_attach_complete));
2204
2205 dump_peers(stdout, 0, 0, &gbcfg);
2206
2207 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2208 OSMO_ASSERT(tlli_info);
2209 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2210 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2211 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2212 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2213 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2214 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2215 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2216 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2217
2218 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2219 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2220 GPRS_SAPI_GMM, sgsn_nu++,
2221 dtap_gmm_information, sizeof(dtap_gmm_information));
2222
2223 dump_peers(stdout, 0, 0, &gbcfg);
2224
2225 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2226 OSMO_ASSERT(tlli_info);
2227 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2228 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2229 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2230 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2231
2232 /* Non-DTAP */
2233 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2234 local_bss_tlli2, &rai_bss, cell_id,
2235 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2236
2237 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2238 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2239 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2240
2241 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2242 local_bss_tlli2, &rai_bss, cell_id,
2243 llc_ui_ll11_dns_query_ul,
2244 sizeof(llc_ui_ll11_dns_query_ul));
2245
2246 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2247 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2248 llc_ui_ll11_dns_resp_dl,
2249 sizeof(llc_ui_ll11_dns_resp_dl));
2250
2251 dump_peers(stdout, 0, 0, &gbcfg);
2252
2253 /* Other messages */
2254 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2255 local_bss_tlli2, 1, 12);
2256
2257 dump_peers(stdout, 0, 0, &gbcfg);
2258
2259 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2260 local_sgsn_tlli2, 1, 12);
2261
2262 dump_peers(stdout, 0, 0, &gbcfg);
2263
2264 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2265
2266 dump_peers(stdout, 0, 0, &gbcfg);
2267
2268 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2269
2270 dump_peers(stdout, 0, 0, &gbcfg);
2271
2272 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2273
2274 /* Detach */
2275 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2276 local_bss_tlli, &rai_bss, cell_id,
2277 GPRS_SAPI_GMM, bss_nu++,
2278 dtap_detach_req, sizeof(dtap_detach_req));
2279
2280 dump_peers(stdout, 0, 0, &gbcfg);
2281
2282 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2283 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2284 GPRS_SAPI_GMM, sgsn_nu++,
2285 dtap_detach_acc, sizeof(dtap_detach_acc));
2286
2287 dump_peers(stdout, 0, 0, &gbcfg);
2288
2289 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2290
2291 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2292 local_bss_tlli2, &rai_bss, cell_id,
2293 GPRS_SAPI_GMM, bss_nu++,
2294 dtap_detach_req, sizeof(dtap_detach_req));
2295
2296 dump_peers(stdout, 0, 0, &gbcfg);
2297
2298 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2299 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2300 GPRS_SAPI_GMM, sgsn_nu++,
2301 dtap_detach_acc, sizeof(dtap_detach_acc));
2302
2303 dump_peers(stdout, 0, 0, &gbcfg);
2304
2305 dump_global(stdout, 0);
2306
2307 gbprox_reset(&gbcfg);
2308 gprs_ns_destroy(nsi);
2309 nsi = NULL;
2310}
2311
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002312/* TODO: Move tlv testing to libosmocore */
2313int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2314int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2315 uint8_t **value);
2316int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2317 size_t *value_len);
2318int lv_shift(uint8_t **data, size_t *data_len,
2319 uint8_t **value, size_t *value_len);
2320
2321static void check_tlv_match(uint8_t **data, size_t *data_len,
2322 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2323{
2324 uint8_t *value;
2325 size_t value_len;
2326 int rc;
2327
2328 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2329 OSMO_ASSERT(rc == 0);
2330
2331 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002332 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002333 OSMO_ASSERT(value_len == exp_len);
2334 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2335}
2336
2337static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2338 uint8_t tag, size_t len, const uint8_t *exp_val)
2339{
2340 uint8_t *value;
2341 int rc;
2342
2343 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2344 OSMO_ASSERT(rc == 0);
2345
2346 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002347 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002348 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2349}
2350
2351static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2352 size_t len, const uint8_t *exp_val)
2353{
2354 uint8_t *value;
2355 int rc;
2356
2357 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002358 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002359 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2360}
2361
2362static void check_lv_shift(uint8_t **data, size_t *data_len,
2363 size_t exp_len, const uint8_t *exp_val)
2364{
2365 uint8_t *value;
2366 size_t value_len;
2367 int rc;
2368
2369 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002370 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002371 OSMO_ASSERT(value_len == exp_len);
2372 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2373}
2374
2375static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2376 const uint8_t *test_data)
2377{
2378 uint8_t buf[300] = {0};
2379
2380 uint8_t *unchanged_ptr = buf - 1;
2381 size_t unchanged_len = 0xdead;
2382 size_t tmp_data_len = data_len;
2383 uint8_t *value = unchanged_ptr;
2384 size_t value_len = unchanged_len;
2385 uint8_t *data = buf;
2386
2387 OSMO_ASSERT(data_len <= sizeof(buf));
2388
2389 tlv_put(data, tag, len, test_data);
2390 if (data_len < len + 2) {
2391 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2392 tag, &value, &value_len));
2393 OSMO_ASSERT(tmp_data_len == 0);
2394 OSMO_ASSERT(data == buf + data_len);
2395 OSMO_ASSERT(value == unchanged_ptr);
2396 OSMO_ASSERT(value_len == unchanged_len);
2397 } else {
2398 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2399 tag, &value, &value_len));
2400 OSMO_ASSERT(value != unchanged_ptr);
2401 OSMO_ASSERT(value_len != unchanged_len);
2402 }
2403}
2404
2405static void check_tv_fixed_match_data_len(size_t data_len,
2406 uint8_t tag, size_t len,
2407 const uint8_t *test_data)
2408{
2409 uint8_t buf[300] = {0};
2410
2411 uint8_t *unchanged_ptr = buf - 1;
2412 size_t tmp_data_len = data_len;
2413 uint8_t *value = unchanged_ptr;
2414 uint8_t *data = buf;
2415
2416 OSMO_ASSERT(data_len <= sizeof(buf));
2417
2418 tv_fixed_put(data, tag, len, test_data);
2419
2420 if (data_len < len + 1) {
2421 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2422 tag, len, &value));
2423 OSMO_ASSERT(tmp_data_len == 0);
2424 OSMO_ASSERT(data == buf + data_len);
2425 OSMO_ASSERT(value == unchanged_ptr);
2426 } else {
2427 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2428 tag, len, &value));
2429 OSMO_ASSERT(value != unchanged_ptr);
2430 }
2431}
2432
2433static void check_v_fixed_shift_data_len(size_t data_len,
2434 size_t len, const uint8_t *test_data)
2435{
2436 uint8_t buf[300] = {0};
2437
2438 uint8_t *unchanged_ptr = buf - 1;
2439 size_t tmp_data_len = data_len;
2440 uint8_t *value = unchanged_ptr;
2441 uint8_t *data = buf;
2442
2443 OSMO_ASSERT(data_len <= sizeof(buf));
2444
2445 memcpy(data, test_data, len);
2446
2447 if (data_len < len) {
2448 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2449 len, &value));
2450 OSMO_ASSERT(tmp_data_len == 0);
2451 OSMO_ASSERT(data == buf + data_len);
2452 OSMO_ASSERT(value == unchanged_ptr);
2453 } else {
2454 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2455 len, &value));
2456 OSMO_ASSERT(value != unchanged_ptr);
2457 }
2458}
2459
2460static void check_lv_shift_data_len(size_t data_len,
2461 size_t len, const uint8_t *test_data)
2462{
2463 uint8_t buf[300] = {0};
2464
2465 uint8_t *unchanged_ptr = buf - 1;
2466 size_t unchanged_len = 0xdead;
2467 size_t tmp_data_len = data_len;
2468 uint8_t *value = unchanged_ptr;
2469 size_t value_len = unchanged_len;
2470 uint8_t *data = buf;
2471
2472 lv_put(data, len, test_data);
2473 if (data_len < len + 1) {
2474 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2475 &value, &value_len));
2476 OSMO_ASSERT(tmp_data_len == 0);
2477 OSMO_ASSERT(data == buf + data_len);
2478 OSMO_ASSERT(value == unchanged_ptr);
2479 OSMO_ASSERT(value_len == unchanged_len);
2480 } else {
2481 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2482 &value, &value_len));
2483 OSMO_ASSERT(value != unchanged_ptr);
2484 OSMO_ASSERT(value_len != unchanged_len);
2485 }
2486}
2487
2488static void test_tlv_shift_functions()
2489{
2490 uint8_t test_data[1024];
2491 uint8_t buf[1024];
2492 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002493 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002494 uint8_t *data;
2495 size_t data_len;
2496 const uint8_t tag = 0x1a;
2497
2498 printf("Test shift functions\n");
2499
2500 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2501 test_data[i] = (uint8_t)i;
2502
2503 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002504 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002505
2506 memset(buf, 0xee, sizeof(buf));
2507 data_end = data = buf;
2508
2509 for (i = 0; i < iterations; i++) {
2510 data_end = tlv_put(data_end, tag, len, test_data);
2511 data_end = tv_fixed_put(data_end, tag, len, test_data);
2512 /* v_fixed_put */
2513 memcpy(data_end, test_data, len);
2514 data_end += len;
2515 data_end = lv_put(data_end, len, test_data);
2516 }
2517
2518 data_len = data_end - data;
2519 OSMO_ASSERT(data_len <= sizeof(buf));
2520
2521 for (i = 0; i < iterations; i++) {
2522 check_tlv_match(&data, &data_len, tag, len, test_data);
2523 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2524 check_v_fixed_shift(&data, &data_len, len, test_data);
2525 check_lv_shift(&data, &data_len, len, test_data);
2526 }
2527
2528 OSMO_ASSERT(data == data_end);
2529
2530 /* Test at end of data */
2531
2532 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2533 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2534 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2535 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2536
2537 /* Test invalid data_len */
2538 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2539 check_tlv_match_data_len(data_len, tag, len, test_data);
2540 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2541 check_v_fixed_shift_data_len(data_len, len, test_data);
2542 check_lv_shift_data_len(data_len, len, test_data);
2543 }
2544 }
2545}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002546
2547static void test_gbproxy_tlli_expire(void)
2548{
2549 struct gbproxy_config cfg = {0};
2550 struct gbproxy_peer *peer;
2551 const char *err_msg = NULL;
2552 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2553 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002554 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002555 const uint32_t tlli1 = 1234 | 0xc0000000;
2556 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002557 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002558 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002559 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002560
2561 printf("Test TLLI info expiry\n\n");
2562
2563 gbproxy_init_config(&cfg);
2564
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002565 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002566 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2567 err_msg);
2568 OSMO_ASSERT(err_msg == NULL);
2569 }
2570
2571 {
2572 struct gbproxy_tlli_info *tlli_info;
2573
2574 printf("Test TLLI replacement:\n");
2575
2576 cfg.tlli_max_len = 0;
2577 cfg.tlli_max_age = 0;
2578 peer = gbproxy_peer_alloc(&cfg, 20);
2579 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2580
2581 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002582 tlli_info = gbproxy_register_tlli(peer, tlli1,
2583 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002584 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002585 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002586 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2587
2588 /* replace the old entry */
2589 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002590 tlli_info = gbproxy_register_tlli(peer, tlli2,
2591 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002592 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002593 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002594 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2595
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002596 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002597
2598 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002599 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002600 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002601 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002602 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002603 OSMO_ASSERT(!tlli_info);
2604
2605 printf("\n");
2606
2607 gbproxy_peer_free(peer);
2608 }
2609
2610 {
2611 struct gbproxy_tlli_info *tlli_info;
2612
2613 printf("Test IMSI replacement:\n");
2614
2615 cfg.tlli_max_len = 0;
2616 cfg.tlli_max_age = 0;
2617 peer = gbproxy_peer_alloc(&cfg, 20);
2618 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2619
2620 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002621 tlli_info = gbproxy_register_tlli(peer, tlli1,
2622 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002623 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002624 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002625 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2626
2627 /* try to replace the old entry */
2628 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002629 tlli_info = gbproxy_register_tlli(peer, tlli1,
2630 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002631 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002632 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002633 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2634
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002635 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002636
2637 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002638 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002639 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002640 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002641 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002642 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002643
2644 printf("\n");
2645
2646 gbproxy_peer_free(peer);
2647 }
2648
2649 {
2650 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002651 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002652
2653 printf("Test TLLI expiry, max_len == 1:\n");
2654
2655 cfg.tlli_max_len = 1;
2656 cfg.tlli_max_age = 0;
2657 peer = gbproxy_peer_alloc(&cfg, 20);
2658 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2659
2660 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002661 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002662 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2663
2664 /* replace the old entry */
2665 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002666 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002667 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2668
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002669 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002670 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002671 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2672
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002673 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002674
2675 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002676 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002677 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002678 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002679 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002680 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002681
2682 printf("\n");
2683
2684 gbproxy_peer_free(peer);
2685 }
2686
2687 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002688 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002689 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002690
2691 printf("Test TLLI expiry, max_age == 1:\n");
2692
2693 cfg.tlli_max_len = 0;
2694 cfg.tlli_max_age = 1;
2695 peer = gbproxy_peer_alloc(&cfg, 20);
2696 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2697
2698 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002699 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002700 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2701
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002702 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002703 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002704 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002705 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2706
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002707 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002708 OSMO_ASSERT(num_removed == 1);
2709 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2710
2711 dump_peers(stdout, 2, now + 2, &cfg);
2712
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002713 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002714 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002715 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002716 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002717 OSMO_ASSERT(tlli_info);
2718 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2719
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002720 printf("\n");
2721
2722 gbproxy_peer_free(peer);
2723 }
2724
2725 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002726 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002727 int num_removed;
2728
2729 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2730
2731 cfg.tlli_max_len = 0;
2732 cfg.tlli_max_age = 1;
2733 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002734 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2735
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002736 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002737 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002738 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2739
2740 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002741 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002742 now + 1);
2743 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2744
2745 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002746 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2747 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002748 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2749
2750 dump_peers(stdout, 2, now + 2, &cfg);
2751
2752 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002753 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002754 OSMO_ASSERT(num_removed == 2);
2755 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2756
2757 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002758
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002759 /* verify that tlli3 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002760 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002761 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002762 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002763 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002764 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002765 OSMO_ASSERT(tlli_info);
2766 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2767
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002768 printf("\n");
2769
2770 gbproxy_peer_free(peer);
2771 }
2772}
2773
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002774static void test_gbproxy_imsi_matching(void)
2775{
2776 struct gbproxy_config cfg = {0};
2777 struct gbproxy_peer *peer;
2778 const char *err_msg = NULL;
2779 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2780 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2781 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2782 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2783 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2784 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2785 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2786 const char *filter_re1 = ".*";
2787 const char *filter_re2 = "^1234";
2788 const char *filter_re3 = "^4321";
2789 const char *filter_re4_bad = "^12[";
2790
2791 printf("=== Test IMSI/TMSI matching ===\n\n");
2792
2793 gbproxy_init_config(&cfg);
2794 OSMO_ASSERT(cfg.check_imsi == 0);
2795
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002796 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002797 OSMO_ASSERT(cfg.check_imsi == 1);
2798
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002799 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002800 OSMO_ASSERT(cfg.check_imsi == 1);
2801
2802 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002803 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002804 OSMO_ASSERT(err_msg != NULL);
2805 OSMO_ASSERT(cfg.check_imsi == 0);
2806
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002807 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002808 OSMO_ASSERT(cfg.check_imsi == 1);
2809
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002810 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002811 OSMO_ASSERT(cfg.check_imsi == 0);
2812
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002813 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002814 OSMO_ASSERT(cfg.check_imsi == 1);
2815
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002816 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002817 OSMO_ASSERT(cfg.check_imsi == 0);
2818
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002819 peer = gbproxy_peer_alloc(&cfg, 20);
2820
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002821 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002822 OSMO_ASSERT(cfg.check_imsi == 1);
2823
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002824 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2825 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002826 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002827 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002828 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002829 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2830 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2831 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2832 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2833 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002834
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002835 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002836 OSMO_ASSERT(cfg.check_imsi == 1);
2837
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002838 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2839 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2840 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2841 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2842 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2843 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2844 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002845
2846 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2847
2848 gbproxy_peer_free(peer);
2849}
2850
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002851static struct log_info_cat gprs_categories[] = {
2852 [DGPRS] = {
2853 .name = "DGPRS",
2854 .description = "GPRS Packet Service",
2855 .enabled = 1, .loglevel = LOGL_DEBUG,
2856 },
2857 [DNS] = {
2858 .name = "DNS",
2859 .description = "GPRS Network Service (NS)",
2860 .enabled = 1, .loglevel = LOGL_INFO,
2861 },
2862 [DBSSGP] = {
2863 .name = "DBSSGP",
2864 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2865 .enabled = 1, .loglevel = LOGL_DEBUG,
2866 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002867};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002868
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002869static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002870 .cat = gprs_categories,
2871 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002872};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002873
2874int main(int argc, char **argv)
2875{
2876 osmo_init_logging(&info);
2877 log_set_use_color(osmo_stderr_target, 0);
2878 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02002879 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002880
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002881 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002882 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
2883 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002884
2885 rate_ctr_init(NULL);
2886
2887 setlinebuf(stdout);
2888
2889 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02002890 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002891 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002892 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002893 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002894 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02002895 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002896 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002897 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002898 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002899 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002900 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002901
2902 exit(EXIT_SUCCESS);
2903}