blob: 12dc914574614ab46947f784d5e0cacc513d02d5 [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
1627 /* Non-DTAP */
1628 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1629 local_bss_tlli, &rai_bss, cell_id,
1630 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1631
1632 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1633 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1634 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1635
1636 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1637 local_bss_tlli, &rai_bss, cell_id,
1638 llc_ui_ll11_dns_query_ul,
1639 sizeof(llc_ui_ll11_dns_query_ul));
1640
1641 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1642 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1643 llc_ui_ll11_dns_resp_dl,
1644 sizeof(llc_ui_ll11_dns_resp_dl));
1645
1646 dump_peers(stdout, 0, 0, &gbcfg);
1647
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001648 /* Other messages */
1649 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1650 local_bss_tlli, 1, 12);
1651
1652 dump_peers(stdout, 0, 0, &gbcfg);
1653
1654 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1655
1656 dump_peers(stdout, 0, 0, &gbcfg);
1657
1658 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1659
1660 dump_peers(stdout, 0, 0, &gbcfg);
1661
1662 /* Bad case: Invalid BVCI */
1663 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1664 local_bss_tlli, 1, 12);
1665 dump_global(stdout, 0);
1666
1667 /* Bad case: Invalid RAI */
1668 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1669
1670 dump_global(stdout, 0);
1671
1672 /* Bad case: Invalid MCC (LAC ok) */
1673 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1674 &rai_wrong_mcc_sgsn);
1675
1676 dump_global(stdout, 0);
1677
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001678 /* Detach */
1679 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1680 local_bss_tlli, &rai_bss, cell_id,
1681 GPRS_SAPI_GMM, bss_nu++,
1682 dtap_detach_req, sizeof(dtap_detach_req));
1683
1684 dump_peers(stdout, 0, 0, &gbcfg);
1685
1686 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1687 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1688 GPRS_SAPI_GMM, sgsn_nu++,
1689 dtap_detach_acc, sizeof(dtap_detach_acc));
1690
1691 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001692
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001693 dump_global(stdout, 0);
1694
1695 gbprox_reset(&gbcfg);
1696 gprs_ns_destroy(nsi);
1697 nsi = NULL;
1698}
1699
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001700static void test_gbproxy_imsi_acquisition()
1701{
1702 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1703 struct sockaddr_in bss_peer[1] = {{0},};
1704 struct sockaddr_in sgsn_peer= {0};
1705 struct gprs_ra_id rai_bss =
1706 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1707 struct gprs_ra_id rai_sgsn =
1708 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1709 struct gprs_ra_id rai_wrong_mcc_sgsn =
1710 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1711 struct gprs_ra_id rai_unknown =
1712 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1713 uint16_t cell_id = 0x1234;
1714
1715 const uint32_t sgsn_ptmsi = 0xefe2b700;
1716 const uint32_t local_sgsn_tlli = 0xefe2b700;
1717 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1718
1719 const uint32_t bss_ptmsi = 0xc00f7304;
1720 const uint32_t local_bss_tlli = 0xc00f7304;
1721 const uint32_t foreign_bss_tlli = 0x8000dead;
1722
1723 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1724 struct gbproxy_tlli_info *tlli_info;
1725 struct gbproxy_peer *peer;
1726 unsigned bss_nu = 0;
1727 unsigned sgsn_nu = 0;
1728
1729 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1730
1731 bssgp_nsi = nsi;
1732 gbcfg.nsi = bssgp_nsi;
1733 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1734 gbcfg.core_mcc = 123;
1735 gbcfg.core_mnc = 456;
1736 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1737 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1738 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001739 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001740 gbcfg.bss_ptmsi_state = 0;
1741 gbcfg.sgsn_tlli_state = 1;
1742
1743 configure_sgsn_peer(&sgsn_peer);
1744 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1745
1746 printf("=== %s ===\n", __func__);
1747 printf("--- Initialise SGSN ---\n\n");
1748
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001749 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001750
1751 printf("--- Initialise BSS 1 ---\n\n");
1752
1753 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1754 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1755
1756 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1757 OSMO_ASSERT(peer != NULL);
1758
1759 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1760
1761 gprs_dump_nsi(nsi);
1762 dump_global(stdout, 0);
1763 dump_peers(stdout, 0, 0, &gbcfg);
1764
1765 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1766
1767 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1768 foreign_bss_tlli, &rai_unknown, cell_id,
1769 GPRS_SAPI_GMM, bss_nu++,
1770 dtap_attach_req, sizeof(dtap_attach_req));
1771
1772 dump_peers(stdout, 0, 0, &gbcfg);
1773
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001774 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1775 foreign_bss_tlli, &rai_bss, cell_id,
1776 GPRS_SAPI_GMM, bss_nu++,
1777 dtap_identity_resp, sizeof(dtap_identity_resp));
1778
1779 dump_peers(stdout, 0, 0, &gbcfg);
1780
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001781 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1782 random_sgsn_tlli, 0, NULL, 0,
1783 GPRS_SAPI_GMM, sgsn_nu++,
1784 dtap_identity_req, sizeof(dtap_identity_req));
1785
1786 dump_peers(stdout, 0, 0, &gbcfg);
1787
1788 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1789 foreign_bss_tlli, &rai_bss, cell_id,
1790 GPRS_SAPI_GMM, bss_nu++,
1791 dtap_identity_resp, sizeof(dtap_identity_resp));
1792
1793 dump_peers(stdout, 0, 0, &gbcfg);
1794
1795 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1796 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1797 GPRS_SAPI_GMM, sgsn_nu++,
1798 dtap_attach_acc, sizeof(dtap_attach_acc));
1799
1800 dump_peers(stdout, 0, 0, &gbcfg);
1801
1802 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1803 OSMO_ASSERT(tlli_info);
1804 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1805 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1806 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1807 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1808 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1809 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1810 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1811 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1812 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1813 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1814
1815 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1816 local_bss_tlli, &rai_bss, cell_id,
1817 GPRS_SAPI_GMM, bss_nu++,
1818 dtap_attach_complete, sizeof(dtap_attach_complete));
1819
1820 dump_peers(stdout, 0, 0, &gbcfg);
1821
1822 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1823 OSMO_ASSERT(tlli_info);
1824 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1825 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1826 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1827 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1828 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1829 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1830 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1831 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1832
1833 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1834 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1835 GPRS_SAPI_GMM, sgsn_nu++,
1836 dtap_gmm_information, sizeof(dtap_gmm_information));
1837
1838 dump_peers(stdout, 0, 0, &gbcfg);
1839
1840 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1841 OSMO_ASSERT(tlli_info);
1842 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1843 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1844 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1845 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1846
1847 /* Non-DTAP */
1848 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1849 local_bss_tlli, &rai_bss, cell_id,
1850 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1851
1852 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1853 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1854 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1855
1856 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1857 local_bss_tlli, &rai_bss, cell_id,
1858 llc_ui_ll11_dns_query_ul,
1859 sizeof(llc_ui_ll11_dns_query_ul));
1860
1861 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1862 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1863 llc_ui_ll11_dns_resp_dl,
1864 sizeof(llc_ui_ll11_dns_resp_dl));
1865
1866 dump_peers(stdout, 0, 0, &gbcfg);
1867
1868 /* Other messages */
1869 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1870 local_bss_tlli, 1, 12);
1871
1872 dump_peers(stdout, 0, 0, &gbcfg);
1873
1874 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
1875 local_sgsn_tlli, 1, 12);
1876
1877 dump_peers(stdout, 0, 0, &gbcfg);
1878
1879 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1880
1881 dump_peers(stdout, 0, 0, &gbcfg);
1882
1883 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1884
1885 dump_peers(stdout, 0, 0, &gbcfg);
1886
1887 /* Bad case: Invalid BVCI */
1888 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1889 local_bss_tlli, 1, 12);
1890 dump_global(stdout, 0);
1891
1892 /* Bad case: Invalid RAI */
1893 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1894
1895 dump_global(stdout, 0);
1896
1897 /* Bad case: Invalid MCC (LAC ok) */
1898 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1899 &rai_wrong_mcc_sgsn);
1900
1901 dump_global(stdout, 0);
1902
1903 /* Detach */
1904 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1905 local_bss_tlli, &rai_bss, cell_id,
1906 GPRS_SAPI_GMM, bss_nu++,
1907 dtap_detach_req, sizeof(dtap_detach_req));
1908
1909 dump_peers(stdout, 0, 0, &gbcfg);
1910
1911 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1912 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1913 GPRS_SAPI_GMM, sgsn_nu++,
1914 dtap_detach_acc, sizeof(dtap_detach_acc));
1915
1916 dump_peers(stdout, 0, 0, &gbcfg);
1917
1918 dump_global(stdout, 0);
1919
1920 gbprox_reset(&gbcfg);
1921 gprs_ns_destroy(nsi);
1922 nsi = NULL;
1923}
1924
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001925static void test_gbproxy_secondary_sgsn()
1926{
1927 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1928 struct sockaddr_in bss_peer[1] = {{0},};
1929 struct sockaddr_in sgsn_peer[2]= {{0},};
1930 struct gprs_ra_id rai_bss =
1931 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1932 struct gprs_ra_id rai_sgsn =
1933 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1934 struct gprs_ra_id rai_unknown =
1935 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1936 uint16_t cell_id = 0x1234;
1937
1938 const uint32_t sgsn_ptmsi = 0xefe2b700;
1939 const uint32_t local_sgsn_tlli = 0xefe2b700;
1940 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1941
1942 const uint32_t bss_ptmsi = 0xc00f7304;
1943 const uint32_t local_bss_tlli = 0xc00f7304;
1944 const uint32_t foreign_bss_tlli = 0x8000dead;
1945
1946 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1947 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1948 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
1949 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1950 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1951 const uint32_t foreign_bss_tlli2 = 0x8000beef;
1952
1953 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1954 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1955 struct gbproxy_tlli_info *tlli_info;
1956 struct gbproxy_peer *peer;
1957 unsigned bss_nu = 0;
1958 unsigned sgsn_nu = 0;
1959
1960 const char *err_msg = NULL;
1961 const char *filter_re = "999999";
1962
1963 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1964 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1965
1966 bssgp_nsi = nsi;
1967 gbcfg.nsi = bssgp_nsi;
1968 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1969 gbcfg.core_mcc = 123;
1970 gbcfg.core_mnc = 456;
1971 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1972 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1973 gbcfg.patch_ptmsi = 1;
1974 gbcfg.acquire_imsi = 1;
1975 gbcfg.bss_ptmsi_state = 0;
1976 gbcfg.sgsn_tlli_state = 1;
1977 gbcfg.route_to_sgsn2 = 1;
1978 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
1979
1980 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
1981 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
1982 err_msg);
1983 OSMO_ASSERT(err_msg == NULL);
1984 }
1985
1986 configure_sgsn_peer(&sgsn_peer[0]);
1987 configure_sgsn2_peer(&sgsn_peer[1]);
1988 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1989
1990 printf("=== %s ===\n", __func__);
1991 printf("--- Initialise SGSN 1 ---\n\n");
1992
1993 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
1994
1995 printf("--- Initialise SGSN 2 ---\n\n");
1996
1997 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
1998
1999 printf("--- Initialise BSS 1 ---\n\n");
2000
2001 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2002 setup_bssgp(nsi, &bss_peer[0], 0x0);
2003 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2004 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2005 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2006 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2007
2008 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2009 OSMO_ASSERT(peer != NULL);
2010
2011 gprs_dump_nsi(nsi);
2012 dump_global(stdout, 0);
2013 dump_peers(stdout, 0, 0, &gbcfg);
2014
2015 printf("--- Flow control ---\n\n");
2016
2017 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2018 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2019 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2020
2021 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2022
2023 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2024 foreign_bss_tlli, &rai_unknown, cell_id,
2025 GPRS_SAPI_GMM, bss_nu++,
2026 dtap_attach_req, sizeof(dtap_attach_req));
2027
2028 dump_peers(stdout, 0, 0, &gbcfg);
2029
2030 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2031 foreign_bss_tlli, &rai_bss, cell_id,
2032 GPRS_SAPI_GMM, bss_nu++,
2033 dtap_identity_resp, sizeof(dtap_identity_resp));
2034
2035 dump_peers(stdout, 0, 0, &gbcfg);
2036
2037 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2038 random_sgsn_tlli, 0, NULL, 0,
2039 GPRS_SAPI_GMM, sgsn_nu++,
2040 dtap_identity_req, sizeof(dtap_identity_req));
2041
2042 dump_peers(stdout, 0, 0, &gbcfg);
2043
2044 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2045 foreign_bss_tlli, &rai_bss, cell_id,
2046 GPRS_SAPI_GMM, bss_nu++,
2047 dtap_identity_resp, sizeof(dtap_identity_resp));
2048
2049 dump_peers(stdout, 0, 0, &gbcfg);
2050
2051 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2052 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2053 GPRS_SAPI_GMM, sgsn_nu++,
2054 dtap_attach_acc, sizeof(dtap_attach_acc));
2055
2056 dump_peers(stdout, 0, 0, &gbcfg);
2057
2058 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2059 OSMO_ASSERT(tlli_info);
2060 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2061 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2062 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2063 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2064 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2065 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2066 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2067 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2068 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2069 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2070
2071 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2072 local_bss_tlli, &rai_bss, cell_id,
2073 GPRS_SAPI_GMM, bss_nu++,
2074 dtap_attach_complete, sizeof(dtap_attach_complete));
2075
2076 dump_peers(stdout, 0, 0, &gbcfg);
2077
2078 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2079 OSMO_ASSERT(tlli_info);
2080 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2081 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2082 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2083 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2084 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2085 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2086 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2087 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2088
2089 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2090 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2091 GPRS_SAPI_GMM, sgsn_nu++,
2092 dtap_gmm_information, sizeof(dtap_gmm_information));
2093
2094 dump_peers(stdout, 0, 0, &gbcfg);
2095
2096 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2097 OSMO_ASSERT(tlli_info);
2098 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2099 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2100 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2101 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2102
2103 /* Non-DTAP */
2104 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2105 local_bss_tlli, &rai_bss, cell_id,
2106 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2107
2108 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2109 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2110 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2111
2112 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2113 local_bss_tlli, &rai_bss, cell_id,
2114 llc_ui_ll11_dns_query_ul,
2115 sizeof(llc_ui_ll11_dns_query_ul));
2116
2117 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2118 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2119 llc_ui_ll11_dns_resp_dl,
2120 sizeof(llc_ui_ll11_dns_resp_dl));
2121
2122 dump_peers(stdout, 0, 0, &gbcfg);
2123
2124 /* Other messages */
2125 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2126 local_bss_tlli, 1, 12);
2127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
2130 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2131 local_sgsn_tlli, 1, 12);
2132
2133 dump_peers(stdout, 0, 0, &gbcfg);
2134
2135 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2136
2137 dump_peers(stdout, 0, 0, &gbcfg);
2138
2139 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2140
2141 dump_peers(stdout, 0, 0, &gbcfg);
2142
2143 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2144
2145 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2146 foreign_bss_tlli2, &rai_unknown, cell_id,
2147 GPRS_SAPI_GMM, bss_nu++,
2148 dtap_attach_req, sizeof(dtap_attach_req));
2149
2150 dump_peers(stdout, 0, 0, &gbcfg);
2151
2152 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2153 foreign_bss_tlli2, &rai_bss, cell_id,
2154 GPRS_SAPI_GMM, bss_nu++,
2155 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2156
2157 dump_peers(stdout, 0, 0, &gbcfg);
2158
2159 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2160 random_sgsn_tlli2, 0, NULL, 0,
2161 GPRS_SAPI_GMM, sgsn_nu++,
2162 dtap_identity_req, sizeof(dtap_identity_req));
2163
2164 dump_peers(stdout, 0, 0, &gbcfg);
2165
2166 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2167 foreign_bss_tlli2, &rai_bss, cell_id,
2168 GPRS_SAPI_GMM, bss_nu++,
2169 dtap_identity_resp, sizeof(dtap_identity_resp));
2170
2171 dump_peers(stdout, 0, 0, &gbcfg);
2172
2173 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2174 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2175 GPRS_SAPI_GMM, sgsn_nu++,
2176 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2177
2178 dump_peers(stdout, 0, 0, &gbcfg);
2179
2180 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2181 OSMO_ASSERT(tlli_info);
2182 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2183 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2184 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2185 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2186 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2187 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2188 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2189 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2190 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2191 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2192
2193 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2194 local_bss_tlli2, &rai_bss, cell_id,
2195 GPRS_SAPI_GMM, bss_nu++,
2196 dtap_attach_complete, sizeof(dtap_attach_complete));
2197
2198 dump_peers(stdout, 0, 0, &gbcfg);
2199
2200 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2201 OSMO_ASSERT(tlli_info);
2202 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2203 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2204 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2205 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2206 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2207 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2208 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2209 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2210
2211 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2212 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2213 GPRS_SAPI_GMM, sgsn_nu++,
2214 dtap_gmm_information, sizeof(dtap_gmm_information));
2215
2216 dump_peers(stdout, 0, 0, &gbcfg);
2217
2218 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2219 OSMO_ASSERT(tlli_info);
2220 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2221 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2222 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2223 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2224
2225 /* Non-DTAP */
2226 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2227 local_bss_tlli2, &rai_bss, cell_id,
2228 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2229
2230 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2231 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2232 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2233
2234 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2235 local_bss_tlli2, &rai_bss, cell_id,
2236 llc_ui_ll11_dns_query_ul,
2237 sizeof(llc_ui_ll11_dns_query_ul));
2238
2239 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2240 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2241 llc_ui_ll11_dns_resp_dl,
2242 sizeof(llc_ui_ll11_dns_resp_dl));
2243
2244 dump_peers(stdout, 0, 0, &gbcfg);
2245
2246 /* Other messages */
2247 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2248 local_bss_tlli2, 1, 12);
2249
2250 dump_peers(stdout, 0, 0, &gbcfg);
2251
2252 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2253 local_sgsn_tlli2, 1, 12);
2254
2255 dump_peers(stdout, 0, 0, &gbcfg);
2256
2257 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2258
2259 dump_peers(stdout, 0, 0, &gbcfg);
2260
2261 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2262
2263 dump_peers(stdout, 0, 0, &gbcfg);
2264
2265 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2266
2267 /* Detach */
2268 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2269 local_bss_tlli, &rai_bss, cell_id,
2270 GPRS_SAPI_GMM, bss_nu++,
2271 dtap_detach_req, sizeof(dtap_detach_req));
2272
2273 dump_peers(stdout, 0, 0, &gbcfg);
2274
2275 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2276 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2277 GPRS_SAPI_GMM, sgsn_nu++,
2278 dtap_detach_acc, sizeof(dtap_detach_acc));
2279
2280 dump_peers(stdout, 0, 0, &gbcfg);
2281
2282 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2283
2284 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2285 local_bss_tlli2, &rai_bss, cell_id,
2286 GPRS_SAPI_GMM, bss_nu++,
2287 dtap_detach_req, sizeof(dtap_detach_req));
2288
2289 dump_peers(stdout, 0, 0, &gbcfg);
2290
2291 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2292 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2293 GPRS_SAPI_GMM, sgsn_nu++,
2294 dtap_detach_acc, sizeof(dtap_detach_acc));
2295
2296 dump_peers(stdout, 0, 0, &gbcfg);
2297
2298 dump_global(stdout, 0);
2299
2300 gbprox_reset(&gbcfg);
2301 gprs_ns_destroy(nsi);
2302 nsi = NULL;
2303}
2304
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002305/* TODO: Move tlv testing to libosmocore */
2306int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2307int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2308 uint8_t **value);
2309int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2310 size_t *value_len);
2311int lv_shift(uint8_t **data, size_t *data_len,
2312 uint8_t **value, size_t *value_len);
2313
2314static void check_tlv_match(uint8_t **data, size_t *data_len,
2315 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2316{
2317 uint8_t *value;
2318 size_t value_len;
2319 int rc;
2320
2321 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2322 OSMO_ASSERT(rc == 0);
2323
2324 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002325 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002326 OSMO_ASSERT(value_len == exp_len);
2327 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2328}
2329
2330static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2331 uint8_t tag, size_t len, const uint8_t *exp_val)
2332{
2333 uint8_t *value;
2334 int rc;
2335
2336 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2337 OSMO_ASSERT(rc == 0);
2338
2339 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002340 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002341 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2342}
2343
2344static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2345 size_t len, const uint8_t *exp_val)
2346{
2347 uint8_t *value;
2348 int rc;
2349
2350 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002351 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002352 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2353}
2354
2355static void check_lv_shift(uint8_t **data, size_t *data_len,
2356 size_t exp_len, const uint8_t *exp_val)
2357{
2358 uint8_t *value;
2359 size_t value_len;
2360 int rc;
2361
2362 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002363 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002364 OSMO_ASSERT(value_len == exp_len);
2365 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2366}
2367
2368static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2369 const uint8_t *test_data)
2370{
2371 uint8_t buf[300] = {0};
2372
2373 uint8_t *unchanged_ptr = buf - 1;
2374 size_t unchanged_len = 0xdead;
2375 size_t tmp_data_len = data_len;
2376 uint8_t *value = unchanged_ptr;
2377 size_t value_len = unchanged_len;
2378 uint8_t *data = buf;
2379
2380 OSMO_ASSERT(data_len <= sizeof(buf));
2381
2382 tlv_put(data, tag, len, test_data);
2383 if (data_len < len + 2) {
2384 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2385 tag, &value, &value_len));
2386 OSMO_ASSERT(tmp_data_len == 0);
2387 OSMO_ASSERT(data == buf + data_len);
2388 OSMO_ASSERT(value == unchanged_ptr);
2389 OSMO_ASSERT(value_len == unchanged_len);
2390 } else {
2391 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2392 tag, &value, &value_len));
2393 OSMO_ASSERT(value != unchanged_ptr);
2394 OSMO_ASSERT(value_len != unchanged_len);
2395 }
2396}
2397
2398static void check_tv_fixed_match_data_len(size_t data_len,
2399 uint8_t tag, size_t len,
2400 const uint8_t *test_data)
2401{
2402 uint8_t buf[300] = {0};
2403
2404 uint8_t *unchanged_ptr = buf - 1;
2405 size_t tmp_data_len = data_len;
2406 uint8_t *value = unchanged_ptr;
2407 uint8_t *data = buf;
2408
2409 OSMO_ASSERT(data_len <= sizeof(buf));
2410
2411 tv_fixed_put(data, tag, len, test_data);
2412
2413 if (data_len < len + 1) {
2414 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2415 tag, len, &value));
2416 OSMO_ASSERT(tmp_data_len == 0);
2417 OSMO_ASSERT(data == buf + data_len);
2418 OSMO_ASSERT(value == unchanged_ptr);
2419 } else {
2420 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2421 tag, len, &value));
2422 OSMO_ASSERT(value != unchanged_ptr);
2423 }
2424}
2425
2426static void check_v_fixed_shift_data_len(size_t data_len,
2427 size_t len, const uint8_t *test_data)
2428{
2429 uint8_t buf[300] = {0};
2430
2431 uint8_t *unchanged_ptr = buf - 1;
2432 size_t tmp_data_len = data_len;
2433 uint8_t *value = unchanged_ptr;
2434 uint8_t *data = buf;
2435
2436 OSMO_ASSERT(data_len <= sizeof(buf));
2437
2438 memcpy(data, test_data, len);
2439
2440 if (data_len < len) {
2441 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2442 len, &value));
2443 OSMO_ASSERT(tmp_data_len == 0);
2444 OSMO_ASSERT(data == buf + data_len);
2445 OSMO_ASSERT(value == unchanged_ptr);
2446 } else {
2447 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2448 len, &value));
2449 OSMO_ASSERT(value != unchanged_ptr);
2450 }
2451}
2452
2453static void check_lv_shift_data_len(size_t data_len,
2454 size_t len, const uint8_t *test_data)
2455{
2456 uint8_t buf[300] = {0};
2457
2458 uint8_t *unchanged_ptr = buf - 1;
2459 size_t unchanged_len = 0xdead;
2460 size_t tmp_data_len = data_len;
2461 uint8_t *value = unchanged_ptr;
2462 size_t value_len = unchanged_len;
2463 uint8_t *data = buf;
2464
2465 lv_put(data, len, test_data);
2466 if (data_len < len + 1) {
2467 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2468 &value, &value_len));
2469 OSMO_ASSERT(tmp_data_len == 0);
2470 OSMO_ASSERT(data == buf + data_len);
2471 OSMO_ASSERT(value == unchanged_ptr);
2472 OSMO_ASSERT(value_len == unchanged_len);
2473 } else {
2474 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2475 &value, &value_len));
2476 OSMO_ASSERT(value != unchanged_ptr);
2477 OSMO_ASSERT(value_len != unchanged_len);
2478 }
2479}
2480
2481static void test_tlv_shift_functions()
2482{
2483 uint8_t test_data[1024];
2484 uint8_t buf[1024];
2485 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002486 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002487 uint8_t *data;
2488 size_t data_len;
2489 const uint8_t tag = 0x1a;
2490
2491 printf("Test shift functions\n");
2492
2493 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2494 test_data[i] = (uint8_t)i;
2495
2496 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002497 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002498
2499 memset(buf, 0xee, sizeof(buf));
2500 data_end = data = buf;
2501
2502 for (i = 0; i < iterations; i++) {
2503 data_end = tlv_put(data_end, tag, len, test_data);
2504 data_end = tv_fixed_put(data_end, tag, len, test_data);
2505 /* v_fixed_put */
2506 memcpy(data_end, test_data, len);
2507 data_end += len;
2508 data_end = lv_put(data_end, len, test_data);
2509 }
2510
2511 data_len = data_end - data;
2512 OSMO_ASSERT(data_len <= sizeof(buf));
2513
2514 for (i = 0; i < iterations; i++) {
2515 check_tlv_match(&data, &data_len, tag, len, test_data);
2516 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2517 check_v_fixed_shift(&data, &data_len, len, test_data);
2518 check_lv_shift(&data, &data_len, len, test_data);
2519 }
2520
2521 OSMO_ASSERT(data == data_end);
2522
2523 /* Test at end of data */
2524
2525 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2526 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2527 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2528 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2529
2530 /* Test invalid data_len */
2531 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2532 check_tlv_match_data_len(data_len, tag, len, test_data);
2533 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2534 check_v_fixed_shift_data_len(data_len, len, test_data);
2535 check_lv_shift_data_len(data_len, len, test_data);
2536 }
2537 }
2538}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002539
2540static void test_gbproxy_tlli_expire(void)
2541{
2542 struct gbproxy_config cfg = {0};
2543 struct gbproxy_peer *peer;
2544 const char *err_msg = NULL;
2545 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2546 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002547 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002548 const uint32_t tlli1 = 1234 | 0xc0000000;
2549 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002550 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002551 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002552 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002553
2554 printf("Test TLLI info expiry\n\n");
2555
2556 gbproxy_init_config(&cfg);
2557
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002558 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002559 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2560 err_msg);
2561 OSMO_ASSERT(err_msg == NULL);
2562 }
2563
2564 {
2565 struct gbproxy_tlli_info *tlli_info;
2566
2567 printf("Test TLLI replacement:\n");
2568
2569 cfg.tlli_max_len = 0;
2570 cfg.tlli_max_age = 0;
2571 peer = gbproxy_peer_alloc(&cfg, 20);
2572 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2573
2574 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002575 tlli_info = gbproxy_register_tlli(peer, tlli1,
2576 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002577 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002578 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002579 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2580
2581 /* replace the old entry */
2582 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002583 tlli_info = gbproxy_register_tlli(peer, tlli2,
2584 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002585 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002586 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002587 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2588
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002589 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002590
2591 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002592 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002593 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002594 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002595 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002596 OSMO_ASSERT(!tlli_info);
2597
2598 printf("\n");
2599
2600 gbproxy_peer_free(peer);
2601 }
2602
2603 {
2604 struct gbproxy_tlli_info *tlli_info;
2605
2606 printf("Test IMSI replacement:\n");
2607
2608 cfg.tlli_max_len = 0;
2609 cfg.tlli_max_age = 0;
2610 peer = gbproxy_peer_alloc(&cfg, 20);
2611 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2612
2613 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002614 tlli_info = gbproxy_register_tlli(peer, tlli1,
2615 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002616 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002617 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002618 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2619
2620 /* try to replace the old entry */
2621 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002622 tlli_info = gbproxy_register_tlli(peer, tlli1,
2623 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002624 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002625 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002626 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2627
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002628 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002629
2630 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002631 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002632 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002633 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002634 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002635 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002636
2637 printf("\n");
2638
2639 gbproxy_peer_free(peer);
2640 }
2641
2642 {
2643 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002644 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002645
2646 printf("Test TLLI expiry, max_len == 1:\n");
2647
2648 cfg.tlli_max_len = 1;
2649 cfg.tlli_max_age = 0;
2650 peer = gbproxy_peer_alloc(&cfg, 20);
2651 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2652
2653 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002654 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002655 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2656
2657 /* replace the old entry */
2658 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002659 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002660 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2661
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002662 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002663 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002664 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2665
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002666 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002667
2668 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002669 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002670 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002671 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002672 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002673 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002674
2675 printf("\n");
2676
2677 gbproxy_peer_free(peer);
2678 }
2679
2680 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002681 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002682 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002683
2684 printf("Test TLLI expiry, max_age == 1:\n");
2685
2686 cfg.tlli_max_len = 0;
2687 cfg.tlli_max_age = 1;
2688 peer = gbproxy_peer_alloc(&cfg, 20);
2689 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2690
2691 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002692 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002693 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2694
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002695 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002696 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002697 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002698 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2699
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002700 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002701 OSMO_ASSERT(num_removed == 1);
2702 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2703
2704 dump_peers(stdout, 2, now + 2, &cfg);
2705
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002706 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002707 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002708 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002709 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002710 OSMO_ASSERT(tlli_info);
2711 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2712
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002713 printf("\n");
2714
2715 gbproxy_peer_free(peer);
2716 }
2717
2718 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002719 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002720 int num_removed;
2721
2722 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2723
2724 cfg.tlli_max_len = 0;
2725 cfg.tlli_max_age = 1;
2726 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002727 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2728
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002729 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002730 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002731 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2732
2733 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002734 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002735 now + 1);
2736 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2737
2738 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002739 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2740 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002741 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2742
2743 dump_peers(stdout, 2, now + 2, &cfg);
2744
2745 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002746 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002747 OSMO_ASSERT(num_removed == 2);
2748 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2749
2750 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002751
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002752 /* verify that tlli3 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002753 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002754 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002755 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002756 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002757 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002758 OSMO_ASSERT(tlli_info);
2759 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2760
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002761 printf("\n");
2762
2763 gbproxy_peer_free(peer);
2764 }
2765}
2766
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002767static void test_gbproxy_imsi_matching(void)
2768{
2769 struct gbproxy_config cfg = {0};
2770 struct gbproxy_peer *peer;
2771 const char *err_msg = NULL;
2772 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2773 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2774 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2775 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2776 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2777 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2778 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2779 const char *filter_re1 = ".*";
2780 const char *filter_re2 = "^1234";
2781 const char *filter_re3 = "^4321";
2782 const char *filter_re4_bad = "^12[";
2783
2784 printf("=== Test IMSI/TMSI matching ===\n\n");
2785
2786 gbproxy_init_config(&cfg);
2787 OSMO_ASSERT(cfg.check_imsi == 0);
2788
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002789 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002790 OSMO_ASSERT(cfg.check_imsi == 1);
2791
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002792 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002793 OSMO_ASSERT(cfg.check_imsi == 1);
2794
2795 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002796 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002797 OSMO_ASSERT(err_msg != NULL);
2798 OSMO_ASSERT(cfg.check_imsi == 0);
2799
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002800 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002801 OSMO_ASSERT(cfg.check_imsi == 1);
2802
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002803 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002804 OSMO_ASSERT(cfg.check_imsi == 0);
2805
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002806 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002807 OSMO_ASSERT(cfg.check_imsi == 1);
2808
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002809 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002810 OSMO_ASSERT(cfg.check_imsi == 0);
2811
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002812 peer = gbproxy_peer_alloc(&cfg, 20);
2813
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002814 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002815 OSMO_ASSERT(cfg.check_imsi == 1);
2816
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002817 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2818 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002819 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002820 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002821 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002822 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2823 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2824 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2825 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2826 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002827
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002828 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002829 OSMO_ASSERT(cfg.check_imsi == 1);
2830
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002831 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2832 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2833 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2834 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2835 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2836 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2837 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002838
2839 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2840
2841 gbproxy_peer_free(peer);
2842}
2843
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002844static struct log_info_cat gprs_categories[] = {
2845 [DGPRS] = {
2846 .name = "DGPRS",
2847 .description = "GPRS Packet Service",
2848 .enabled = 1, .loglevel = LOGL_DEBUG,
2849 },
2850 [DNS] = {
2851 .name = "DNS",
2852 .description = "GPRS Network Service (NS)",
2853 .enabled = 1, .loglevel = LOGL_INFO,
2854 },
2855 [DBSSGP] = {
2856 .name = "DBSSGP",
2857 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2858 .enabled = 1, .loglevel = LOGL_DEBUG,
2859 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002860};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002861
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002862static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002863 .cat = gprs_categories,
2864 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002865};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002866
2867int main(int argc, char **argv)
2868{
2869 osmo_init_logging(&info);
2870 log_set_use_color(osmo_stderr_target, 0);
2871 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02002872 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002873
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002874 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002875 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
2876 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002877
2878 rate_ctr_init(NULL);
2879
2880 setlinebuf(stdout);
2881
2882 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02002883 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002884 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002885 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002886 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002887 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02002888 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002889 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002890 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002891 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002892 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002893 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002894
2895 exit(EXIT_SUCCESS);
2896}