blob: 6fd2e5546b13b0b3f286ddb4e4c8120951e1ea0d [file] [log] [blame]
Jacob Erlbeck76fa57a2013-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 Freytherf28f8f52014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck76fa57a2013-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 Erlbeck077abce2014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck31132872014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck76fa57a2013-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 Freyther8ac3a722014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeck322d9f92014-08-15 14:56:28 +020035#include <openbsc/gprs_llc.h>
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020036#include <openbsc/debug.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020037
38#define REMOTE_BSS_ADDR 0x01020304
39#define REMOTE_SGSN_ADDR 0x05060708
40
Jacob Erlbeck45017722013-10-18 13:04:47 +020041#define SGSN_NSEI 0x0100
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020042
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020043struct gbproxy_config gbcfg = {0};
44
Holger Hans Peter Freytherf28f8f52014-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 Erlbeckc404c082014-08-08 08:37:37 +020073static int dump_peers(FILE *stream, int indent, time_t now,
74 struct gbproxy_config *cfg)
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020075{
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020076 struct gbproxy_peer *peer;
Holger Hans Peter Freytherf28f8f52014-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 Freytherf28f8f52014-08-04 11:26:54 +020081
82 rc = fprintf(stream, "%*sPeers:\n", indent, "");
83 if (rc < 0)
84 return rc;
85
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +020086 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020087 struct gbproxy_tlli_info *tlli_info;
88 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherf28f8f52014-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 Erlbeckc404c082014-08-08 08:37:37 +0200120 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck9ac42ba2014-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 Erlbeck31132872014-08-11 17:26:21 +0200129 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck383c8412014-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 Erlbeck4c0f6982014-08-22 17:10:01 +0200140 fprintf(stream, ", IMSI %s, AGE %d",
141 mi_buf, (int)age);
142
143 if (tlli_info->imsi_acq_pending)
144 fprintf(stream, ", IMSI acquisition in progress");
145
146 if (!llist_empty(&tlli_info->stored_msgs))
147 fprintf(stream, ", stored messages");
148
149 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200150 if (rc < 0)
151 return rc;
152 }
153 }
154
155 return 0;
156}
157
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200158/* DTAP - Attach Request */
159static const unsigned char dtap_attach_req[] = {
160 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
161 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
162 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
163 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
164 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
165 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200166};
167
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200168/* DTAP - Identity Request */
169static const unsigned char dtap_identity_req[] = {
170 0x08, 0x15, 0x01
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200171};
172
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200173/* DTAP - Identity Response */
174static const unsigned char dtap_identity_resp[] = {
175 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
176 0x16, 0x17, 0x18
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200177};
178
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200179/* DTAP - Attach Accept */
180static const unsigned char dtap_attach_acc[] = {
181 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
182 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
183 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200184};
185
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200186/* DTAP - Attach Complete */
187static const unsigned char dtap_attach_complete[] = {
188 0x08, 0x03
Jacob Erlbeck31132872014-08-11 17:26:21 +0200189};
190
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200191/* DTAP - GMM Information */
192static const unsigned char dtap_gmm_information[] = {
193 0x08, 0x21
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200194};
195
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200196/* DTAP - Routing Area Update Request */
197static const unsigned char dtap_ra_upd_req[] = {
198 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
199 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
200 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
201 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
202 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
203 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
204 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200205};
206
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200207/* DTAP - Routing Area Update Accept */
208static const unsigned char dtap_ra_upd_acc[] = {
209 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
210 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
211 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200212};
213
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200214/* DTAP - Activate PDP Context Request */
215static const unsigned char dtap_act_pdp_ctx_req[] = {
216 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200217 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
219 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
220 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
221 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200222 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200223};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200224
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200225/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200226/* normal detach, power_off = 1 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200227static const unsigned char dtap_detach_po_req[] = {
228 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
229 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200230};
231
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200232/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200233/* normal detach, power_off = 0 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200234static const unsigned char dtap_detach_req[] = {
235 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
236 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200237};
238
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200239/* DTAP - Detach Accept */
240static const unsigned char dtap_detach_acc[] = {
241 0x08, 0x06, 0x00
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200242};
243
Jacob Erlbeck70e00de2014-08-15 17:20:06 +0200244/* GPRS-LLC - SAPI: LLGMM, U, XID */
245static const unsigned char llc_u_xid_ul[] = {
246 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
247 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
248};
249
250/* GPRS-LLC - SAPI: LLGMM, U, XID */
251static const unsigned char llc_u_xid_dl[] = {
252 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
253 0xe4, 0xa9, 0x1a, 0x9e
254};
255
256/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
257static const unsigned char llc_ui_ll11_dns_query_ul[] = {
258 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
259 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
260 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
261 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
262 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
263 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
264 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
265 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
266 0x8f, 0x07
267};
268
269/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
270static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
271 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
272 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
273 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
274 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
275 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
276 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
277 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
278 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
279 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
280 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
281 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
282 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
283 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
284 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
285 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
286 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
287 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
288 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
289 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
290 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
291 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
292 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
293 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
294 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
295 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
296 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
297};
298
Jacob Erlbeck45017722013-10-18 13:04:47 +0200299static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
300 struct sockaddr_in *peer, const unsigned char* data,
301 size_t data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200302
303static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
304 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
305{
306 /* GPRS Network Service, PDU type: NS_RESET,
307 */
308 unsigned char msg[12] = {
309 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
310 0x04, 0x82, 0x11, 0x22
311 };
312
313 msg[3] = cause;
314 msg[6] = nsvci / 256;
315 msg[7] = nsvci % 256;
316 msg[10] = nsei / 256;
317 msg[11] = nsei % 256;
318
319 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
320}
321
Jacob Erlbeck45017722013-10-18 13:04:47 +0200322static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
323 uint16_t nsvci, uint16_t nsei)
324{
325 /* GPRS Network Service, PDU type: NS_RESET_ACK,
326 */
327 unsigned char msg[9] = {
328 0x03, 0x01, 0x82, 0x11, 0x22,
329 0x04, 0x82, 0x11, 0x22
330 };
331
332 msg[3] = nsvci / 256;
333 msg[4] = nsvci % 256;
334 msg[7] = nsei / 256;
335 msg[8] = nsei % 256;
336
337 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
338}
339
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200340static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
341{
342 /* GPRS Network Service, PDU type: NS_ALIVE */
343 unsigned char msg[1] = {
344 0x0a
345 };
346
347 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
348}
349
350static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
351{
352 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
353 unsigned char msg[1] = {
354 0x0b
355 };
356
357 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
358}
359
360static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
361{
362 /* GPRS Network Service, PDU type: NS_UNBLOCK */
363 unsigned char msg[1] = {
364 0x06
365 };
366
367 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
368}
369
Jacob Erlbeck45017722013-10-18 13:04:47 +0200370static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
371{
372 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
373 unsigned char msg[1] = {
374 0x07
375 };
376
377 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
378}
379
380static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
381 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200382 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
383{
384 /* GPRS Network Service, PDU type: NS_UNITDATA */
385 unsigned char msg[4096] = {
386 0x00, 0x00, 0x00, 0x00
387 };
388
389 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
390
391 msg[2] = nsbvci / 256;
392 msg[3] = nsbvci % 256;
393 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
394
Jacob Erlbeck45017722013-10-18 13:04:47 +0200395 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200396}
397
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200398static void send_bssgp_ul_unitdata(
399 struct gprs_ns_inst *nsi, const char *text,
400 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
401 struct gprs_ra_id *raid, uint16_t cell_id,
402 const uint8_t *llc_msg, size_t llc_msg_size)
403{
404 /* GPRS Network Service, PDU type: NS_UNITDATA */
405 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
406 unsigned char msg[4096] = {
407 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
408 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
409 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
410 };
411
412 size_t bssgp_msg_size = 23 + llc_msg_size;
413
414 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
415
416 gsm48_construct_ra(msg + 10, raid);
417 msg[1] = (uint8_t)(tlli >> 24);
418 msg[2] = (uint8_t)(tlli >> 16);
419 msg[3] = (uint8_t)(tlli >> 8);
420 msg[4] = (uint8_t)(tlli >> 0);
421 msg[16] = cell_id / 256;
422 msg[17] = cell_id % 256;
423 msg[21] = llc_msg_size / 256;
424 msg[22] = llc_msg_size % 256;
425 memcpy(msg + 23, llc_msg, llc_msg_size);
426
427 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
428 src_addr, nsbvci, msg, bssgp_msg_size);
429}
430
431static void send_bssgp_dl_unitdata(
432 struct gprs_ns_inst *nsi, const char *text,
433 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
434 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
435 const uint8_t *llc_msg, size_t llc_msg_size)
436{
437 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
438 unsigned char msg[4096] = {
439 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
440 0x16, 0x82, 0x02, 0x58,
441 };
442 unsigned char racap_drx[] = {
443 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
444 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
445 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
446 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
447 };
448
449 size_t bssgp_msg_size = 0;
450
451 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
452
453 msg[1] = (uint8_t)(tlli >> 24);
454 msg[2] = (uint8_t)(tlli >> 16);
455 msg[3] = (uint8_t)(tlli >> 8);
456 msg[4] = (uint8_t)(tlli >> 0);
457
458 bssgp_msg_size = 12;
459
460 if (with_racap_drx) {
461 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
462 bssgp_msg_size += sizeof(racap_drx);
463 }
464
465 if (imsi) {
466 OSMO_ASSERT(imsi_size <= 127);
467 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
468 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
469 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
470 bssgp_msg_size += 2 + imsi_size;
471 }
472
473 if ((bssgp_msg_size % 4) != 0) {
474 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
475 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
476 msg[bssgp_msg_size + 1] = 0x80 | abytes;
477 memset(msg + bssgp_msg_size + 2, 0, abytes);
478 bssgp_msg_size += 2 + abytes;
479 }
480
481 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
482 if (llc_msg_size < 128) {
483 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
484 bssgp_msg_size += 2;
485 } else {
486 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
487 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
488 bssgp_msg_size += 3;
489 }
490 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
491 bssgp_msg_size += llc_msg_size;
492
493
494 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
495 src_addr, nsbvci, msg, bssgp_msg_size);
496}
497
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200498static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
499 uint16_t bvci)
500{
501 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
502 * BSSGP RESET */
Jacob Erlbeck8a600ae2014-08-06 12:38:10 +0200503 unsigned char msg[18] = {
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200504 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeck3f086322014-06-02 10:48:59 +0200505 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
506 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200507 };
508
509 msg[3] = bvci / 256;
510 msg[4] = bvci % 256;
511
Jacob Erlbeck45017722013-10-18 13:04:47 +0200512 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
513}
514
515static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
516 struct sockaddr_in *src_addr, uint16_t bvci)
517{
518 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
519 * BSSGP RESET_ACK */
520 static unsigned char msg[5] = {
521 0x23, 0x04, 0x82, 0x00,
522 0x00
523 };
524
525 msg[3] = bvci / 256;
526 msg[4] = bvci % 256;
527
528 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200529}
530
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200531static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
532 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200533 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200534 struct gprs_ra_id *raid)
535{
536 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
537 unsigned char msg[15] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200538 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
539 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200540 };
541
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200542 msg[3] = (uint8_t)(tlli >> 24);
543 msg[4] = (uint8_t)(tlli >> 16);
544 msg[5] = (uint8_t)(tlli >> 8);
545 msg[6] = (uint8_t)(tlli >> 0);
546
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200547 gsm48_construct_ra(msg + 9, raid);
548
549 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
550}
551
552static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
553 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200554 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200555 struct gprs_ra_id *raid)
556{
557 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
558 unsigned char msg[18] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200559 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
560 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200561 0x81, 0x01
562 };
563
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200564 msg[3] = (uint8_t)(tlli >> 24);
565 msg[4] = (uint8_t)(tlli >> 16);
566 msg[5] = (uint8_t)(tlli >> 8);
567 msg[6] = (uint8_t)(tlli >> 0);
568
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200569 gsm48_construct_ra(msg + 9, raid);
570
571 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
572}
573
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200574static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
575 struct sockaddr_in *src_addr,
576 uint16_t bvci, uint32_t tlli,
577 unsigned n_frames, unsigned n_octets)
578{
579 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
580 unsigned char msg[] = {
581 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
582 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
583 /* n octets */ 0xff, 0xff, 0xff
584 };
585
586 msg[3] = (uint8_t)(tlli >> 24);
587 msg[4] = (uint8_t)(tlli >> 16);
588 msg[5] = (uint8_t)(tlli >> 8);
589 msg[6] = (uint8_t)(tlli >> 0);
590 msg[9] = (uint8_t)(n_frames);
591 msg[12] = (uint8_t)(bvci >> 8);
592 msg[13] = (uint8_t)(bvci >> 0);
593 msg[16] = (uint8_t)(n_octets >> 16);
594 msg[17] = (uint8_t)(n_octets >> 8);
595 msg[18] = (uint8_t)(n_octets >> 0);
596
597 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
598}
599
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200600static void send_llc_ul_ui(
601 struct gprs_ns_inst *nsi, const char *text,
602 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
603 struct gprs_ra_id *raid, uint16_t cell_id,
604 unsigned sapi, unsigned nu,
605 const uint8_t *msg, size_t msg_size)
606{
607 unsigned char llc_msg[4096] = {
608 0x00, 0xc0, 0x01
609 };
610
611 size_t llc_msg_size = 3 + msg_size + 3;
612 uint8_t e_bit = 0;
613 uint8_t pm_bit = 1;
614 unsigned fcs;
615
616 nu &= 0x01ff;
617
618 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
619
620 llc_msg[0] = (sapi & 0x0f);
621 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
622 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
623
624 memcpy(llc_msg + 3, msg, msg_size);
625
626 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
627 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
628 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
629 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
630
631 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
632 src_addr, nsbvci, tlli, raid, cell_id,
633 llc_msg, llc_msg_size);
634}
635
636static void send_llc_dl_ui(
637 struct gprs_ns_inst *nsi, const char *text,
638 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
639 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
640 unsigned sapi, unsigned nu,
641 const uint8_t *msg, size_t msg_size)
642{
643 /* GPRS Network Service, PDU type: NS_UNITDATA */
644 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
645 unsigned char llc_msg[4096] = {
646 0x00, 0x00, 0x01
647 };
648
649 size_t llc_msg_size = 3 + msg_size + 3;
650 uint8_t e_bit = 0;
651 uint8_t pm_bit = 1;
652 unsigned fcs;
653
654 nu &= 0x01ff;
655
656 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
657
658 llc_msg[0] = 0x40 | (sapi & 0x0f);
659 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
660 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
661
662 memcpy(llc_msg + 3, msg, msg_size);
663
664 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
665 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
666 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
667 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
668
669 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
670 src_addr, nsbvci, tlli,
671 with_racap_drx, imsi, imsi_size,
672 llc_msg, llc_msg_size);
673}
674
675
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200676static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
677 uint16_t nsvci, uint16_t nsei)
678{
679 printf("Setup NS-VC: remote 0x%08x:%d, "
680 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
681 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
682 nsvci, nsvci, nsei, nsei);
683
684 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
685 send_ns_alive(nsi, src_addr);
686 send_ns_unblock(nsi, src_addr);
687 send_ns_alive_ack(nsi, src_addr);
688}
689
690static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
691 uint16_t bvci)
692{
693 printf("Setup BSSGP: remote 0x%08x:%d, "
694 "BVCI 0x%04x(%d)\n\n",
695 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
696 bvci, bvci);
697
698 send_bssgp_reset(nsi, src_addr, bvci);
699}
700
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200701static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer)
702{
703 gprs_ns_nsip_connect(nsi, sgsn_peer, SGSN_NSEI, SGSN_NSEI+1);
704 send_ns_reset_ack(nsi, sgsn_peer, SGSN_NSEI+1, SGSN_NSEI);
705 send_ns_alive_ack(nsi, sgsn_peer);
706 send_ns_unblock_ack(nsi, sgsn_peer);
707 send_ns_alive(nsi, sgsn_peer);
708}
709
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200710static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
711{
712 sgsn_peer->sin_family = AF_INET;
713 sgsn_peer->sin_port = htons(32000);
714 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
715}
716
717static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
718{
719 size_t i;
720
721 for (i = 0; i < size; ++i) {
722 bss_peers[i].sin_family = AF_INET;
723 bss_peers[i].sin_port = htons((i + 1) * 1111);
724 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
725 }
726}
727
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200728int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
729 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
730
731/* override */
732int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
733 struct msgb *msg, uint16_t bvci)
734{
735 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
736 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200737 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200738
739 switch (event) {
740 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200741 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200742 default:
743 break;
744 }
745 return 0;
746}
747
748/* override */
749ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
750 const struct sockaddr *dest_addr, socklen_t addrlen)
751{
752 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
753 const struct sockaddr *, socklen_t);
754 static sendto_t real_sendto = NULL;
755 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200756 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200757
758 if (!real_sendto)
759 real_sendto = dlsym(RTLD_NEXT, "sendto");
760
761 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200762 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
763 dest_host, dest_port,
764 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200765 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200766 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
767 dest_host, dest_port,
768 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200769 else
770 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
771
772 return len;
773}
774
775/* override */
776int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
777{
Jacob Erlbeck45017722013-10-18 13:04:47 +0200778 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
779 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200780 uint16_t bvci = msgb_bvci(msg);
781 uint16_t nsei = msgb_nsei(msg);
782
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200783 size_t len = msgb_length(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200784
Jacob Erlbeck45017722013-10-18 13:04:47 +0200785 if (!real_gprs_ns_sendmsg)
786 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
787
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200788 if (nsei == SGSN_NSEI)
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200789 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
790 "msg length %d (%s)\n",
791 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200792 else
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200793 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
794 "msg length %d (%s)\n",
795 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200796
Jacob Erlbeck45017722013-10-18 13:04:47 +0200797 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200798}
799
800static void dump_rate_ctr_group(FILE *stream, const char *prefix,
801 struct rate_ctr_group *ctrg)
802{
803 unsigned int i;
804
805 for (i = 0; i < ctrg->desc->num_ctr; i++) {
806 struct rate_ctr *ctr = &ctrg->ctr[i];
807 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
808 fprintf(stream, " %s%s: %llu%s",
809 prefix, ctrg->desc->ctr_desc[i].description,
810 (long long)ctr->current,
811 "\n");
812 };
813}
814
815/* Signal handler for signals from NS layer */
816static int test_signal(unsigned int subsys, unsigned int signal,
817 void *handler_data, void *signal_data)
818{
819 struct ns_signal_data *nssd = signal_data;
820 int rc;
821
822 if (subsys != SS_L_NS)
823 return 0;
824
825 switch (signal) {
826 case S_NS_RESET:
827 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
828 nssd->nsvc->nsvci,
829 gprs_ns_ll_str(nssd->nsvc));
830 break;
831
832 case S_NS_ALIVE_EXP:
833 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
834 nssd->nsvc->nsvci,
835 gprs_ns_ll_str(nssd->nsvc));
836 break;
837
838 case S_NS_BLOCK:
839 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
840 nssd->nsvc->nsvci,
841 gprs_ns_ll_str(nssd->nsvc));
842 break;
843
844 case S_NS_UNBLOCK:
845 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
846 nssd->nsvc->nsvci,
847 gprs_ns_ll_str(nssd->nsvc));
848 break;
849
850 case S_NS_REPLACED:
851 printf("==> got signal NS_REPLACED: 0x%04x/%s",
852 nssd->nsvc->nsvci,
853 gprs_ns_ll_str(nssd->nsvc));
854 printf(" -> 0x%04x/%s\n",
855 nssd->old_nsvc->nsvci,
856 gprs_ns_ll_str(nssd->old_nsvc));
857 break;
858
859 default:
860 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
861 nssd->nsvc->nsvci,
862 gprs_ns_ll_str(nssd->nsvc));
863 break;
864 }
865 printf("\n");
866 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
867 return rc;
868}
869
870static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
871{
872 struct msgb *msg;
873 int ret;
874 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
875 fprintf(stderr, "message too long: %d\n", data_len);
876 return -1;
877 }
878
879 msg = gprs_ns_msgb_alloc();
880 memmove(msg->data, data, data_len);
881 msg->l2h = msg->data;
882 msgb_put(msg, data_len);
883
884 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
885 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
886 osmo_hexdump(data, data_len));
887
888 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
889
890 printf("result (%s) = %d\n\n", text, ret);
891
892 msgb_free(msg);
893
894 return ret;
895}
896
897static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
898{
899 struct gprs_nsvc *nsvc;
900
901 printf("Current NS-VCIs:\n");
902 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
903 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200904 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200905 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck45017722013-10-18 13:04:47 +0200906 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
907 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
908 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200909 );
910 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
911 }
912 printf("\n");
913}
914
915static void test_gbproxy()
916{
917 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
918 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck45017722013-10-18 13:04:47 +0200919 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200920
921 bssgp_nsi = nsi;
922 gbcfg.nsi = bssgp_nsi;
923 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
924
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200925 configure_sgsn_peer(&sgsn_peer);
926 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200927
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200928 printf("=== %s ===\n", __func__);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200929 printf("--- Initialise SGSN ---\n\n");
930
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200931 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200932 gprs_dump_nsi(nsi);
933
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200934 printf("--- Initialise BSS 1 ---\n\n");
935
936 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
937 setup_bssgp(nsi, &bss_peer[0], 0x1002);
938 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200939 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200940
Jacob Erlbeck45017722013-10-18 13:04:47 +0200941 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
942
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200943 printf("--- Initialise BSS 2 ---\n\n");
944
945 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
946 setup_bssgp(nsi, &bss_peer[1], 0x2002);
947 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200948 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200949
Jacob Erlbeck45017722013-10-18 13:04:47 +0200950 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
951
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200952 printf("--- Move BSS 1 to new port ---\n\n");
953
954 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
955 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200956 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200957
958 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
959
960 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
961 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200962 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200963
964 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
965
966 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
967 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200968 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200969
970 printf("--- Move BSS 2 to new port ---\n\n");
971
972 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
973 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200974 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200975
976 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
977
978 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
979 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200980 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200981
Jacob Erlbeck45017722013-10-18 13:04:47 +0200982 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
983
984 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
985 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200986 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200987
988 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
989
990 setup_bssgp(nsi, &bss_peer[0], 0x1012);
991 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200992 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200993
994 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
995
996 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
997
998 setup_bssgp(nsi, &bss_peer[0], 0x1002);
999 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001000 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001001
1002 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1003
1004 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1005
1006 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1007 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001008 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001009
1010 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1011
1012 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\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 0x1012 ---\n\n");
1017
1018 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1019
1020 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1021
1022 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1023
1024 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1025
1026 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1027
1028 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1029
1030 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1031
1032 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1033
1034 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1035
1036 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1037
1038 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1039 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001040 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001041
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001042 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001043
Jacob Erlbeck45017722013-10-18 13:04:47 +02001044 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1045
1046 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1047
1048 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1049
1050 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1051
1052 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1053
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001054 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1055
1056 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1057
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001058 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001059
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001060 gbprox_reset(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001061 gprs_ns_destroy(nsi);
1062 nsi = NULL;
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001063}
1064
1065static void test_gbproxy_ident_changes()
1066{
1067 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1068 struct sockaddr_in bss_peer[1] = {{0},};
1069 struct sockaddr_in sgsn_peer= {0};
1070 uint16_t nsei[2] = {0x1000, 0x2000};
1071 uint16_t nsvci[2] = {0x1001, 0x2001};
1072 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1073
1074 bssgp_nsi = nsi;
1075 gbcfg.nsi = bssgp_nsi;
1076 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1077
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001078 configure_sgsn_peer(&sgsn_peer);
1079 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001080
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001081 printf("=== %s ===\n", __func__);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001082 printf("--- Initialise SGSN ---\n\n");
1083
Jacob Erlbeck738b1c82014-07-07 10:46:00 +02001084 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001085 gprs_dump_nsi(nsi);
1086
1087 printf("--- Initialise BSS 1 ---\n\n");
1088
1089 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1090 gprs_dump_nsi(nsi);
1091
1092 printf("--- Setup BVCI 1 ---\n\n");
1093
1094 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1095 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001096 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001097
1098 printf("--- Setup BVCI 2 ---\n\n");
1099
1100 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1101 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001102 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001103
1104 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1105
1106 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1107 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1108
1109 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1110
1111 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1112 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1113
1114 printf("--- Change NSEI ---\n\n");
1115
1116 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1117 gprs_dump_nsi(nsi);
1118
1119 printf("--- Setup BVCI 1 ---\n\n");
1120
1121 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1122 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001123 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001124
1125 printf("--- Setup BVCI 3 ---\n\n");
1126
1127 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1128 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001129 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001130
1131 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1132
1133 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1134 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1135
1136 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1137 " (should fail) ---\n\n");
1138
1139 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001140 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001141 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001142 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001143
1144 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1145
1146 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1147 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1148
1149 printf("--- Change NSVCI ---\n\n");
1150
1151 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1152 gprs_dump_nsi(nsi);
1153
1154 printf("--- Setup BVCI 1 ---\n\n");
1155
1156 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1157 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001158 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001159
1160 printf("--- Setup BVCI 4 ---\n\n");
1161
1162 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1163 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001164 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001165
1166 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1167
1168 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1169 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1170
1171 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1172 " (should fail) ---\n\n");
1173
1174 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001175 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001176 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001177 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001178
1179 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1180
1181 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1182 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1183
1184 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1185
1186 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1187 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1188
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001189 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001190 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001191
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001192 gbprox_reset(&gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001193 gprs_ns_destroy(nsi);
1194 nsi = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001195}
1196
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001197static void test_gbproxy_ra_patching()
1198{
1199 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1200 struct sockaddr_in bss_peer[1] = {{0},};
1201 struct sockaddr_in sgsn_peer= {0};
1202 struct gprs_ra_id rai_bss =
1203 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1204 struct gprs_ra_id rai_sgsn =
1205 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1206 struct gprs_ra_id rai_unknown =
1207 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001208 uint16_t cell_id = 0x7530;
Jacob Erlbeck43037632014-06-06 18:49:23 +02001209 const char *err_msg = NULL;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001210 const uint32_t ptmsi = 0xefe2b700;
1211 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001212 const uint32_t foreign_tlli = 0xbbc54679;
1213 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck31132872014-08-11 17:26:21 +02001214 struct gbproxy_tlli_info *tlli_info;
1215 struct gbproxy_peer *peer;
1216
1217 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001218
1219 bssgp_nsi = nsi;
1220 gbcfg.nsi = bssgp_nsi;
1221 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck2504bc42014-05-19 10:14:58 +02001222 gbcfg.core_mcc = 123;
1223 gbcfg.core_mnc = 456;
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001224 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freyther2d10ad12014-08-04 14:22:13 +02001225 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001226 gbcfg.patch_ptmsi = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001227
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001228 configure_sgsn_peer(&sgsn_peer);
1229 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001230
Jacob Erlbeck43037632014-06-06 18:49:23 +02001231 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001232 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck43037632014-06-06 18:49:23 +02001233 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1234 gbcfg.match_re, err_msg);
1235 exit(1);
1236 }
1237
1238
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001239 printf("=== %s ===\n", __func__);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001240 printf("--- Initialise SGSN ---\n\n");
1241
1242 connect_sgsn(nsi, &sgsn_peer);
1243 gprs_dump_nsi(nsi);
1244
1245 printf("--- Initialise BSS 1 ---\n\n");
1246
1247 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1248 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1249 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001250 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001251
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001252 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001253 OSMO_ASSERT(peer != NULL);
1254
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001255 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1256
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001257 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1258 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001259
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001260 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001261 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001262
1263 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1264
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001265 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1266 foreign_tlli, &rai_bss, cell_id,
1267 GPRS_SAPI_GMM, 0,
1268 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001269
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001270 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1271 foreign_tlli, 0, NULL, 0,
1272 GPRS_SAPI_GMM, 0,
1273 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001274
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001275 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1276 foreign_tlli, &rai_bss, cell_id,
1277 GPRS_SAPI_GMM, 3,
1278 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001279
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001280 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1281 foreign_tlli, 1, imsi, sizeof(imsi),
1282 GPRS_SAPI_GMM, 1,
1283 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001284
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001285 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001286 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001287 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1288 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1289 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1290 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1291 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1292 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1293 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1294 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001295
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001296 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1297 local_tlli, &rai_bss, cell_id,
1298 GPRS_SAPI_GMM, 4,
1299 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck31132872014-08-11 17:26:21 +02001300
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001301 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001302 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001303 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1304 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1305 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1306 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1307 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1308 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1309 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1310 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001311
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001312 /* Replace APN (1) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001313 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1314 local_tlli, &rai_bss, cell_id,
1315 GPRS_SAPI_GMM, 3,
1316 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001317
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001318 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001319 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001320 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1321 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1322 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1323 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1324 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1325 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1326 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1327 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001328
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001329 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1330 local_tlli, 1, imsi, sizeof(imsi),
1331 GPRS_SAPI_GMM, 2,
1332 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeckab7366f2014-06-06 18:47:36 +02001333
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001334 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001335 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001336 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1337 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1338 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1339 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001340
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001341 /* Replace APN (2) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001342 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1343 local_tlli, &rai_bss, cell_id,
1344 GPRS_SAPI_GMM, 3,
1345 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001346
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001347 gbcfg.core_apn[0] = 0;
1348 gbcfg.core_apn_size = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001349
1350 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001351 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1352 local_tlli, &rai_bss, cell_id,
1353 GPRS_SAPI_GMM, 3,
1354 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001355
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001356 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001357
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001358 /* Detach */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001359 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1360 local_tlli, &rai_bss, cell_id,
1361 GPRS_SAPI_GMM, 6,
1362 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001363
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001364 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1365 local_tlli, 1, imsi, sizeof(imsi),
1366 GPRS_SAPI_GMM, 5,
1367 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001368
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001369 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001370
1371 printf("--- RA update ---\n\n");
1372
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001373 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1374 foreign_tlli, &rai_bss, 0x7080,
1375 GPRS_SAPI_GMM, 5,
1376 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001377
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001378 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1379 foreign_tlli, 1, imsi, sizeof(imsi),
1380 GPRS_SAPI_GMM, 6,
1381 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001382
1383 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001384 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1385 local_tlli, &rai_bss, cell_id,
1386 GPRS_SAPI_GMM, 3,
1387 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001388
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001389 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001390
Jacob Erlbeckf95340d2014-08-11 15:07:37 +02001391 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001392 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1393 local_tlli, &rai_bss, cell_id,
1394 GPRS_SAPI_GMM, 6,
1395 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001396
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001397 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001398 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001399
1400 printf("--- Bad cases ---\n\n");
1401
Jacob Erlbeck43037632014-06-06 18:49:23 +02001402 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001403 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1404 local_tlli, &rai_bss, cell_id,
1405 GPRS_SAPI_GMM, 3,
1406 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001407
Jacob Erlbeck90a1fd12014-05-27 13:49:04 +02001408 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001409 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001410
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001411 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001412 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001413
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001414 gbprox_reset(&gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001415 gprs_ns_destroy(nsi);
1416 nsi = NULL;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001417}
1418
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001419static void test_gbproxy_ptmsi_patching()
1420{
1421 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1422 struct sockaddr_in bss_peer[1] = {{0},};
1423 struct sockaddr_in sgsn_peer= {0};
1424 struct gprs_ra_id rai_bss =
1425 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1426 struct gprs_ra_id rai_sgsn =
1427 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001428 struct gprs_ra_id rai_wrong_mcc_sgsn =
1429 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001430 struct gprs_ra_id rai_unknown =
1431 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1432 uint16_t cell_id = 0x1234;
1433
1434 const uint32_t sgsn_ptmsi = 0xefe2b700;
1435 const uint32_t local_sgsn_tlli = 0xefe2b700;
1436 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1437
1438 const uint32_t bss_ptmsi = 0xc00f7304;
1439 const uint32_t local_bss_tlli = 0xc00f7304;
1440 const uint32_t foreign_bss_tlli = 0x8000dead;
1441
1442 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1443 struct gbproxy_tlli_info *tlli_info;
1444 struct gbproxy_peer *peer;
1445 unsigned bss_nu = 0;
1446 unsigned sgsn_nu = 0;
1447
1448 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1449
1450 bssgp_nsi = nsi;
1451 gbcfg.nsi = bssgp_nsi;
1452 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1453 gbcfg.core_mcc = 123;
1454 gbcfg.core_mnc = 456;
1455 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1456 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1457 gbcfg.patch_ptmsi = 1;
1458 gbcfg.bss_ptmsi_state = 0;
1459 gbcfg.sgsn_tlli_state = 1;
1460
1461 configure_sgsn_peer(&sgsn_peer);
1462 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1463
1464 printf("=== %s ===\n", __func__);
1465 printf("--- Initialise SGSN ---\n\n");
1466
1467 connect_sgsn(nsi, &sgsn_peer);
1468
1469 printf("--- Initialise BSS 1 ---\n\n");
1470
1471 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1472 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1473
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001474 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001475 OSMO_ASSERT(peer != NULL);
1476
1477 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1478
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001479 gprs_dump_nsi(nsi);
1480 dump_global(stdout, 0);
1481 dump_peers(stdout, 0, 0, &gbcfg);
1482
1483 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1484
1485 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1486 foreign_bss_tlli, &rai_unknown, cell_id,
1487 GPRS_SAPI_GMM, bss_nu++,
1488 dtap_attach_req, sizeof(dtap_attach_req));
1489
1490 dump_peers(stdout, 0, 0, &gbcfg);
1491
1492 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1493 random_sgsn_tlli, 0, NULL, 0,
1494 GPRS_SAPI_GMM, sgsn_nu++,
1495 dtap_identity_req, sizeof(dtap_identity_req));
1496
1497 dump_peers(stdout, 0, 0, &gbcfg);
1498
1499 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1500 foreign_bss_tlli, &rai_bss, cell_id,
1501 GPRS_SAPI_GMM, bss_nu++,
1502 dtap_identity_resp, sizeof(dtap_identity_resp));
1503
1504 dump_peers(stdout, 0, 0, &gbcfg);
1505
1506 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1507 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1508 GPRS_SAPI_GMM, sgsn_nu++,
1509 dtap_attach_acc, sizeof(dtap_attach_acc));
1510
1511 dump_peers(stdout, 0, 0, &gbcfg);
1512
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001513 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001514 OSMO_ASSERT(tlli_info);
1515 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1516 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1517 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1518 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1519 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1520 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1521 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1522 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1523 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1524 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1525
1526 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1527 local_bss_tlli, &rai_bss, cell_id,
1528 GPRS_SAPI_GMM, bss_nu++,
1529 dtap_attach_complete, sizeof(dtap_attach_complete));
1530
1531 dump_peers(stdout, 0, 0, &gbcfg);
1532
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001533 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001534 OSMO_ASSERT(tlli_info);
1535 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1536 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1537 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1538 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1539 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1540 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1541 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1542 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1543
1544 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1545 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1546 GPRS_SAPI_GMM, sgsn_nu++,
1547 dtap_gmm_information, sizeof(dtap_gmm_information));
1548
1549 dump_peers(stdout, 0, 0, &gbcfg);
1550
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001551 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001552 OSMO_ASSERT(tlli_info);
1553 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1554 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1555 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1556 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1557
1558 /* Non-DTAP */
1559 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1560 local_bss_tlli, &rai_bss, cell_id,
1561 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1562
1563 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1564 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1565 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1566
1567 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1568 local_bss_tlli, &rai_bss, cell_id,
1569 llc_ui_ll11_dns_query_ul,
1570 sizeof(llc_ui_ll11_dns_query_ul));
1571
1572 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1573 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1574 llc_ui_ll11_dns_resp_dl,
1575 sizeof(llc_ui_ll11_dns_resp_dl));
1576
1577 dump_peers(stdout, 0, 0, &gbcfg);
1578
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001579 /* Other messages */
1580 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1581 local_bss_tlli, 1, 12);
1582
1583 dump_peers(stdout, 0, 0, &gbcfg);
1584
1585 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1586
1587 dump_peers(stdout, 0, 0, &gbcfg);
1588
1589 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1590
1591 dump_peers(stdout, 0, 0, &gbcfg);
1592
1593 /* Bad case: Invalid BVCI */
1594 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1595 local_bss_tlli, 1, 12);
1596 dump_global(stdout, 0);
1597
1598 /* Bad case: Invalid RAI */
1599 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1600
1601 dump_global(stdout, 0);
1602
1603 /* Bad case: Invalid MCC (LAC ok) */
1604 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1605 &rai_wrong_mcc_sgsn);
1606
1607 dump_global(stdout, 0);
1608
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001609 /* Detach */
1610 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1611 local_bss_tlli, &rai_bss, cell_id,
1612 GPRS_SAPI_GMM, bss_nu++,
1613 dtap_detach_req, sizeof(dtap_detach_req));
1614
1615 dump_peers(stdout, 0, 0, &gbcfg);
1616
1617 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1618 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1619 GPRS_SAPI_GMM, sgsn_nu++,
1620 dtap_detach_acc, sizeof(dtap_detach_acc));
1621
1622 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001623
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001624 dump_global(stdout, 0);
1625
1626 gbprox_reset(&gbcfg);
1627 gprs_ns_destroy(nsi);
1628 nsi = NULL;
1629}
1630
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001631static void test_gbproxy_imsi_acquisition()
1632{
1633 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1634 struct sockaddr_in bss_peer[1] = {{0},};
1635 struct sockaddr_in sgsn_peer= {0};
1636 struct gprs_ra_id rai_bss =
1637 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1638 struct gprs_ra_id rai_sgsn =
1639 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1640 struct gprs_ra_id rai_wrong_mcc_sgsn =
1641 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1642 struct gprs_ra_id rai_unknown =
1643 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1644 uint16_t cell_id = 0x1234;
1645
1646 const uint32_t sgsn_ptmsi = 0xefe2b700;
1647 const uint32_t local_sgsn_tlli = 0xefe2b700;
1648 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1649
1650 const uint32_t bss_ptmsi = 0xc00f7304;
1651 const uint32_t local_bss_tlli = 0xc00f7304;
1652 const uint32_t foreign_bss_tlli = 0x8000dead;
1653
1654 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1655 struct gbproxy_tlli_info *tlli_info;
1656 struct gbproxy_peer *peer;
1657 unsigned bss_nu = 0;
1658 unsigned sgsn_nu = 0;
1659
1660 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1661
1662 bssgp_nsi = nsi;
1663 gbcfg.nsi = bssgp_nsi;
1664 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1665 gbcfg.core_mcc = 123;
1666 gbcfg.core_mnc = 456;
1667 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1668 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1669 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02001670 gbcfg.acquire_imsi = 1;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001671 gbcfg.bss_ptmsi_state = 0;
1672 gbcfg.sgsn_tlli_state = 1;
1673
1674 configure_sgsn_peer(&sgsn_peer);
1675 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1676
1677 printf("=== %s ===\n", __func__);
1678 printf("--- Initialise SGSN ---\n\n");
1679
1680 connect_sgsn(nsi, &sgsn_peer);
1681
1682 printf("--- Initialise BSS 1 ---\n\n");
1683
1684 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1685 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1686
1687 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1688 OSMO_ASSERT(peer != NULL);
1689
1690 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1691
1692 gprs_dump_nsi(nsi);
1693 dump_global(stdout, 0);
1694 dump_peers(stdout, 0, 0, &gbcfg);
1695
1696 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1697
1698 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1699 foreign_bss_tlli, &rai_unknown, cell_id,
1700 GPRS_SAPI_GMM, bss_nu++,
1701 dtap_attach_req, sizeof(dtap_attach_req));
1702
1703 dump_peers(stdout, 0, 0, &gbcfg);
1704
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02001705 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1706 foreign_bss_tlli, &rai_bss, cell_id,
1707 GPRS_SAPI_GMM, bss_nu++,
1708 dtap_identity_resp, sizeof(dtap_identity_resp));
1709
1710 dump_peers(stdout, 0, 0, &gbcfg);
1711
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001712 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1713 random_sgsn_tlli, 0, NULL, 0,
1714 GPRS_SAPI_GMM, sgsn_nu++,
1715 dtap_identity_req, sizeof(dtap_identity_req));
1716
1717 dump_peers(stdout, 0, 0, &gbcfg);
1718
1719 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1720 foreign_bss_tlli, &rai_bss, cell_id,
1721 GPRS_SAPI_GMM, bss_nu++,
1722 dtap_identity_resp, sizeof(dtap_identity_resp));
1723
1724 dump_peers(stdout, 0, 0, &gbcfg);
1725
1726 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1727 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1728 GPRS_SAPI_GMM, sgsn_nu++,
1729 dtap_attach_acc, sizeof(dtap_attach_acc));
1730
1731 dump_peers(stdout, 0, 0, &gbcfg);
1732
1733 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1734 OSMO_ASSERT(tlli_info);
1735 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1736 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1737 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1738 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1739 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1740 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1741 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1742 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1743 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1744 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1745
1746 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1747 local_bss_tlli, &rai_bss, cell_id,
1748 GPRS_SAPI_GMM, bss_nu++,
1749 dtap_attach_complete, sizeof(dtap_attach_complete));
1750
1751 dump_peers(stdout, 0, 0, &gbcfg);
1752
1753 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1754 OSMO_ASSERT(tlli_info);
1755 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1756 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1757 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1758 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1759 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1760 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1761 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1762 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1763
1764 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1765 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1766 GPRS_SAPI_GMM, sgsn_nu++,
1767 dtap_gmm_information, sizeof(dtap_gmm_information));
1768
1769 dump_peers(stdout, 0, 0, &gbcfg);
1770
1771 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1772 OSMO_ASSERT(tlli_info);
1773 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1774 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1775 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1776 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1777
1778 /* Non-DTAP */
1779 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1780 local_bss_tlli, &rai_bss, cell_id,
1781 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1782
1783 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1784 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1785 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1786
1787 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1788 local_bss_tlli, &rai_bss, cell_id,
1789 llc_ui_ll11_dns_query_ul,
1790 sizeof(llc_ui_ll11_dns_query_ul));
1791
1792 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1793 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1794 llc_ui_ll11_dns_resp_dl,
1795 sizeof(llc_ui_ll11_dns_resp_dl));
1796
1797 dump_peers(stdout, 0, 0, &gbcfg);
1798
1799 /* Other messages */
1800 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1801 local_bss_tlli, 1, 12);
1802
1803 dump_peers(stdout, 0, 0, &gbcfg);
1804
1805 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
1806 local_sgsn_tlli, 1, 12);
1807
1808 dump_peers(stdout, 0, 0, &gbcfg);
1809
1810 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
1811
1812 dump_peers(stdout, 0, 0, &gbcfg);
1813
1814 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
1815
1816 dump_peers(stdout, 0, 0, &gbcfg);
1817
1818 /* Bad case: Invalid BVCI */
1819 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
1820 local_bss_tlli, 1, 12);
1821 dump_global(stdout, 0);
1822
1823 /* Bad case: Invalid RAI */
1824 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
1825
1826 dump_global(stdout, 0);
1827
1828 /* Bad case: Invalid MCC (LAC ok) */
1829 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
1830 &rai_wrong_mcc_sgsn);
1831
1832 dump_global(stdout, 0);
1833
1834 /* Detach */
1835 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1836 local_bss_tlli, &rai_bss, cell_id,
1837 GPRS_SAPI_GMM, bss_nu++,
1838 dtap_detach_req, sizeof(dtap_detach_req));
1839
1840 dump_peers(stdout, 0, 0, &gbcfg);
1841
1842 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1843 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1844 GPRS_SAPI_GMM, sgsn_nu++,
1845 dtap_detach_acc, sizeof(dtap_detach_acc));
1846
1847 dump_peers(stdout, 0, 0, &gbcfg);
1848
1849 dump_global(stdout, 0);
1850
1851 gbprox_reset(&gbcfg);
1852 gprs_ns_destroy(nsi);
1853 nsi = NULL;
1854}
1855
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001856/* TODO: Move tlv testing to libosmocore */
1857int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
1858int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
1859 uint8_t **value);
1860int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
1861 size_t *value_len);
1862int lv_shift(uint8_t **data, size_t *data_len,
1863 uint8_t **value, size_t *value_len);
1864
1865static void check_tlv_match(uint8_t **data, size_t *data_len,
1866 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
1867{
1868 uint8_t *value;
1869 size_t value_len;
1870 int rc;
1871
1872 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
1873 OSMO_ASSERT(rc == 0);
1874
1875 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001876 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001877 OSMO_ASSERT(value_len == exp_len);
1878 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1879}
1880
1881static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
1882 uint8_t tag, size_t len, const uint8_t *exp_val)
1883{
1884 uint8_t *value;
1885 int rc;
1886
1887 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
1888 OSMO_ASSERT(rc == 0);
1889
1890 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001891 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001892 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1893}
1894
1895static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
1896 size_t len, const uint8_t *exp_val)
1897{
1898 uint8_t *value;
1899 int rc;
1900
1901 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001902 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001903 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1904}
1905
1906static void check_lv_shift(uint8_t **data, size_t *data_len,
1907 size_t exp_len, const uint8_t *exp_val)
1908{
1909 uint8_t *value;
1910 size_t value_len;
1911 int rc;
1912
1913 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001914 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001915 OSMO_ASSERT(value_len == exp_len);
1916 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1917}
1918
1919static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
1920 const uint8_t *test_data)
1921{
1922 uint8_t buf[300] = {0};
1923
1924 uint8_t *unchanged_ptr = buf - 1;
1925 size_t unchanged_len = 0xdead;
1926 size_t tmp_data_len = data_len;
1927 uint8_t *value = unchanged_ptr;
1928 size_t value_len = unchanged_len;
1929 uint8_t *data = buf;
1930
1931 OSMO_ASSERT(data_len <= sizeof(buf));
1932
1933 tlv_put(data, tag, len, test_data);
1934 if (data_len < len + 2) {
1935 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
1936 tag, &value, &value_len));
1937 OSMO_ASSERT(tmp_data_len == 0);
1938 OSMO_ASSERT(data == buf + data_len);
1939 OSMO_ASSERT(value == unchanged_ptr);
1940 OSMO_ASSERT(value_len == unchanged_len);
1941 } else {
1942 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
1943 tag, &value, &value_len));
1944 OSMO_ASSERT(value != unchanged_ptr);
1945 OSMO_ASSERT(value_len != unchanged_len);
1946 }
1947}
1948
1949static void check_tv_fixed_match_data_len(size_t data_len,
1950 uint8_t tag, size_t len,
1951 const uint8_t *test_data)
1952{
1953 uint8_t buf[300] = {0};
1954
1955 uint8_t *unchanged_ptr = buf - 1;
1956 size_t tmp_data_len = data_len;
1957 uint8_t *value = unchanged_ptr;
1958 uint8_t *data = buf;
1959
1960 OSMO_ASSERT(data_len <= sizeof(buf));
1961
1962 tv_fixed_put(data, tag, len, test_data);
1963
1964 if (data_len < len + 1) {
1965 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
1966 tag, len, &value));
1967 OSMO_ASSERT(tmp_data_len == 0);
1968 OSMO_ASSERT(data == buf + data_len);
1969 OSMO_ASSERT(value == unchanged_ptr);
1970 } else {
1971 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
1972 tag, len, &value));
1973 OSMO_ASSERT(value != unchanged_ptr);
1974 }
1975}
1976
1977static void check_v_fixed_shift_data_len(size_t data_len,
1978 size_t len, const uint8_t *test_data)
1979{
1980 uint8_t buf[300] = {0};
1981
1982 uint8_t *unchanged_ptr = buf - 1;
1983 size_t tmp_data_len = data_len;
1984 uint8_t *value = unchanged_ptr;
1985 uint8_t *data = buf;
1986
1987 OSMO_ASSERT(data_len <= sizeof(buf));
1988
1989 memcpy(data, test_data, len);
1990
1991 if (data_len < len) {
1992 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
1993 len, &value));
1994 OSMO_ASSERT(tmp_data_len == 0);
1995 OSMO_ASSERT(data == buf + data_len);
1996 OSMO_ASSERT(value == unchanged_ptr);
1997 } else {
1998 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
1999 len, &value));
2000 OSMO_ASSERT(value != unchanged_ptr);
2001 }
2002}
2003
2004static void check_lv_shift_data_len(size_t data_len,
2005 size_t len, const uint8_t *test_data)
2006{
2007 uint8_t buf[300] = {0};
2008
2009 uint8_t *unchanged_ptr = buf - 1;
2010 size_t unchanged_len = 0xdead;
2011 size_t tmp_data_len = data_len;
2012 uint8_t *value = unchanged_ptr;
2013 size_t value_len = unchanged_len;
2014 uint8_t *data = buf;
2015
2016 lv_put(data, len, test_data);
2017 if (data_len < len + 1) {
2018 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2019 &value, &value_len));
2020 OSMO_ASSERT(tmp_data_len == 0);
2021 OSMO_ASSERT(data == buf + data_len);
2022 OSMO_ASSERT(value == unchanged_ptr);
2023 OSMO_ASSERT(value_len == unchanged_len);
2024 } else {
2025 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2026 &value, &value_len));
2027 OSMO_ASSERT(value != unchanged_ptr);
2028 OSMO_ASSERT(value_len != unchanged_len);
2029 }
2030}
2031
2032static void test_tlv_shift_functions()
2033{
2034 uint8_t test_data[1024];
2035 uint8_t buf[1024];
2036 uint8_t *data_end;
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002037 unsigned i, len;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002038 uint8_t *data;
2039 size_t data_len;
2040 const uint8_t tag = 0x1a;
2041
2042 printf("Test shift functions\n");
2043
2044 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2045 test_data[i] = (uint8_t)i;
2046
2047 for (len = 0; len < 256; len++) {
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002048 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002049
2050 memset(buf, 0xee, sizeof(buf));
2051 data_end = data = buf;
2052
2053 for (i = 0; i < iterations; i++) {
2054 data_end = tlv_put(data_end, tag, len, test_data);
2055 data_end = tv_fixed_put(data_end, tag, len, test_data);
2056 /* v_fixed_put */
2057 memcpy(data_end, test_data, len);
2058 data_end += len;
2059 data_end = lv_put(data_end, len, test_data);
2060 }
2061
2062 data_len = data_end - data;
2063 OSMO_ASSERT(data_len <= sizeof(buf));
2064
2065 for (i = 0; i < iterations; i++) {
2066 check_tlv_match(&data, &data_len, tag, len, test_data);
2067 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2068 check_v_fixed_shift(&data, &data_len, len, test_data);
2069 check_lv_shift(&data, &data_len, len, test_data);
2070 }
2071
2072 OSMO_ASSERT(data == data_end);
2073
2074 /* Test at end of data */
2075
2076 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2077 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2078 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2079 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2080
2081 /* Test invalid data_len */
2082 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2083 check_tlv_match_data_len(data_len, tag, len, test_data);
2084 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2085 check_v_fixed_shift_data_len(data_len, len, test_data);
2086 check_lv_shift_data_len(data_len, len, test_data);
2087 }
2088 }
2089}
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002090
2091static void test_gbproxy_tlli_expire(void)
2092{
2093 struct gbproxy_config cfg = {0};
2094 struct gbproxy_peer *peer;
2095 const char *err_msg = NULL;
2096 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2097 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002098 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002099 const uint32_t tlli1 = 1234 | 0xc0000000;
2100 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002101 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002102 const char *filter_re = ".*";
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002103 time_t now = 1407479214;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002104
2105 printf("Test TLLI info expiry\n\n");
2106
2107 gbproxy_init_config(&cfg);
2108
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002109 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002110 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2111 err_msg);
2112 OSMO_ASSERT(err_msg == NULL);
2113 }
2114
2115 {
2116 struct gbproxy_tlli_info *tlli_info;
2117
2118 printf("Test TLLI replacement:\n");
2119
2120 cfg.tlli_max_len = 0;
2121 cfg.tlli_max_age = 0;
2122 peer = gbproxy_peer_alloc(&cfg, 20);
2123 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2124
2125 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002126 tlli_info = gbproxy_register_tlli(peer, tlli1,
2127 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002128 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002129 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002130 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2131
2132 /* replace the old entry */
2133 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002134 tlli_info = gbproxy_register_tlli(peer, tlli2,
2135 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002136 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002137 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002138 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2139
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002140 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002141
2142 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002143 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002144 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002145 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002146 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002147 OSMO_ASSERT(!tlli_info);
2148
2149 printf("\n");
2150
2151 gbproxy_peer_free(peer);
2152 }
2153
2154 {
2155 struct gbproxy_tlli_info *tlli_info;
2156
2157 printf("Test IMSI replacement:\n");
2158
2159 cfg.tlli_max_len = 0;
2160 cfg.tlli_max_age = 0;
2161 peer = gbproxy_peer_alloc(&cfg, 20);
2162 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2163
2164 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002165 tlli_info = gbproxy_register_tlli(peer, tlli1,
2166 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002167 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002168 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002169 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2170
2171 /* try to replace the old entry */
2172 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002173 tlli_info = gbproxy_register_tlli(peer, tlli1,
2174 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002175 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002176 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002177 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2178
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002179 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002180
2181 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002182 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002183 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002184 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002185 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002186 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002187
2188 printf("\n");
2189
2190 gbproxy_peer_free(peer);
2191 }
2192
2193 {
2194 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002195 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002196
2197 printf("Test TLLI expiry, max_len == 1:\n");
2198
2199 cfg.tlli_max_len = 1;
2200 cfg.tlli_max_age = 0;
2201 peer = gbproxy_peer_alloc(&cfg, 20);
2202 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2203
2204 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002205 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002206 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2207
2208 /* replace the old entry */
2209 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002210 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002211 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2212
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002213 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002214 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002215 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2216
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002217 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002218
2219 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002220 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002221 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002222 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002223 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002224 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002225
2226 printf("\n");
2227
2228 gbproxy_peer_free(peer);
2229 }
2230
2231 {
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002232 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002233 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002234
2235 printf("Test TLLI expiry, max_age == 1:\n");
2236
2237 cfg.tlli_max_len = 0;
2238 cfg.tlli_max_age = 1;
2239 peer = gbproxy_peer_alloc(&cfg, 20);
2240 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2241
2242 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002243 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002244 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2245
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002246 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002247 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002248 now + 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002249 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2250
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002251 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002252 OSMO_ASSERT(num_removed == 1);
2253 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2254
2255 dump_peers(stdout, 2, now + 2, &cfg);
2256
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002257 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002258 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002259 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002260 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002261 OSMO_ASSERT(tlli_info);
2262 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2263
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002264 printf("\n");
2265
2266 gbproxy_peer_free(peer);
2267 }
2268
2269 {
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002270 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002271 int num_removed;
2272
2273 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2274
2275 cfg.tlli_max_len = 0;
2276 cfg.tlli_max_age = 1;
2277 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002278 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2279
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002280 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002281 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002282 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2283
2284 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002285 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002286 now + 1);
2287 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2288
2289 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002290 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2291 now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002292 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2293
2294 dump_peers(stdout, 2, now + 2, &cfg);
2295
2296 printf(" Remove stale TLLIs\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002297 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002298 OSMO_ASSERT(num_removed == 2);
2299 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2300
2301 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002302
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002303 /* verify that tlli3 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002304 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002305 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002306 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002307 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002308 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002309 OSMO_ASSERT(tlli_info);
2310 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2311
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002312 printf("\n");
2313
2314 gbproxy_peer_free(peer);
2315 }
2316}
2317
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002318static void test_gbproxy_imsi_matching(void)
2319{
2320 struct gbproxy_config cfg = {0};
2321 struct gbproxy_peer *peer;
2322 const char *err_msg = NULL;
2323 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2324 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2325 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2326 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2327 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2328 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2329 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2330 const char *filter_re1 = ".*";
2331 const char *filter_re2 = "^1234";
2332 const char *filter_re3 = "^4321";
2333 const char *filter_re4_bad = "^12[";
2334
2335 printf("=== Test IMSI/TMSI matching ===\n\n");
2336
2337 gbproxy_init_config(&cfg);
2338 OSMO_ASSERT(cfg.check_imsi == 0);
2339
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002340 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002341 OSMO_ASSERT(cfg.check_imsi == 1);
2342
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002343 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002344 OSMO_ASSERT(cfg.check_imsi == 1);
2345
2346 err_msg = NULL;
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002347 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002348 OSMO_ASSERT(err_msg != NULL);
2349 OSMO_ASSERT(cfg.check_imsi == 0);
2350
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002351 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002352 OSMO_ASSERT(cfg.check_imsi == 1);
2353
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002354 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002355 OSMO_ASSERT(cfg.check_imsi == 0);
2356
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002357 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02002358 OSMO_ASSERT(cfg.check_imsi == 1);
2359
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002360 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02002361 OSMO_ASSERT(cfg.check_imsi == 0);
2362
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002363 peer = gbproxy_peer_alloc(&cfg, 20);
2364
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002365 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002366 OSMO_ASSERT(cfg.check_imsi == 1);
2367
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002368 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2369 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002370 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002371 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002372 * case. */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002373 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2374 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2375 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2376 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2377 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002378
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002379 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002380 OSMO_ASSERT(cfg.check_imsi == 1);
2381
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002382 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2383 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2384 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2385 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2386 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2387 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2388 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002389
2390 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2391
2392 gbproxy_peer_free(peer);
2393}
2394
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02002395static struct log_info_cat gprs_categories[] = {
2396 [DGPRS] = {
2397 .name = "DGPRS",
2398 .description = "GPRS Packet Service",
2399 .enabled = 1, .loglevel = LOGL_DEBUG,
2400 },
2401 [DNS] = {
2402 .name = "DNS",
2403 .description = "GPRS Network Service (NS)",
2404 .enabled = 1, .loglevel = LOGL_INFO,
2405 },
2406 [DBSSGP] = {
2407 .name = "DBSSGP",
2408 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2409 .enabled = 1, .loglevel = LOGL_DEBUG,
2410 },
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02002411};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02002412
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02002413static struct log_info info = {
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02002414 .cat = gprs_categories,
2415 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02002416};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02002417
2418int main(int argc, char **argv)
2419{
2420 osmo_init_logging(&info);
2421 log_set_use_color(osmo_stderr_target, 0);
2422 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02002423 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02002424
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02002425 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02002426 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
2427 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02002428
2429 rate_ctr_init(NULL);
2430
2431 setlinebuf(stdout);
2432
2433 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther5eaf1a22014-08-04 11:10:09 +02002434 gbproxy_init_config(&gbcfg);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002435 test_tlv_shift_functions();
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02002436 test_gbproxy();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02002437 test_gbproxy_ident_changes();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002438 test_gbproxy_imsi_matching();
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02002439 test_gbproxy_ra_patching();
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002440 test_gbproxy_ptmsi_patching();
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002441 test_gbproxy_imsi_acquisition();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002442 test_gbproxy_tlli_expire();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02002443 printf("===== GbProxy test END\n\n");
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02002444
2445 exit(EXIT_SUCCESS);
2446}