blob: 8f339b9cdbe9f407936eb4f4fa2cedb279f68a9e [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 Erlbeck7fb42db2014-07-07 10:46:01 +020043struct gbproxy_config gbcfg = {0};
44
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020045static int dump_global(FILE *stream, int indent)
46{
47 unsigned int i;
48 const struct rate_ctr_group_desc *desc;
49 int rc;
50
51 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
52 if (rc < 0)
53 return rc;
54
55 desc = gbcfg.ctrg->desc;
56
57 for (i = 0; i < desc->num_ctr; i++) {
58 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
59 if (ctr->current) {
60 rc = fprintf(stream, "%*s %s: %llu\n",
61 indent, "",
62 desc->ctr_desc[i].description,
63 (long long)ctr->current);
64
65 if (rc < 0)
66 return rc;
67 }
68 }
69
70 return 0;
71}
72
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020073static int dump_peers(FILE *stream, int indent, time_t now,
74 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020075{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020076 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020077 struct gprs_ra_id raid;
78 unsigned int i;
79 const struct rate_ctr_group_desc *desc;
80 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020081
82 rc = fprintf(stream, "%*sPeers:\n", indent, "");
83 if (rc < 0)
84 return rc;
85
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020086 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020087 struct gbproxy_tlli_info *tlli_info;
88 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020089 gsm48_parse_ra(&raid, peer->ra);
90
91 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
92 "RAI %u-%u-%u-%u\n",
93 indent, "",
94 peer->nsei, peer->bvci,
95 peer->blocked ? "" : "not ",
96 raid.mcc, raid.mnc, raid.lac, raid.rac);
97
98 if (rc < 0)
99 return rc;
100
101 desc = peer->ctrg->desc;
102
103 for (i = 0; i < desc->num_ctr; i++) {
104 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
105 if (ctr->current) {
106 rc = fprintf(stream, "%*s %s: %llu\n",
107 indent, "",
108 desc->ctr_desc[i].description,
109 (long long)ctr->current);
110
111 if (rc < 0)
112 return rc;
113 }
114 }
115
116 fprintf(stream, "%*s TLLI-Cache: %d\n",
117 indent, "", state->enabled_tllis_count);
118 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
119 char mi_buf[200];
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200120 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200121 if (tlli_info->mi_data_len > 0) {
122 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
123 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
124 tlli_info->mi_data,
125 tlli_info->mi_data_len);
126 } else {
127 snprintf(mi_buf, sizeof(mi_buf), "(none)");
128 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200129 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200130 indent, "", tlli_info->tlli.current);
131 if (tlli_info->tlli.assigned)
132 fprintf(stream, "/%08x", tlli_info->tlli.assigned);
133 if (tlli_info->sgsn_tlli.current) {
134 fprintf(stream, " -> %08x",
135 tlli_info->sgsn_tlli.current);
136 if (tlli_info->sgsn_tlli.assigned)
137 fprintf(stream, "/%08x",
138 tlli_info->sgsn_tlli.assigned);
139 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200140 rc = fprintf(stream, ", IMSI %s, AGE %d\n",
141 mi_buf, (int)age);
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200142 if (rc < 0)
143 return rc;
144 }
145 }
146
147 return 0;
148}
149
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200150/* DTAP - Attach Request */
151static const unsigned char dtap_attach_req[] = {
152 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
153 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
154 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
155 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
156 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
157 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200158};
159
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200160/* DTAP - Identity Request */
161static const unsigned char dtap_identity_req[] = {
162 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200163};
164
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200165/* DTAP - Identity Response */
166static const unsigned char dtap_identity_resp[] = {
167 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
168 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200169};
170
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200171/* DTAP - Attach Accept */
172static const unsigned char dtap_attach_acc[] = {
173 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
174 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
175 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200176};
177
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200178/* DTAP - Attach Complete */
179static const unsigned char dtap_attach_complete[] = {
180 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200181};
182
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200183/* DTAP - GMM Information */
184static const unsigned char dtap_gmm_information[] = {
185 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200186};
187
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200188/* DTAP - Routing Area Update Request */
189static const unsigned char dtap_ra_upd_req[] = {
190 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
191 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
192 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
193 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
194 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
195 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
196 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200197};
198
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200199/* DTAP - Routing Area Update Accept */
200static const unsigned char dtap_ra_upd_acc[] = {
201 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
202 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
203 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200204};
205
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200206/* DTAP - Activate PDP Context Request */
207static const unsigned char dtap_act_pdp_ctx_req[] = {
208 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200209 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
211 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
212 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
213 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200214 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200215};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200216
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200217/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200218/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200219static const unsigned char dtap_detach_po_req[] = {
220 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
221 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200222};
223
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200224/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200225/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200226static const unsigned char dtap_detach_req[] = {
227 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
228 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200229};
230
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200231/* DTAP - Detach Accept */
232static const unsigned char dtap_detach_acc[] = {
233 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200234};
235
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200236/* GPRS-LLC - SAPI: LLGMM, U, XID */
237static const unsigned char llc_u_xid_ul[] = {
238 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
239 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
240};
241
242/* GPRS-LLC - SAPI: LLGMM, U, XID */
243static const unsigned char llc_u_xid_dl[] = {
244 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
245 0xe4, 0xa9, 0x1a, 0x9e
246};
247
248/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
249static const unsigned char llc_ui_ll11_dns_query_ul[] = {
250 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
251 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
252 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
253 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
254 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
255 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
256 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
257 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
258 0x8f, 0x07
259};
260
261/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
262static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
263 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
264 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
265 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
266 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
267 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
268 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
269 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
270 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
271 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
272 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
273 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
274 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
275 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
276 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
277 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
278 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
279 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
280 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
281 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
282 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
283 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
284 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
285 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
286 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
287 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
288 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
289};
290
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200291static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
292 struct sockaddr_in *peer, const unsigned char* data,
293 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200294
295static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
296 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
297{
298 /* GPRS Network Service, PDU type: NS_RESET,
299 */
300 unsigned char msg[12] = {
301 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
302 0x04, 0x82, 0x11, 0x22
303 };
304
305 msg[3] = cause;
306 msg[6] = nsvci / 256;
307 msg[7] = nsvci % 256;
308 msg[10] = nsei / 256;
309 msg[11] = nsei % 256;
310
311 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
312}
313
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200314static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
315 uint16_t nsvci, uint16_t nsei)
316{
317 /* GPRS Network Service, PDU type: NS_RESET_ACK,
318 */
319 unsigned char msg[9] = {
320 0x03, 0x01, 0x82, 0x11, 0x22,
321 0x04, 0x82, 0x11, 0x22
322 };
323
324 msg[3] = nsvci / 256;
325 msg[4] = nsvci % 256;
326 msg[7] = nsei / 256;
327 msg[8] = nsei % 256;
328
329 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
330}
331
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200332static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
333{
334 /* GPRS Network Service, PDU type: NS_ALIVE */
335 unsigned char msg[1] = {
336 0x0a
337 };
338
339 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
340}
341
342static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
343{
344 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
345 unsigned char msg[1] = {
346 0x0b
347 };
348
349 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
350}
351
352static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
353{
354 /* GPRS Network Service, PDU type: NS_UNBLOCK */
355 unsigned char msg[1] = {
356 0x06
357 };
358
359 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
360}
361
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200362static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
363{
364 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
365 unsigned char msg[1] = {
366 0x07
367 };
368
369 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
370}
371
372static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
373 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200374 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
375{
376 /* GPRS Network Service, PDU type: NS_UNITDATA */
377 unsigned char msg[4096] = {
378 0x00, 0x00, 0x00, 0x00
379 };
380
381 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
382
383 msg[2] = nsbvci / 256;
384 msg[3] = nsbvci % 256;
385 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
386
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200387 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200388}
389
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200390static void send_bssgp_ul_unitdata(
391 struct gprs_ns_inst *nsi, const char *text,
392 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
393 struct gprs_ra_id *raid, uint16_t cell_id,
394 const uint8_t *llc_msg, size_t llc_msg_size)
395{
396 /* GPRS Network Service, PDU type: NS_UNITDATA */
397 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
398 unsigned char msg[4096] = {
399 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
400 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
401 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
402 };
403
404 size_t bssgp_msg_size = 23 + llc_msg_size;
405
406 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
407
408 gsm48_construct_ra(msg + 10, raid);
409 msg[1] = (uint8_t)(tlli >> 24);
410 msg[2] = (uint8_t)(tlli >> 16);
411 msg[3] = (uint8_t)(tlli >> 8);
412 msg[4] = (uint8_t)(tlli >> 0);
413 msg[16] = cell_id / 256;
414 msg[17] = cell_id % 256;
415 msg[21] = llc_msg_size / 256;
416 msg[22] = llc_msg_size % 256;
417 memcpy(msg + 23, llc_msg, llc_msg_size);
418
419 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
420 src_addr, nsbvci, msg, bssgp_msg_size);
421}
422
423static void send_bssgp_dl_unitdata(
424 struct gprs_ns_inst *nsi, const char *text,
425 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
426 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
427 const uint8_t *llc_msg, size_t llc_msg_size)
428{
429 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
430 unsigned char msg[4096] = {
431 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
432 0x16, 0x82, 0x02, 0x58,
433 };
434 unsigned char racap_drx[] = {
435 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
436 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
437 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
438 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
439 };
440
441 size_t bssgp_msg_size = 0;
442
443 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
444
445 msg[1] = (uint8_t)(tlli >> 24);
446 msg[2] = (uint8_t)(tlli >> 16);
447 msg[3] = (uint8_t)(tlli >> 8);
448 msg[4] = (uint8_t)(tlli >> 0);
449
450 bssgp_msg_size = 12;
451
452 if (with_racap_drx) {
453 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
454 bssgp_msg_size += sizeof(racap_drx);
455 }
456
457 if (imsi) {
458 OSMO_ASSERT(imsi_size <= 127);
459 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
460 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
461 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
462 bssgp_msg_size += 2 + imsi_size;
463 }
464
465 if ((bssgp_msg_size % 4) != 0) {
466 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
467 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
468 msg[bssgp_msg_size + 1] = 0x80 | abytes;
469 memset(msg + bssgp_msg_size + 2, 0, abytes);
470 bssgp_msg_size += 2 + abytes;
471 }
472
473 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
474 if (llc_msg_size < 128) {
475 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
476 bssgp_msg_size += 2;
477 } else {
478 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
479 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
480 bssgp_msg_size += 3;
481 }
482 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
483 bssgp_msg_size += llc_msg_size;
484
485
486 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
487 src_addr, nsbvci, msg, bssgp_msg_size);
488}
489
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200490static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
491 uint16_t bvci)
492{
493 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
494 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200495 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200496 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200497 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
498 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200499 };
500
501 msg[3] = bvci / 256;
502 msg[4] = bvci % 256;
503
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200504 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
505}
506
507static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
508 struct sockaddr_in *src_addr, uint16_t bvci)
509{
510 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
511 * BSSGP RESET_ACK */
512 static unsigned char msg[5] = {
513 0x23, 0x04, 0x82, 0x00,
514 0x00
515 };
516
517 msg[3] = bvci / 256;
518 msg[4] = bvci % 256;
519
520 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200521}
522
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200523static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
524 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200525 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200526 struct gprs_ra_id *raid)
527{
528 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
529 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200530 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
531 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200532 };
533
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200534 msg[3] = (uint8_t)(tlli >> 24);
535 msg[4] = (uint8_t)(tlli >> 16);
536 msg[5] = (uint8_t)(tlli >> 8);
537 msg[6] = (uint8_t)(tlli >> 0);
538
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200539 gsm48_construct_ra(msg + 9, raid);
540
541 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
542}
543
544static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
545 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200546 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200547 struct gprs_ra_id *raid)
548{
549 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
550 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200551 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
552 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200553 0x81, 0x01
554 };
555
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200556 msg[3] = (uint8_t)(tlli >> 24);
557 msg[4] = (uint8_t)(tlli >> 16);
558 msg[5] = (uint8_t)(tlli >> 8);
559 msg[6] = (uint8_t)(tlli >> 0);
560
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200561 gsm48_construct_ra(msg + 9, raid);
562
563 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
564}
565
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200566static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
567 struct sockaddr_in *src_addr,
568 uint16_t bvci, uint32_t tlli,
569 unsigned n_frames, unsigned n_octets)
570{
571 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
572 unsigned char msg[] = {
573 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
574 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
575 /* n octets */ 0xff, 0xff, 0xff
576 };
577
578 msg[3] = (uint8_t)(tlli >> 24);
579 msg[4] = (uint8_t)(tlli >> 16);
580 msg[5] = (uint8_t)(tlli >> 8);
581 msg[6] = (uint8_t)(tlli >> 0);
582 msg[9] = (uint8_t)(n_frames);
583 msg[12] = (uint8_t)(bvci >> 8);
584 msg[13] = (uint8_t)(bvci >> 0);
585 msg[16] = (uint8_t)(n_octets >> 16);
586 msg[17] = (uint8_t)(n_octets >> 8);
587 msg[18] = (uint8_t)(n_octets >> 0);
588
589 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
590}
591
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200592static void send_llc_ul_ui(
593 struct gprs_ns_inst *nsi, const char *text,
594 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
595 struct gprs_ra_id *raid, uint16_t cell_id,
596 unsigned sapi, unsigned nu,
597 const uint8_t *msg, size_t msg_size)
598{
599 unsigned char llc_msg[4096] = {
600 0x00, 0xc0, 0x01
601 };
602
603 size_t llc_msg_size = 3 + msg_size + 3;
604 uint8_t e_bit = 0;
605 uint8_t pm_bit = 1;
606 unsigned fcs;
607
608 nu &= 0x01ff;
609
610 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
611
612 llc_msg[0] = (sapi & 0x0f);
613 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
614 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
615
616 memcpy(llc_msg + 3, msg, msg_size);
617
618 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
619 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
620 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
621 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
622
623 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
624 src_addr, nsbvci, tlli, raid, cell_id,
625 llc_msg, llc_msg_size);
626}
627
628static void send_llc_dl_ui(
629 struct gprs_ns_inst *nsi, const char *text,
630 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
631 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
632 unsigned sapi, unsigned nu,
633 const uint8_t *msg, size_t msg_size)
634{
635 /* GPRS Network Service, PDU type: NS_UNITDATA */
636 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
637 unsigned char llc_msg[4096] = {
638 0x00, 0x00, 0x01
639 };
640
641 size_t llc_msg_size = 3 + msg_size + 3;
642 uint8_t e_bit = 0;
643 uint8_t pm_bit = 1;
644 unsigned fcs;
645
646 nu &= 0x01ff;
647
648 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
649
650 llc_msg[0] = 0x40 | (sapi & 0x0f);
651 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
652 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
653
654 memcpy(llc_msg + 3, msg, msg_size);
655
656 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
657 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
658 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
659 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
660
661 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
662 src_addr, nsbvci, tlli,
663 with_racap_drx, imsi, imsi_size,
664 llc_msg, llc_msg_size);
665}
666
667
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200668static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
669 uint16_t nsvci, uint16_t nsei)
670{
671 printf("Setup NS-VC: remote 0x%08x:%d, "
672 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
673 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
674 nsvci, nsvci, nsei, nsei);
675
676 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
677 send_ns_alive(nsi, src_addr);
678 send_ns_unblock(nsi, src_addr);
679 send_ns_alive_ack(nsi, src_addr);
680}
681
682static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
683 uint16_t bvci)
684{
685 printf("Setup BSSGP: remote 0x%08x:%d, "
686 "BVCI 0x%04x(%d)\n\n",
687 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
688 bvci, bvci);
689
690 send_bssgp_reset(nsi, src_addr, bvci);
691}
692
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200693static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer)
694{
695 gprs_ns_nsip_connect(nsi, sgsn_peer, SGSN_NSEI, SGSN_NSEI+1);
696 send_ns_reset_ack(nsi, sgsn_peer, SGSN_NSEI+1, SGSN_NSEI);
697 send_ns_alive_ack(nsi, sgsn_peer);
698 send_ns_unblock_ack(nsi, sgsn_peer);
699 send_ns_alive(nsi, sgsn_peer);
700}
701
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200702static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
703{
704 sgsn_peer->sin_family = AF_INET;
705 sgsn_peer->sin_port = htons(32000);
706 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
707}
708
709static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
710{
711 size_t i;
712
713 for (i = 0; i < size; ++i) {
714 bss_peers[i].sin_family = AF_INET;
715 bss_peers[i].sin_port = htons((i + 1) * 1111);
716 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
717 }
718}
719
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200720int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
721 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
722
723/* override */
724int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
725 struct msgb *msg, uint16_t bvci)
726{
727 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
728 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200729 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200730
731 switch (event) {
732 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +0200733 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200734 default:
735 break;
736 }
737 return 0;
738}
739
740/* override */
741ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
742 const struct sockaddr *dest_addr, socklen_t addrlen)
743{
744 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
745 const struct sockaddr *, socklen_t);
746 static sendto_t real_sendto = NULL;
747 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200748 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200749
750 if (!real_sendto)
751 real_sendto = dlsym(RTLD_NEXT, "sendto");
752
753 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200754 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
755 dest_host, dest_port,
756 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200757 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200758 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
759 dest_host, dest_port,
760 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200761 else
762 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
763
764 return len;
765}
766
767/* override */
768int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
769{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200770 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
771 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200772 uint16_t bvci = msgb_bvci(msg);
773 uint16_t nsei = msgb_nsei(msg);
774
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200775 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200776
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200777 if (!real_gprs_ns_sendmsg)
778 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
779
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200780 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200781 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
782 "msg length %d (%s)\n",
783 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200784 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200785 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
786 "msg length %d (%s)\n",
787 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200788
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200789 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200790}
791
792static void dump_rate_ctr_group(FILE *stream, const char *prefix,
793 struct rate_ctr_group *ctrg)
794{
795 unsigned int i;
796
797 for (i = 0; i < ctrg->desc->num_ctr; i++) {
798 struct rate_ctr *ctr = &ctrg->ctr[i];
799 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
800 fprintf(stream, " %s%s: %llu%s",
801 prefix, ctrg->desc->ctr_desc[i].description,
802 (long long)ctr->current,
803 "\n");
804 };
805}
806
807/* Signal handler for signals from NS layer */
808static int test_signal(unsigned int subsys, unsigned int signal,
809 void *handler_data, void *signal_data)
810{
811 struct ns_signal_data *nssd = signal_data;
812 int rc;
813
814 if (subsys != SS_L_NS)
815 return 0;
816
817 switch (signal) {
818 case S_NS_RESET:
819 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
820 nssd->nsvc->nsvci,
821 gprs_ns_ll_str(nssd->nsvc));
822 break;
823
824 case S_NS_ALIVE_EXP:
825 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
826 nssd->nsvc->nsvci,
827 gprs_ns_ll_str(nssd->nsvc));
828 break;
829
830 case S_NS_BLOCK:
831 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
832 nssd->nsvc->nsvci,
833 gprs_ns_ll_str(nssd->nsvc));
834 break;
835
836 case S_NS_UNBLOCK:
837 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
838 nssd->nsvc->nsvci,
839 gprs_ns_ll_str(nssd->nsvc));
840 break;
841
842 case S_NS_REPLACED:
843 printf("==> got signal NS_REPLACED: 0x%04x/%s",
844 nssd->nsvc->nsvci,
845 gprs_ns_ll_str(nssd->nsvc));
846 printf(" -> 0x%04x/%s\n",
847 nssd->old_nsvc->nsvci,
848 gprs_ns_ll_str(nssd->old_nsvc));
849 break;
850
851 default:
852 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
853 nssd->nsvc->nsvci,
854 gprs_ns_ll_str(nssd->nsvc));
855 break;
856 }
857 printf("\n");
858 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
859 return rc;
860}
861
862static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
863{
864 struct msgb *msg;
865 int ret;
866 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
867 fprintf(stderr, "message too long: %d\n", data_len);
868 return -1;
869 }
870
871 msg = gprs_ns_msgb_alloc();
872 memmove(msg->data, data, data_len);
873 msg->l2h = msg->data;
874 msgb_put(msg, data_len);
875
876 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
877 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
878 osmo_hexdump(data, data_len));
879
880 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
881
882 printf("result (%s) = %d\n\n", text, ret);
883
884 msgb_free(msg);
885
886 return ret;
887}
888
889static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
890{
891 struct gprs_nsvc *nsvc;
892
893 printf("Current NS-VCIs:\n");
894 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
895 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200896 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200897 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200898 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
899 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
900 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200901 );
902 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
903 }
904 printf("\n");
905}
906
907static void test_gbproxy()
908{
909 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
910 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200911 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200912
913 bssgp_nsi = nsi;
914 gbcfg.nsi = bssgp_nsi;
915 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
916
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200917 configure_sgsn_peer(&sgsn_peer);
918 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200919
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200920 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200921 printf("--- Initialise SGSN ---\n\n");
922
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200923 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200924 gprs_dump_nsi(nsi);
925
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200926 printf("--- Initialise BSS 1 ---\n\n");
927
928 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
929 setup_bssgp(nsi, &bss_peer[0], 0x1002);
930 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200931 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200932
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200933 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
934
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200935 printf("--- Initialise BSS 2 ---\n\n");
936
937 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
938 setup_bssgp(nsi, &bss_peer[1], 0x2002);
939 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200940 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200941
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200942 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
943
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200944 printf("--- Move BSS 1 to new port ---\n\n");
945
946 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
947 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200948 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200949
950 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
951
952 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
953 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200954 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200955
956 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
957
958 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
959 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200960 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200961
962 printf("--- Move BSS 2 to new port ---\n\n");
963
964 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
965 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200966 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200967
968 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
969
970 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
971 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200972 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200973
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200974 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
975
976 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
977 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200978 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200979
980 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
981
982 setup_bssgp(nsi, &bss_peer[0], 0x1012);
983 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200984 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200985
986 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
987
988 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
989
990 setup_bssgp(nsi, &bss_peer[0], 0x1002);
991 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200992 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200993
994 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
995
996 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
997
998 setup_bssgp(nsi, &bss_peer[0], 0x1002);
999 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001000 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001001
1002 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1003
1004 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1005
1006 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1007
1008 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1009
1010 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1011
1012 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1013
1014 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1015
1016 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1017
1018 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1019
1020 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1021
1022 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1023
1024 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1025
1026 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1027
1028 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1029
1030 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1031 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001032 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001033
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001034 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001035
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001036 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1037
1038 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1039
1040 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1041
1042 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1043
1044 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1045
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001046 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1047
1048 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1049
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001050 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001051
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001052 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001053 gprs_ns_destroy(nsi);
1054 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001055}
1056
1057static void test_gbproxy_ident_changes()
1058{
1059 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1060 struct sockaddr_in bss_peer[1] = {{0},};
1061 struct sockaddr_in sgsn_peer= {0};
1062 uint16_t nsei[2] = {0x1000, 0x2000};
1063 uint16_t nsvci[2] = {0x1001, 0x2001};
1064 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1065
1066 bssgp_nsi = nsi;
1067 gbcfg.nsi = bssgp_nsi;
1068 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1069
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001070 configure_sgsn_peer(&sgsn_peer);
1071 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001072
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001073 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001074 printf("--- Initialise SGSN ---\n\n");
1075
Jacob Erlbeck2e038f72014-07-07 10:46:00 +02001076 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001077 gprs_dump_nsi(nsi);
1078
1079 printf("--- Initialise BSS 1 ---\n\n");
1080
1081 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1082 gprs_dump_nsi(nsi);
1083
1084 printf("--- Setup BVCI 1 ---\n\n");
1085
1086 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1087 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001088 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001089
1090 printf("--- Setup BVCI 2 ---\n\n");
1091
1092 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1093 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001094 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001095
1096 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1097
1098 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1099 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1100
1101 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1102
1103 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1104 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1105
1106 printf("--- Change NSEI ---\n\n");
1107
1108 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1109 gprs_dump_nsi(nsi);
1110
1111 printf("--- Setup BVCI 1 ---\n\n");
1112
1113 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1114 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001115 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001116
1117 printf("--- Setup BVCI 3 ---\n\n");
1118
1119 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1120 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001121 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001122
1123 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1124
1125 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1126 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1127
1128 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1129 " (should fail) ---\n\n");
1130
1131 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001132 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001133 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001134 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001135
1136 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1137
1138 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1139 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1140
1141 printf("--- Change NSVCI ---\n\n");
1142
1143 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1144 gprs_dump_nsi(nsi);
1145
1146 printf("--- Setup BVCI 1 ---\n\n");
1147
1148 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1149 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001150 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001151
1152 printf("--- Setup BVCI 4 ---\n\n");
1153
1154 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1155 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001156 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001157
1158 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1159
1160 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1161 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1162
1163 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1164 " (should fail) ---\n\n");
1165
1166 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001167 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001168 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001169 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001170
1171 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1172
1173 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1174 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1175
1176 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1177
1178 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1179 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1180
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001181 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001182 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001183
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001184 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001185 gprs_ns_destroy(nsi);
1186 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001187}
1188
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001189static void test_gbproxy_ra_patching()
1190{
1191 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1192 struct sockaddr_in bss_peer[1] = {{0},};
1193 struct sockaddr_in sgsn_peer= {0};
1194 struct gprs_ra_id rai_bss =
1195 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1196 struct gprs_ra_id rai_sgsn =
1197 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1198 struct gprs_ra_id rai_unknown =
1199 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001200 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001201 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001202 const uint32_t ptmsi = 0xefe2b700;
1203 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001204 const uint32_t foreign_tlli = 0xbbc54679;
1205 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001206 struct gbproxy_tlli_info *tlli_info;
1207 struct gbproxy_peer *peer;
1208
1209 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001210
1211 bssgp_nsi = nsi;
1212 gbcfg.nsi = bssgp_nsi;
1213 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001214 gbcfg.core_mcc = 123;
1215 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001216 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001217 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001218 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001219
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001220 configure_sgsn_peer(&sgsn_peer);
1221 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001222
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001223 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001224 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001225 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1226 gbcfg.match_re, err_msg);
1227 exit(1);
1228 }
1229
1230
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001231 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001232 printf("--- Initialise SGSN ---\n\n");
1233
1234 connect_sgsn(nsi, &sgsn_peer);
1235 gprs_dump_nsi(nsi);
1236
1237 printf("--- Initialise BSS 1 ---\n\n");
1238
1239 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1240 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1241 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001242 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001243
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001244 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001245 OSMO_ASSERT(peer != NULL);
1246
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001247 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1248
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001249 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1250 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001251
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001252 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001253 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001254
1255 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1256
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001257 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1258 foreign_tlli, &rai_bss, cell_id,
1259 GPRS_SAPI_GMM, 0,
1260 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001261
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001262 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1263 foreign_tlli, 0, NULL, 0,
1264 GPRS_SAPI_GMM, 0,
1265 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001266
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001267 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1268 foreign_tlli, &rai_bss, cell_id,
1269 GPRS_SAPI_GMM, 3,
1270 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001271
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001272 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1273 foreign_tlli, 1, imsi, sizeof(imsi),
1274 GPRS_SAPI_GMM, 1,
1275 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001276
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001277 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001278 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001279 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1280 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1281 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1282 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1283 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1284 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1285 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1286 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001287
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001288 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1289 local_tlli, &rai_bss, cell_id,
1290 GPRS_SAPI_GMM, 4,
1291 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001292
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001293 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001294 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001295 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1296 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1297 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1298 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1299 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1300 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1301 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1302 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001303
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001304 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001305 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1306 local_tlli, &rai_bss, cell_id,
1307 GPRS_SAPI_GMM, 3,
1308 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001309
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001310 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001311 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001312 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1313 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1314 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1315 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1316 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1317 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1318 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1319 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001320
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001321 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1322 local_tlli, 1, imsi, sizeof(imsi),
1323 GPRS_SAPI_GMM, 2,
1324 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001325
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001326 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001327 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001328 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1329 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1330 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1331 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001332
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001333 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001334 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1335 local_tlli, &rai_bss, cell_id,
1336 GPRS_SAPI_GMM, 3,
1337 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001338
Jacob Erlbeck73685282014-05-23 20:48:07 +02001339 gbcfg.core_apn[0] = 0;
1340 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001341
1342 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001343 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1344 local_tlli, &rai_bss, cell_id,
1345 GPRS_SAPI_GMM, 3,
1346 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001347
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001348 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001349
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001350 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001351 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1352 local_tlli, &rai_bss, cell_id,
1353 GPRS_SAPI_GMM, 6,
1354 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001355
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001356 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1357 local_tlli, 1, imsi, sizeof(imsi),
1358 GPRS_SAPI_GMM, 5,
1359 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001360
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001361 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001362
1363 printf("--- RA update ---\n\n");
1364
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001365 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1366 foreign_tlli, &rai_bss, 0x7080,
1367 GPRS_SAPI_GMM, 5,
1368 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001369
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001370 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1371 foreign_tlli, 1, imsi, sizeof(imsi),
1372 GPRS_SAPI_GMM, 6,
1373 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001374
1375 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001376 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1377 local_tlli, &rai_bss, cell_id,
1378 GPRS_SAPI_GMM, 3,
1379 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001380
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001381 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001382
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001383 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001384 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1385 local_tlli, &rai_bss, cell_id,
1386 GPRS_SAPI_GMM, 6,
1387 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001388
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001389 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001390 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001391
1392 printf("--- Bad cases ---\n\n");
1393
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001394 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001395 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1396 local_tlli, &rai_bss, cell_id,
1397 GPRS_SAPI_GMM, 3,
1398 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001399
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001400 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001401 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001402
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001403 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001404 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001405
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02001406 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001407 gprs_ns_destroy(nsi);
1408 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001409}
1410
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001411static void test_gbproxy_ptmsi_patching()
1412{
1413 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1414 struct sockaddr_in bss_peer[1] = {{0},};
1415 struct sockaddr_in sgsn_peer= {0};
1416 struct gprs_ra_id rai_bss =
1417 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1418 struct gprs_ra_id rai_sgsn =
1419 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001420 struct gprs_ra_id rai_wrong_mcc_sgsn =
1421 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001422 struct gprs_ra_id rai_unknown =
1423 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1424 uint16_t cell_id = 0x1234;
1425
1426 const uint32_t sgsn_ptmsi = 0xefe2b700;
1427 const uint32_t local_sgsn_tlli = 0xefe2b700;
1428 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1429
1430 const uint32_t bss_ptmsi = 0xc00f7304;
1431 const uint32_t local_bss_tlli = 0xc00f7304;
1432 const uint32_t foreign_bss_tlli = 0x8000dead;
1433
1434 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1435 struct gbproxy_tlli_info *tlli_info;
1436 struct gbproxy_peer *peer;
1437 unsigned bss_nu = 0;
1438 unsigned sgsn_nu = 0;
1439
1440 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1441
1442 bssgp_nsi = nsi;
1443 gbcfg.nsi = bssgp_nsi;
1444 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1445 gbcfg.core_mcc = 123;
1446 gbcfg.core_mnc = 456;
1447 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1448 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1449 gbcfg.patch_ptmsi = 1;
1450 gbcfg.bss_ptmsi_state = 0;
1451 gbcfg.sgsn_tlli_state = 1;
1452
1453 configure_sgsn_peer(&sgsn_peer);
1454 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1455
1456 printf("=== %s ===\n", __func__);
1457 printf("--- Initialise SGSN ---\n\n");
1458
1459 connect_sgsn(nsi, &sgsn_peer);
1460
1461 printf("--- Initialise BSS 1 ---\n\n");
1462
1463 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1464 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1465
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001466 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001467 OSMO_ASSERT(peer != NULL);
1468
1469 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1470
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001471 gprs_dump_nsi(nsi);
1472 dump_global(stdout, 0);
1473 dump_peers(stdout, 0, 0, &gbcfg);
1474
1475 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1476
1477 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1478 foreign_bss_tlli, &rai_unknown, cell_id,
1479 GPRS_SAPI_GMM, bss_nu++,
1480 dtap_attach_req, sizeof(dtap_attach_req));
1481
1482 dump_peers(stdout, 0, 0, &gbcfg);
1483
1484 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1485 random_sgsn_tlli, 0, NULL, 0,
1486 GPRS_SAPI_GMM, sgsn_nu++,
1487 dtap_identity_req, sizeof(dtap_identity_req));
1488
1489 dump_peers(stdout, 0, 0, &gbcfg);
1490
1491 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1492 foreign_bss_tlli, &rai_bss, cell_id,
1493 GPRS_SAPI_GMM, bss_nu++,
1494 dtap_identity_resp, sizeof(dtap_identity_resp));
1495
1496 dump_peers(stdout, 0, 0, &gbcfg);
1497
1498 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1499 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1500 GPRS_SAPI_GMM, sgsn_nu++,
1501 dtap_attach_acc, sizeof(dtap_attach_acc));
1502
1503 dump_peers(stdout, 0, 0, &gbcfg);
1504
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001505 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001506 OSMO_ASSERT(tlli_info);
1507 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1508 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1509 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1510 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1511 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1512 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1513 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1514 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1515 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1516 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1517
1518 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1519 local_bss_tlli, &rai_bss, cell_id,
1520 GPRS_SAPI_GMM, bss_nu++,
1521 dtap_attach_complete, sizeof(dtap_attach_complete));
1522
1523 dump_peers(stdout, 0, 0, &gbcfg);
1524
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001525 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001526 OSMO_ASSERT(tlli_info);
1527 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1528 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1529 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1530 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1531 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1532 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1533 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1534 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1535
1536 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1537 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1538 GPRS_SAPI_GMM, sgsn_nu++,
1539 dtap_gmm_information, sizeof(dtap_gmm_information));
1540
1541 dump_peers(stdout, 0, 0, &gbcfg);
1542
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001543 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001544 OSMO_ASSERT(tlli_info);
1545 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1546 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1547 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1548 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1549
1550 /* Non-DTAP */
1551 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1552 local_bss_tlli, &rai_bss, cell_id,
1553 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1554
1555 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1556 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1557 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1558
1559 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1560 local_bss_tlli, &rai_bss, cell_id,
1561 llc_ui_ll11_dns_query_ul,
1562 sizeof(llc_ui_ll11_dns_query_ul));
1563
1564 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1565 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1566 llc_ui_ll11_dns_resp_dl,
1567 sizeof(llc_ui_ll11_dns_resp_dl));
1568
1569 dump_peers(stdout, 0, 0, &gbcfg);
1570
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001571 /* Other messages */
1572 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1573 local_bss_tlli, 1, 12);
1574
1575 dump_peers(stdout, 0, 0, &gbcfg);
1576
1577 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1578
1579 dump_peers(stdout, 0, 0, &gbcfg);
1580
1581 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1582
1583 dump_peers(stdout, 0, 0, &gbcfg);
1584
1585 /* Bad case: Invalid BVCI */
1586 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1587 local_bss_tlli, 1, 12);
1588 dump_global(stdout, 0);
1589
1590 /* Bad case: Invalid RAI */
1591 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1592
1593 dump_global(stdout, 0);
1594
1595 /* Bad case: Invalid MCC (LAC ok) */
1596 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1597 &rai_wrong_mcc_sgsn);
1598
1599 dump_global(stdout, 0);
1600
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001601 /* Detach */
1602 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1603 local_bss_tlli, &rai_bss, cell_id,
1604 GPRS_SAPI_GMM, bss_nu++,
1605 dtap_detach_req, sizeof(dtap_detach_req));
1606
1607 dump_peers(stdout, 0, 0, &gbcfg);
1608
1609 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1610 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1611 GPRS_SAPI_GMM, sgsn_nu++,
1612 dtap_detach_acc, sizeof(dtap_detach_acc));
1613
1614 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001615
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001616 dump_global(stdout, 0);
1617
1618 gbprox_reset(&gbcfg);
1619 gprs_ns_destroy(nsi);
1620 nsi = NULL;
1621}
1622
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001623static void test_gbproxy_imsi_acquisition()
1624{
1625 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1626 struct sockaddr_in bss_peer[1] = {{0},};
1627 struct sockaddr_in sgsn_peer= {0};
1628 struct gprs_ra_id rai_bss =
1629 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1630 struct gprs_ra_id rai_sgsn =
1631 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1632 struct gprs_ra_id rai_wrong_mcc_sgsn =
1633 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1634 struct gprs_ra_id rai_unknown =
1635 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1636 uint16_t cell_id = 0x1234;
1637
1638 const uint32_t sgsn_ptmsi = 0xefe2b700;
1639 const uint32_t local_sgsn_tlli = 0xefe2b700;
1640 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1641
1642 const uint32_t bss_ptmsi = 0xc00f7304;
1643 const uint32_t local_bss_tlli = 0xc00f7304;
1644 const uint32_t foreign_bss_tlli = 0x8000dead;
1645
1646 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1647 struct gbproxy_tlli_info *tlli_info;
1648 struct gbproxy_peer *peer;
1649 unsigned bss_nu = 0;
1650 unsigned sgsn_nu = 0;
1651
1652 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1653
1654 bssgp_nsi = nsi;
1655 gbcfg.nsi = bssgp_nsi;
1656 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1657 gbcfg.core_mcc = 123;
1658 gbcfg.core_mnc = 456;
1659 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1660 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1661 gbcfg.patch_ptmsi = 1;
1662 gbcfg.bss_ptmsi_state = 0;
1663 gbcfg.sgsn_tlli_state = 1;
1664
1665 configure_sgsn_peer(&sgsn_peer);
1666 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1667
1668 printf("=== %s ===\n", __func__);
1669 printf("--- Initialise SGSN ---\n\n");
1670
1671 connect_sgsn(nsi, &sgsn_peer);
1672
1673 printf("--- Initialise BSS 1 ---\n\n");
1674
1675 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1676 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1677
1678 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1679 OSMO_ASSERT(peer != NULL);
1680
1681 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1682
1683 gprs_dump_nsi(nsi);
1684 dump_global(stdout, 0);
1685 dump_peers(stdout, 0, 0, &gbcfg);
1686
1687 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1688
1689 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1690 foreign_bss_tlli, &rai_unknown, cell_id,
1691 GPRS_SAPI_GMM, bss_nu++,
1692 dtap_attach_req, sizeof(dtap_attach_req));
1693
1694 dump_peers(stdout, 0, 0, &gbcfg);
1695
1696 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1697 random_sgsn_tlli, 0, NULL, 0,
1698 GPRS_SAPI_GMM, sgsn_nu++,
1699 dtap_identity_req, sizeof(dtap_identity_req));
1700
1701 dump_peers(stdout, 0, 0, &gbcfg);
1702
1703 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1704 foreign_bss_tlli, &rai_bss, cell_id,
1705 GPRS_SAPI_GMM, bss_nu++,
1706 dtap_identity_resp, sizeof(dtap_identity_resp));
1707
1708 dump_peers(stdout, 0, 0, &gbcfg);
1709
1710 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1711 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1712 GPRS_SAPI_GMM, sgsn_nu++,
1713 dtap_attach_acc, sizeof(dtap_attach_acc));
1714
1715 dump_peers(stdout, 0, 0, &gbcfg);
1716
1717 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1718 OSMO_ASSERT(tlli_info);
1719 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1720 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1721 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1722 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1723 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1724 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1725 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1726 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1727 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1728 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1729
1730 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1731 local_bss_tlli, &rai_bss, cell_id,
1732 GPRS_SAPI_GMM, bss_nu++,
1733 dtap_attach_complete, sizeof(dtap_attach_complete));
1734
1735 dump_peers(stdout, 0, 0, &gbcfg);
1736
1737 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1738 OSMO_ASSERT(tlli_info);
1739 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1740 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1741 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1742 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1743 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1744 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1745 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1746 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1747
1748 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1749 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1750 GPRS_SAPI_GMM, sgsn_nu++,
1751 dtap_gmm_information, sizeof(dtap_gmm_information));
1752
1753 dump_peers(stdout, 0, 0, &gbcfg);
1754
1755 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1756 OSMO_ASSERT(tlli_info);
1757 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1758 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1759 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1760 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1761
1762 /* Non-DTAP */
1763 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1764 local_bss_tlli, &rai_bss, cell_id,
1765 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1766
1767 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1768 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1769 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1770
1771 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1772 local_bss_tlli, &rai_bss, cell_id,
1773 llc_ui_ll11_dns_query_ul,
1774 sizeof(llc_ui_ll11_dns_query_ul));
1775
1776 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1777 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1778 llc_ui_ll11_dns_resp_dl,
1779 sizeof(llc_ui_ll11_dns_resp_dl));
1780
1781 dump_peers(stdout, 0, 0, &gbcfg);
1782
1783 /* Other messages */
1784 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1785 local_bss_tlli, 1, 12);
1786
1787 dump_peers(stdout, 0, 0, &gbcfg);
1788
1789 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
1790 local_sgsn_tlli, 1, 12);
1791
1792 dump_peers(stdout, 0, 0, &gbcfg);
1793
1794 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1795
1796 dump_peers(stdout, 0, 0, &gbcfg);
1797
1798 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1799
1800 dump_peers(stdout, 0, 0, &gbcfg);
1801
1802 /* Bad case: Invalid BVCI */
1803 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1804 local_bss_tlli, 1, 12);
1805 dump_global(stdout, 0);
1806
1807 /* Bad case: Invalid RAI */
1808 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1809
1810 dump_global(stdout, 0);
1811
1812 /* Bad case: Invalid MCC (LAC ok) */
1813 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1814 &rai_wrong_mcc_sgsn);
1815
1816 dump_global(stdout, 0);
1817
1818 /* Detach */
1819 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1820 local_bss_tlli, &rai_bss, cell_id,
1821 GPRS_SAPI_GMM, bss_nu++,
1822 dtap_detach_req, sizeof(dtap_detach_req));
1823
1824 dump_peers(stdout, 0, 0, &gbcfg);
1825
1826 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1827 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1828 GPRS_SAPI_GMM, sgsn_nu++,
1829 dtap_detach_acc, sizeof(dtap_detach_acc));
1830
1831 dump_peers(stdout, 0, 0, &gbcfg);
1832
1833 dump_global(stdout, 0);
1834
1835 gbprox_reset(&gbcfg);
1836 gprs_ns_destroy(nsi);
1837 nsi = NULL;
1838}
1839
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001840/* TODO: Move tlv testing to libosmocore */
1841int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
1842int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
1843 uint8_t **value);
1844int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
1845 size_t *value_len);
1846int lv_shift(uint8_t **data, size_t *data_len,
1847 uint8_t **value, size_t *value_len);
1848
1849static void check_tlv_match(uint8_t **data, size_t *data_len,
1850 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
1851{
1852 uint8_t *value;
1853 size_t value_len;
1854 int rc;
1855
1856 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
1857 OSMO_ASSERT(rc == 0);
1858
1859 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001860 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001861 OSMO_ASSERT(value_len == exp_len);
1862 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1863}
1864
1865static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
1866 uint8_t tag, size_t len, const uint8_t *exp_val)
1867{
1868 uint8_t *value;
1869 int rc;
1870
1871 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
1872 OSMO_ASSERT(rc == 0);
1873
1874 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001875 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001876 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1877}
1878
1879static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
1880 size_t len, const uint8_t *exp_val)
1881{
1882 uint8_t *value;
1883 int rc;
1884
1885 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001886 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001887 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1888}
1889
1890static void check_lv_shift(uint8_t **data, size_t *data_len,
1891 size_t exp_len, const uint8_t *exp_val)
1892{
1893 uint8_t *value;
1894 size_t value_len;
1895 int rc;
1896
1897 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001898 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001899 OSMO_ASSERT(value_len == exp_len);
1900 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1901}
1902
1903static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
1904 const uint8_t *test_data)
1905{
1906 uint8_t buf[300] = {0};
1907
1908 uint8_t *unchanged_ptr = buf - 1;
1909 size_t unchanged_len = 0xdead;
1910 size_t tmp_data_len = data_len;
1911 uint8_t *value = unchanged_ptr;
1912 size_t value_len = unchanged_len;
1913 uint8_t *data = buf;
1914
1915 OSMO_ASSERT(data_len <= sizeof(buf));
1916
1917 tlv_put(data, tag, len, test_data);
1918 if (data_len < len + 2) {
1919 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
1920 tag, &value, &value_len));
1921 OSMO_ASSERT(tmp_data_len == 0);
1922 OSMO_ASSERT(data == buf + data_len);
1923 OSMO_ASSERT(value == unchanged_ptr);
1924 OSMO_ASSERT(value_len == unchanged_len);
1925 } else {
1926 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
1927 tag, &value, &value_len));
1928 OSMO_ASSERT(value != unchanged_ptr);
1929 OSMO_ASSERT(value_len != unchanged_len);
1930 }
1931}
1932
1933static void check_tv_fixed_match_data_len(size_t data_len,
1934 uint8_t tag, size_t len,
1935 const uint8_t *test_data)
1936{
1937 uint8_t buf[300] = {0};
1938
1939 uint8_t *unchanged_ptr = buf - 1;
1940 size_t tmp_data_len = data_len;
1941 uint8_t *value = unchanged_ptr;
1942 uint8_t *data = buf;
1943
1944 OSMO_ASSERT(data_len <= sizeof(buf));
1945
1946 tv_fixed_put(data, tag, len, test_data);
1947
1948 if (data_len < len + 1) {
1949 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
1950 tag, len, &value));
1951 OSMO_ASSERT(tmp_data_len == 0);
1952 OSMO_ASSERT(data == buf + data_len);
1953 OSMO_ASSERT(value == unchanged_ptr);
1954 } else {
1955 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
1956 tag, len, &value));
1957 OSMO_ASSERT(value != unchanged_ptr);
1958 }
1959}
1960
1961static void check_v_fixed_shift_data_len(size_t data_len,
1962 size_t len, const uint8_t *test_data)
1963{
1964 uint8_t buf[300] = {0};
1965
1966 uint8_t *unchanged_ptr = buf - 1;
1967 size_t tmp_data_len = data_len;
1968 uint8_t *value = unchanged_ptr;
1969 uint8_t *data = buf;
1970
1971 OSMO_ASSERT(data_len <= sizeof(buf));
1972
1973 memcpy(data, test_data, len);
1974
1975 if (data_len < len) {
1976 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
1977 len, &value));
1978 OSMO_ASSERT(tmp_data_len == 0);
1979 OSMO_ASSERT(data == buf + data_len);
1980 OSMO_ASSERT(value == unchanged_ptr);
1981 } else {
1982 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
1983 len, &value));
1984 OSMO_ASSERT(value != unchanged_ptr);
1985 }
1986}
1987
1988static void check_lv_shift_data_len(size_t data_len,
1989 size_t len, const uint8_t *test_data)
1990{
1991 uint8_t buf[300] = {0};
1992
1993 uint8_t *unchanged_ptr = buf - 1;
1994 size_t unchanged_len = 0xdead;
1995 size_t tmp_data_len = data_len;
1996 uint8_t *value = unchanged_ptr;
1997 size_t value_len = unchanged_len;
1998 uint8_t *data = buf;
1999
2000 lv_put(data, len, test_data);
2001 if (data_len < len + 1) {
2002 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2003 &value, &value_len));
2004 OSMO_ASSERT(tmp_data_len == 0);
2005 OSMO_ASSERT(data == buf + data_len);
2006 OSMO_ASSERT(value == unchanged_ptr);
2007 OSMO_ASSERT(value_len == unchanged_len);
2008 } else {
2009 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2010 &value, &value_len));
2011 OSMO_ASSERT(value != unchanged_ptr);
2012 OSMO_ASSERT(value_len != unchanged_len);
2013 }
2014}
2015
2016static void test_tlv_shift_functions()
2017{
2018 uint8_t test_data[1024];
2019 uint8_t buf[1024];
2020 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002021 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002022 uint8_t *data;
2023 size_t data_len;
2024 const uint8_t tag = 0x1a;
2025
2026 printf("Test shift functions\n");
2027
2028 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2029 test_data[i] = (uint8_t)i;
2030
2031 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002032 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002033
2034 memset(buf, 0xee, sizeof(buf));
2035 data_end = data = buf;
2036
2037 for (i = 0; i < iterations; i++) {
2038 data_end = tlv_put(data_end, tag, len, test_data);
2039 data_end = tv_fixed_put(data_end, tag, len, test_data);
2040 /* v_fixed_put */
2041 memcpy(data_end, test_data, len);
2042 data_end += len;
2043 data_end = lv_put(data_end, len, test_data);
2044 }
2045
2046 data_len = data_end - data;
2047 OSMO_ASSERT(data_len <= sizeof(buf));
2048
2049 for (i = 0; i < iterations; i++) {
2050 check_tlv_match(&data, &data_len, tag, len, test_data);
2051 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2052 check_v_fixed_shift(&data, &data_len, len, test_data);
2053 check_lv_shift(&data, &data_len, len, test_data);
2054 }
2055
2056 OSMO_ASSERT(data == data_end);
2057
2058 /* Test at end of data */
2059
2060 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2061 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2062 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2063 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2064
2065 /* Test invalid data_len */
2066 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2067 check_tlv_match_data_len(data_len, tag, len, test_data);
2068 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2069 check_v_fixed_shift_data_len(data_len, len, test_data);
2070 check_lv_shift_data_len(data_len, len, test_data);
2071 }
2072 }
2073}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002074
2075static void test_gbproxy_tlli_expire(void)
2076{
2077 struct gbproxy_config cfg = {0};
2078 struct gbproxy_peer *peer;
2079 const char *err_msg = NULL;
2080 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2081 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002082 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002083 const uint32_t tlli1 = 1234 | 0xc0000000;
2084 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002085 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002086 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002087 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002088
2089 printf("Test TLLI info expiry\n\n");
2090
2091 gbproxy_init_config(&cfg);
2092
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002093 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002094 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2095 err_msg);
2096 OSMO_ASSERT(err_msg == NULL);
2097 }
2098
2099 {
2100 struct gbproxy_tlli_info *tlli_info;
2101
2102 printf("Test TLLI replacement:\n");
2103
2104 cfg.tlli_max_len = 0;
2105 cfg.tlli_max_age = 0;
2106 peer = gbproxy_peer_alloc(&cfg, 20);
2107 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2108
2109 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002110 tlli_info = gbproxy_register_tlli(peer, tlli1,
2111 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002112 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002113 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002114 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2115
2116 /* replace the old entry */
2117 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002118 tlli_info = gbproxy_register_tlli(peer, tlli2,
2119 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002120 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002121 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002122 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2123
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002124 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002125
2126 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002127 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002128 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002129 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002130 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002131 OSMO_ASSERT(!tlli_info);
2132
2133 printf("\n");
2134
2135 gbproxy_peer_free(peer);
2136 }
2137
2138 {
2139 struct gbproxy_tlli_info *tlli_info;
2140
2141 printf("Test IMSI replacement:\n");
2142
2143 cfg.tlli_max_len = 0;
2144 cfg.tlli_max_age = 0;
2145 peer = gbproxy_peer_alloc(&cfg, 20);
2146 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2147
2148 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002149 tlli_info = gbproxy_register_tlli(peer, tlli1,
2150 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002151 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002152 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002153 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2154
2155 /* try to replace the old entry */
2156 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002157 tlli_info = gbproxy_register_tlli(peer, tlli1,
2158 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002159 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002160 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002161 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2162
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002163 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002164
2165 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002166 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002167 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002168 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002169 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002170 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002171
2172 printf("\n");
2173
2174 gbproxy_peer_free(peer);
2175 }
2176
2177 {
2178 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002179 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002180
2181 printf("Test TLLI expiry, max_len == 1:\n");
2182
2183 cfg.tlli_max_len = 1;
2184 cfg.tlli_max_age = 0;
2185 peer = gbproxy_peer_alloc(&cfg, 20);
2186 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2187
2188 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002189 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002190 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2191
2192 /* replace the old entry */
2193 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002194 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002195 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2196
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002197 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002198 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002199 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2200
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002201 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002202
2203 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002204 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002205 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002206 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002207 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002208 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002209
2210 printf("\n");
2211
2212 gbproxy_peer_free(peer);
2213 }
2214
2215 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002216 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002217 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002218
2219 printf("Test TLLI expiry, max_age == 1:\n");
2220
2221 cfg.tlli_max_len = 0;
2222 cfg.tlli_max_age = 1;
2223 peer = gbproxy_peer_alloc(&cfg, 20);
2224 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2225
2226 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002227 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002228 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2229
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002230 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002231 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002232 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002233 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2234
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002235 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002236 OSMO_ASSERT(num_removed == 1);
2237 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2238
2239 dump_peers(stdout, 2, now + 2, &cfg);
2240
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002241 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002242 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002243 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002244 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002245 OSMO_ASSERT(tlli_info);
2246 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2247
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002248 printf("\n");
2249
2250 gbproxy_peer_free(peer);
2251 }
2252
2253 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002254 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002255 int num_removed;
2256
2257 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2258
2259 cfg.tlli_max_len = 0;
2260 cfg.tlli_max_age = 1;
2261 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002262 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2263
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002264 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002265 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002266 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2267
2268 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002269 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002270 now + 1);
2271 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2272
2273 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002274 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2275 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002276 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2277
2278 dump_peers(stdout, 2, now + 2, &cfg);
2279
2280 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002281 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002282 OSMO_ASSERT(num_removed == 2);
2283 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2284
2285 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002286
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002287 /* verify that tlli3 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002288 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002289 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002290 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002291 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002292 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002293 OSMO_ASSERT(tlli_info);
2294 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2295
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002296 printf("\n");
2297
2298 gbproxy_peer_free(peer);
2299 }
2300}
2301
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002302static void test_gbproxy_imsi_matching(void)
2303{
2304 struct gbproxy_config cfg = {0};
2305 struct gbproxy_peer *peer;
2306 const char *err_msg = NULL;
2307 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2308 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2309 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2310 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2311 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2312 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2313 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2314 const char *filter_re1 = ".*";
2315 const char *filter_re2 = "^1234";
2316 const char *filter_re3 = "^4321";
2317 const char *filter_re4_bad = "^12[";
2318
2319 printf("=== Test IMSI/TMSI matching ===\n\n");
2320
2321 gbproxy_init_config(&cfg);
2322 OSMO_ASSERT(cfg.check_imsi == 0);
2323
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002324 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002325 OSMO_ASSERT(cfg.check_imsi == 1);
2326
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002327 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002328 OSMO_ASSERT(cfg.check_imsi == 1);
2329
2330 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002331 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002332 OSMO_ASSERT(err_msg != NULL);
2333 OSMO_ASSERT(cfg.check_imsi == 0);
2334
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002335 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002336 OSMO_ASSERT(cfg.check_imsi == 1);
2337
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002338 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002339 OSMO_ASSERT(cfg.check_imsi == 0);
2340
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002341 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002342 OSMO_ASSERT(cfg.check_imsi == 1);
2343
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002344 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002345 OSMO_ASSERT(cfg.check_imsi == 0);
2346
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002347 peer = gbproxy_peer_alloc(&cfg, 20);
2348
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002349 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002350 OSMO_ASSERT(cfg.check_imsi == 1);
2351
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002352 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2353 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002354 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002355 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002356 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002357 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2358 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2359 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2360 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2361 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002362
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002363 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002364 OSMO_ASSERT(cfg.check_imsi == 1);
2365
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002366 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2367 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2368 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2369 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2370 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2371 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2372 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002373
2374 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2375
2376 gbproxy_peer_free(peer);
2377}
2378
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002379static struct log_info_cat gprs_categories[] = {
2380 [DGPRS] = {
2381 .name = "DGPRS",
2382 .description = "GPRS Packet Service",
2383 .enabled = 1, .loglevel = LOGL_DEBUG,
2384 },
2385 [DNS] = {
2386 .name = "DNS",
2387 .description = "GPRS Network Service (NS)",
2388 .enabled = 1, .loglevel = LOGL_INFO,
2389 },
2390 [DBSSGP] = {
2391 .name = "DBSSGP",
2392 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2393 .enabled = 1, .loglevel = LOGL_DEBUG,
2394 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002395};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002396
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002397static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002398 .cat = gprs_categories,
2399 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02002400};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002401
2402int main(int argc, char **argv)
2403{
2404 osmo_init_logging(&info);
2405 log_set_use_color(osmo_stderr_target, 0);
2406 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece62772014-08-04 15:42:36 +02002407 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002408
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002409 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02002410 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
2411 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002412
2413 rate_ctr_init(NULL);
2414
2415 setlinebuf(stdout);
2416
2417 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02002418 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002419 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002420 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002421 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002422 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02002423 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02002424 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002425 test_gbproxy_imsi_acquisition();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002426 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02002427 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02002428
2429 exit(EXIT_SUCCESS);
2430}