blob: 6fd54857f4ce0196c4a64d1d3377c73b70c241ef [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 Erlbeck12356062014-08-27 12:44:25 +020043#define REMOTE_SGSN2_ADDR 0x15161718
44#define SGSN2_NSEI 0x0102
45
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020046struct gbproxy_config gbcfg = {0};
47
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020048static int dump_global(FILE *stream, int indent)
49{
50 unsigned int i;
51 const struct rate_ctr_group_desc *desc;
52 int rc;
53
54 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
55 if (rc < 0)
56 return rc;
57
58 desc = gbcfg.ctrg->desc;
59
60 for (i = 0; i < desc->num_ctr; i++) {
61 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
62 if (ctr->current) {
63 rc = fprintf(stream, "%*s %s: %llu\n",
64 indent, "",
65 desc->ctr_desc[i].description,
66 (long long)ctr->current);
67
68 if (rc < 0)
69 return rc;
70 }
71 }
72
73 return 0;
74}
75
Jacob Erlbeckc404c082014-08-08 08:37:37 +020076static int dump_peers(FILE *stream, int indent, time_t now,
77 struct gbproxy_config *cfg)
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020078{
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020079 struct gbproxy_peer *peer;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020080 struct gprs_ra_id raid;
81 unsigned int i;
82 const struct rate_ctr_group_desc *desc;
83 int rc;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020084
85 rc = fprintf(stream, "%*sPeers:\n", indent, "");
86 if (rc < 0)
87 return rc;
88
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +020089 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020090 struct gbproxy_tlli_info *tlli_info;
91 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020092 gsm48_parse_ra(&raid, peer->ra);
93
94 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
95 "RAI %u-%u-%u-%u\n",
96 indent, "",
97 peer->nsei, peer->bvci,
98 peer->blocked ? "" : "not ",
99 raid.mcc, raid.mnc, raid.lac, raid.rac);
100
101 if (rc < 0)
102 return rc;
103
104 desc = peer->ctrg->desc;
105
106 for (i = 0; i < desc->num_ctr; i++) {
107 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
108 if (ctr->current) {
109 rc = fprintf(stream, "%*s %s: %llu\n",
110 indent, "",
111 desc->ctr_desc[i].description,
112 (long long)ctr->current);
113
114 if (rc < 0)
115 return rc;
116 }
117 }
118
119 fprintf(stream, "%*s TLLI-Cache: %d\n",
120 indent, "", state->enabled_tllis_count);
121 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
122 char mi_buf[200];
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200123 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200124 int stored_msgs = 0;
125 struct llist_head *iter;
126 llist_for_each(iter, &tlli_info->stored_msgs)
127 stored_msgs++;
128
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200129 if (tlli_info->mi_data_len > 0) {
130 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
131 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
132 tlli_info->mi_data,
133 tlli_info->mi_data_len);
134 } else {
135 snprintf(mi_buf, sizeof(mi_buf), "(none)");
136 }
Jacob Erlbeck31132872014-08-11 17:26:21 +0200137 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200138 indent, "", tlli_info->tlli.current);
139 if (tlli_info->tlli.assigned)
140 fprintf(stream, "/%08x", tlli_info->tlli.assigned);
141 if (tlli_info->sgsn_tlli.current) {
142 fprintf(stream, " -> %08x",
143 tlli_info->sgsn_tlli.current);
144 if (tlli_info->sgsn_tlli.assigned)
145 fprintf(stream, "/%08x",
146 tlli_info->sgsn_tlli.assigned);
147 }
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200148 fprintf(stream, ", IMSI %s, AGE %d",
149 mi_buf, (int)age);
150
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200151 if (stored_msgs)
152 fprintf(stream, ", STORED %d", stored_msgs);
153
Jacob Erlbeck12356062014-08-27 12:44:25 +0200154 if (cfg->check_imsi && tlli_info->enable_patching)
155 fprintf(stream, ", IMSI matches");
156
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200157 if (tlli_info->imsi_acq_pending)
158 fprintf(stream, ", IMSI acquisition in progress");
159
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200160 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200161 if (rc < 0)
162 return rc;
163 }
164 }
165
166 return 0;
167}
168
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200169/* DTAP - Attach Request */
170static const unsigned char dtap_attach_req[] = {
171 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
172 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
173 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
174 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
175 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
176 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200177};
178
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200179/* DTAP - Identity Request */
180static const unsigned char dtap_identity_req[] = {
181 0x08, 0x15, 0x01
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200182};
183
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200184/* DTAP - Identity Response */
185static const unsigned char dtap_identity_resp[] = {
186 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
187 0x16, 0x17, 0x18
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200188};
189
Jacob Erlbeck12356062014-08-27 12:44:25 +0200190/* DTAP - Identity Response, IMSI 2 */
191static const unsigned char dtap_identity2_resp[] = {
192 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
193 0x16, 0x17, 0x18
194};
195
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200196/* DTAP - Attach Accept */
197static const unsigned char dtap_attach_acc[] = {
198 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
199 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
200 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200201};
202
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200203/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeck12356062014-08-27 12:44:25 +0200204static const unsigned char dtap_attach_acc2[] = {
205 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
206 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
207 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
208};
209
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200210/* DTAP - Attach Complete */
211static const unsigned char dtap_attach_complete[] = {
212 0x08, 0x03
Jacob Erlbeck31132872014-08-11 17:26:21 +0200213};
214
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200215/* DTAP - GMM Information */
216static const unsigned char dtap_gmm_information[] = {
217 0x08, 0x21
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200218};
219
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200220/* DTAP - Routing Area Update Request */
221static const unsigned char dtap_ra_upd_req[] = {
222 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
223 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
224 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
225 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
226 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
227 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
228 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200229};
230
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200231/* DTAP - Routing Area Update Accept */
232static const unsigned char dtap_ra_upd_acc[] = {
233 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
234 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
235 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200236};
237
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200238/* DTAP - Routing Area Update Accept, P-TMSI 2 */
239static const unsigned char dtap_ra_upd_acc2[] = {
240 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
241 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
242 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
243};
244
245/* DTAP - Routing Area Update Accept, P-TMSI 3 */
246static const unsigned char dtap_ra_upd_acc3[] = {
247 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
248 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
249 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
250};
251
252/* DTAP - Routing Area Update Complete */
253static const unsigned char dtap_ra_upd_complete[] = {
254 0x08, 0x0a
255};
256
257
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200258/* DTAP - Activate PDP Context Request */
259static const unsigned char dtap_act_pdp_ctx_req[] = {
260 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200261 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
263 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
264 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
265 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200266 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200267};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200268
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200269/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200270/* normal detach, power_off = 1 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200271static const unsigned char dtap_detach_po_req[] = {
272 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
273 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200274};
275
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200276/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200277/* normal detach, power_off = 0 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200278static const unsigned char dtap_detach_req[] = {
279 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
280 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200281};
282
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200283/* DTAP - Detach Accept */
284static const unsigned char dtap_detach_acc[] = {
285 0x08, 0x06, 0x00
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200286};
287
Jacob Erlbeck70e00de2014-08-15 17:20:06 +0200288/* GPRS-LLC - SAPI: LLGMM, U, XID */
289static const unsigned char llc_u_xid_ul[] = {
290 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
291 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
292};
293
294/* GPRS-LLC - SAPI: LLGMM, U, XID */
295static const unsigned char llc_u_xid_dl[] = {
296 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
297 0xe4, 0xa9, 0x1a, 0x9e
298};
299
300/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
301static const unsigned char llc_ui_ll11_dns_query_ul[] = {
302 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
303 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
304 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
305 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
306 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
307 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
308 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
309 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
310 0x8f, 0x07
311};
312
313/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
314static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
315 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
316 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
317 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
318 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
319 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
320 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
321 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
322 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
323 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
324 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
325 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
326 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
327 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
328 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
329 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
330 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
331 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
332 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
333 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
334 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
335 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
336 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
337 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
338 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
339 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
340 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
341};
342
Jacob Erlbeck45017722013-10-18 13:04:47 +0200343static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
344 struct sockaddr_in *peer, const unsigned char* data,
345 size_t data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200346
347static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
348 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
349{
350 /* GPRS Network Service, PDU type: NS_RESET,
351 */
352 unsigned char msg[12] = {
353 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
354 0x04, 0x82, 0x11, 0x22
355 };
356
357 msg[3] = cause;
358 msg[6] = nsvci / 256;
359 msg[7] = nsvci % 256;
360 msg[10] = nsei / 256;
361 msg[11] = nsei % 256;
362
363 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
364}
365
Jacob Erlbeck45017722013-10-18 13:04:47 +0200366static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
367 uint16_t nsvci, uint16_t nsei)
368{
369 /* GPRS Network Service, PDU type: NS_RESET_ACK,
370 */
371 unsigned char msg[9] = {
372 0x03, 0x01, 0x82, 0x11, 0x22,
373 0x04, 0x82, 0x11, 0x22
374 };
375
376 msg[3] = nsvci / 256;
377 msg[4] = nsvci % 256;
378 msg[7] = nsei / 256;
379 msg[8] = nsei % 256;
380
381 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
382}
383
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200384static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
385{
386 /* GPRS Network Service, PDU type: NS_ALIVE */
387 unsigned char msg[1] = {
388 0x0a
389 };
390
391 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
392}
393
394static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
395{
396 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
397 unsigned char msg[1] = {
398 0x0b
399 };
400
401 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
402}
403
404static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
405{
406 /* GPRS Network Service, PDU type: NS_UNBLOCK */
407 unsigned char msg[1] = {
408 0x06
409 };
410
411 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
412}
413
Jacob Erlbeck45017722013-10-18 13:04:47 +0200414static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
415{
416 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
417 unsigned char msg[1] = {
418 0x07
419 };
420
421 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
422}
423
424static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
425 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200426 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
427{
428 /* GPRS Network Service, PDU type: NS_UNITDATA */
429 unsigned char msg[4096] = {
430 0x00, 0x00, 0x00, 0x00
431 };
432
433 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
434
435 msg[2] = nsbvci / 256;
436 msg[3] = nsbvci % 256;
437 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
438
Jacob Erlbeck45017722013-10-18 13:04:47 +0200439 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200440}
441
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200442static void send_bssgp_ul_unitdata(
443 struct gprs_ns_inst *nsi, const char *text,
444 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
445 struct gprs_ra_id *raid, uint16_t cell_id,
446 const uint8_t *llc_msg, size_t llc_msg_size)
447{
448 /* GPRS Network Service, PDU type: NS_UNITDATA */
449 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
450 unsigned char msg[4096] = {
451 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
452 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
453 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
454 };
455
456 size_t bssgp_msg_size = 23 + llc_msg_size;
457
458 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
459
460 gsm48_construct_ra(msg + 10, raid);
461 msg[1] = (uint8_t)(tlli >> 24);
462 msg[2] = (uint8_t)(tlli >> 16);
463 msg[3] = (uint8_t)(tlli >> 8);
464 msg[4] = (uint8_t)(tlli >> 0);
465 msg[16] = cell_id / 256;
466 msg[17] = cell_id % 256;
467 msg[21] = llc_msg_size / 256;
468 msg[22] = llc_msg_size % 256;
469 memcpy(msg + 23, llc_msg, llc_msg_size);
470
471 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
472 src_addr, nsbvci, msg, bssgp_msg_size);
473}
474
475static void send_bssgp_dl_unitdata(
476 struct gprs_ns_inst *nsi, const char *text,
477 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
478 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
479 const uint8_t *llc_msg, size_t llc_msg_size)
480{
481 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
482 unsigned char msg[4096] = {
483 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
484 0x16, 0x82, 0x02, 0x58,
485 };
486 unsigned char racap_drx[] = {
487 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
488 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
489 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
490 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
491 };
492
493 size_t bssgp_msg_size = 0;
494
495 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
496
497 msg[1] = (uint8_t)(tlli >> 24);
498 msg[2] = (uint8_t)(tlli >> 16);
499 msg[3] = (uint8_t)(tlli >> 8);
500 msg[4] = (uint8_t)(tlli >> 0);
501
502 bssgp_msg_size = 12;
503
504 if (with_racap_drx) {
505 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
506 bssgp_msg_size += sizeof(racap_drx);
507 }
508
509 if (imsi) {
510 OSMO_ASSERT(imsi_size <= 127);
511 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
512 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
513 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
514 bssgp_msg_size += 2 + imsi_size;
515 }
516
517 if ((bssgp_msg_size % 4) != 0) {
518 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
519 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
520 msg[bssgp_msg_size + 1] = 0x80 | abytes;
521 memset(msg + bssgp_msg_size + 2, 0, abytes);
522 bssgp_msg_size += 2 + abytes;
523 }
524
525 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
526 if (llc_msg_size < 128) {
527 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
528 bssgp_msg_size += 2;
529 } else {
530 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
531 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
532 bssgp_msg_size += 3;
533 }
534 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
535 bssgp_msg_size += llc_msg_size;
536
537
538 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
539 src_addr, nsbvci, msg, bssgp_msg_size);
540}
541
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200542static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
543 uint16_t bvci)
544{
545 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
546 * BSSGP RESET */
Jacob Erlbeck8a600ae2014-08-06 12:38:10 +0200547 unsigned char msg[18] = {
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200548 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeck3f086322014-06-02 10:48:59 +0200549 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
550 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200551 };
552
553 msg[3] = bvci / 256;
554 msg[4] = bvci % 256;
555
Jacob Erlbeck45017722013-10-18 13:04:47 +0200556 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
557}
558
559static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
560 struct sockaddr_in *src_addr, uint16_t bvci)
561{
562 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
563 * BSSGP RESET_ACK */
564 static unsigned char msg[5] = {
565 0x23, 0x04, 0x82, 0x00,
566 0x00
567 };
568
569 msg[3] = bvci / 256;
570 msg[4] = bvci % 256;
571
572 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200573}
574
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200575static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
576 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200577 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200578 struct gprs_ra_id *raid)
579{
580 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
581 unsigned char msg[15] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200582 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
583 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200584 };
585
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200586 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
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200591 gsm48_construct_ra(msg + 9, raid);
592
593 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
594}
595
596static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
597 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200598 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200599 struct gprs_ra_id *raid)
600{
601 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
602 unsigned char msg[18] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200603 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
604 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200605 0x81, 0x01
606 };
607
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200608 msg[3] = (uint8_t)(tlli >> 24);
609 msg[4] = (uint8_t)(tlli >> 16);
610 msg[5] = (uint8_t)(tlli >> 8);
611 msg[6] = (uint8_t)(tlli >> 0);
612
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200613 gsm48_construct_ra(msg + 9, raid);
614
615 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
616}
617
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200618static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
619 struct sockaddr_in *src_addr,
620 uint16_t bvci, uint32_t tlli,
621 unsigned n_frames, unsigned n_octets)
622{
623 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
624 unsigned char msg[] = {
625 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
626 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
627 /* n octets */ 0xff, 0xff, 0xff
628 };
629
630 msg[3] = (uint8_t)(tlli >> 24);
631 msg[4] = (uint8_t)(tlli >> 16);
632 msg[5] = (uint8_t)(tlli >> 8);
633 msg[6] = (uint8_t)(tlli >> 0);
634 msg[9] = (uint8_t)(n_frames);
635 msg[12] = (uint8_t)(bvci >> 8);
636 msg[13] = (uint8_t)(bvci >> 0);
637 msg[16] = (uint8_t)(n_octets >> 16);
638 msg[17] = (uint8_t)(n_octets >> 8);
639 msg[18] = (uint8_t)(n_octets >> 0);
640
641 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
642}
643
Jacob Erlbeck12356062014-08-27 12:44:25 +0200644static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
645 struct sockaddr_in *src_addr,
646 uint16_t bvci, uint8_t tag)
647{
648 /* GPRS Network Service, PDU type: NS_UNITDATA,
649 * BSSGP FLOW_CONTROL_BVC */
650 unsigned char msg[] = {
651 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
652 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
653 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
654 };
655
656 msg[3] = tag;
657
658 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
659 msg, sizeof(msg));
660}
661
662static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
663 struct sockaddr_in *src_addr,
664 uint16_t bvci, uint8_t tag)
665{
666 /* GPRS Network Service, PDU type: NS_UNITDATA,
667 * BSSGP FLOW_CONTROL_BVC_ACK */
668 unsigned char msg[] = {
669 0x27, 0x1e, 0x81, /* Tag */ 0xce
670 };
671
672 msg[3] = tag;
673
674 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
675 msg, sizeof(msg));
676}
677
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200678static void send_llc_ul_ui(
679 struct gprs_ns_inst *nsi, const char *text,
680 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
681 struct gprs_ra_id *raid, uint16_t cell_id,
682 unsigned sapi, unsigned nu,
683 const uint8_t *msg, size_t msg_size)
684{
685 unsigned char llc_msg[4096] = {
686 0x00, 0xc0, 0x01
687 };
688
689 size_t llc_msg_size = 3 + msg_size + 3;
690 uint8_t e_bit = 0;
691 uint8_t pm_bit = 1;
692 unsigned fcs;
693
694 nu &= 0x01ff;
695
696 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
697
698 llc_msg[0] = (sapi & 0x0f);
699 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
700 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
701
702 memcpy(llc_msg + 3, msg, msg_size);
703
704 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
705 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
706 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
707 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
708
709 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
710 src_addr, nsbvci, tlli, raid, cell_id,
711 llc_msg, llc_msg_size);
712}
713
714static void send_llc_dl_ui(
715 struct gprs_ns_inst *nsi, const char *text,
716 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
717 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
718 unsigned sapi, unsigned nu,
719 const uint8_t *msg, size_t msg_size)
720{
721 /* GPRS Network Service, PDU type: NS_UNITDATA */
722 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
723 unsigned char llc_msg[4096] = {
724 0x00, 0x00, 0x01
725 };
726
727 size_t llc_msg_size = 3 + msg_size + 3;
728 uint8_t e_bit = 0;
729 uint8_t pm_bit = 1;
730 unsigned fcs;
731
732 nu &= 0x01ff;
733
734 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
735
736 llc_msg[0] = 0x40 | (sapi & 0x0f);
737 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
738 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
739
740 memcpy(llc_msg + 3, msg, msg_size);
741
742 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
743 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
744 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
745 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
746
747 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
748 src_addr, nsbvci, tlli,
749 with_racap_drx, imsi, imsi_size,
750 llc_msg, llc_msg_size);
751}
752
753
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200754static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
755 uint16_t nsvci, uint16_t nsei)
756{
757 printf("Setup NS-VC: remote 0x%08x:%d, "
758 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
759 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
760 nsvci, nsvci, nsei, nsei);
761
762 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
763 send_ns_alive(nsi, src_addr);
764 send_ns_unblock(nsi, src_addr);
765 send_ns_alive_ack(nsi, src_addr);
766}
767
768static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
769 uint16_t bvci)
770{
771 printf("Setup BSSGP: remote 0x%08x:%d, "
772 "BVCI 0x%04x(%d)\n\n",
773 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
774 bvci, bvci);
775
776 send_bssgp_reset(nsi, src_addr, bvci);
777}
778
Jacob Erlbeck12356062014-08-27 12:44:25 +0200779static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
780 uint32_t sgsn_nsei)
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200781{
Jacob Erlbeck12356062014-08-27 12:44:25 +0200782 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
783 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200784 send_ns_alive_ack(nsi, sgsn_peer);
785 send_ns_unblock_ack(nsi, sgsn_peer);
786 send_ns_alive(nsi, sgsn_peer);
787}
788
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200789static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
790{
791 sgsn_peer->sin_family = AF_INET;
792 sgsn_peer->sin_port = htons(32000);
793 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
794}
795
Jacob Erlbeck12356062014-08-27 12:44:25 +0200796static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
797{
798 sgsn_peer->sin_family = AF_INET;
799 sgsn_peer->sin_port = htons(32001);
800 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
801}
802
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200803static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
804{
805 size_t i;
806
807 for (i = 0; i < size; ++i) {
808 bss_peers[i].sin_family = AF_INET;
809 bss_peers[i].sin_port = htons((i + 1) * 1111);
810 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
811 }
812}
813
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200814int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
815 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
816
817/* override */
818int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
819 struct msgb *msg, uint16_t bvci)
820{
821 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
822 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200823 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200824
825 switch (event) {
826 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200827 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200828 default:
829 break;
830 }
831 return 0;
832}
833
834/* override */
835ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
836 const struct sockaddr *dest_addr, socklen_t addrlen)
837{
838 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
839 const struct sockaddr *, socklen_t);
840 static sendto_t real_sendto = NULL;
841 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200842 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200843
844 if (!real_sendto)
845 real_sendto = dlsym(RTLD_NEXT, "sendto");
846
847 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200848 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
849 dest_host, dest_port,
850 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200851 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200852 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
853 dest_host, dest_port,
854 len, osmo_hexdump(buf, len));
Jacob Erlbeck12356062014-08-27 12:44:25 +0200855 else if (dest_host == REMOTE_SGSN2_ADDR)
856 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
857 dest_host, dest_port,
858 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200859 else
860 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
861
862 return len;
863}
864
865/* override */
866int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
867{
Jacob Erlbeck45017722013-10-18 13:04:47 +0200868 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
869 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200870 uint16_t bvci = msgb_bvci(msg);
871 uint16_t nsei = msgb_nsei(msg);
872
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200873 size_t len = msgb_length(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200874
Jacob Erlbeck45017722013-10-18 13:04:47 +0200875 if (!real_gprs_ns_sendmsg)
876 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
877
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200878 if (nsei == SGSN_NSEI)
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200879 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
880 "msg length %d (%s)\n",
881 bvci, len, __func__);
Jacob Erlbeck12356062014-08-27 12:44:25 +0200882 else if (nsei == SGSN2_NSEI)
883 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
884 "msg length %d (%s)\n",
885 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200886 else
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200887 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
888 "msg length %d (%s)\n",
889 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200890
Jacob Erlbeck45017722013-10-18 13:04:47 +0200891 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200892}
893
894static void dump_rate_ctr_group(FILE *stream, const char *prefix,
895 struct rate_ctr_group *ctrg)
896{
897 unsigned int i;
898
899 for (i = 0; i < ctrg->desc->num_ctr; i++) {
900 struct rate_ctr *ctr = &ctrg->ctr[i];
901 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
902 fprintf(stream, " %s%s: %llu%s",
903 prefix, ctrg->desc->ctr_desc[i].description,
904 (long long)ctr->current,
905 "\n");
906 };
907}
908
909/* Signal handler for signals from NS layer */
910static int test_signal(unsigned int subsys, unsigned int signal,
911 void *handler_data, void *signal_data)
912{
913 struct ns_signal_data *nssd = signal_data;
914 int rc;
915
916 if (subsys != SS_L_NS)
917 return 0;
918
919 switch (signal) {
920 case S_NS_RESET:
921 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
922 nssd->nsvc->nsvci,
923 gprs_ns_ll_str(nssd->nsvc));
924 break;
925
926 case S_NS_ALIVE_EXP:
927 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
928 nssd->nsvc->nsvci,
929 gprs_ns_ll_str(nssd->nsvc));
930 break;
931
932 case S_NS_BLOCK:
933 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
934 nssd->nsvc->nsvci,
935 gprs_ns_ll_str(nssd->nsvc));
936 break;
937
938 case S_NS_UNBLOCK:
939 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
940 nssd->nsvc->nsvci,
941 gprs_ns_ll_str(nssd->nsvc));
942 break;
943
944 case S_NS_REPLACED:
945 printf("==> got signal NS_REPLACED: 0x%04x/%s",
946 nssd->nsvc->nsvci,
947 gprs_ns_ll_str(nssd->nsvc));
948 printf(" -> 0x%04x/%s\n",
949 nssd->old_nsvc->nsvci,
950 gprs_ns_ll_str(nssd->old_nsvc));
951 break;
952
953 default:
954 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
955 nssd->nsvc->nsvci,
956 gprs_ns_ll_str(nssd->nsvc));
957 break;
958 }
959 printf("\n");
960 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
961 return rc;
962}
963
964static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
965{
966 struct msgb *msg;
967 int ret;
968 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
969 fprintf(stderr, "message too long: %d\n", data_len);
970 return -1;
971 }
972
973 msg = gprs_ns_msgb_alloc();
974 memmove(msg->data, data, data_len);
975 msg->l2h = msg->data;
976 msgb_put(msg, data_len);
977
978 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
979 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
980 osmo_hexdump(data, data_len));
981
982 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
983
984 printf("result (%s) = %d\n\n", text, ret);
985
986 msgb_free(msg);
987
988 return ret;
989}
990
991static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
992{
993 struct gprs_nsvc *nsvc;
994
995 printf("Current NS-VCIs:\n");
996 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
997 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200998 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200999 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck45017722013-10-18 13:04:47 +02001000 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1001 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1002 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001003 );
1004 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1005 }
1006 printf("\n");
1007}
1008
1009static void test_gbproxy()
1010{
1011 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1012 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck45017722013-10-18 13:04:47 +02001013 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001014
1015 bssgp_nsi = nsi;
1016 gbcfg.nsi = bssgp_nsi;
1017 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1018
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001019 configure_sgsn_peer(&sgsn_peer);
1020 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001021
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001022 printf("=== %s ===\n", __func__);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001023 printf("--- Initialise SGSN ---\n\n");
1024
Jacob Erlbeck12356062014-08-27 12:44:25 +02001025 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001026 gprs_dump_nsi(nsi);
1027
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001028 printf("--- Initialise BSS 1 ---\n\n");
1029
1030 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1031 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1032 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001033 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001034
Jacob Erlbeck45017722013-10-18 13:04:47 +02001035 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1036
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001037 printf("--- Initialise BSS 2 ---\n\n");
1038
1039 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1040 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1041 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001042 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001043
Jacob Erlbeck45017722013-10-18 13:04:47 +02001044 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1045
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001046 printf("--- Move BSS 1 to new port ---\n\n");
1047
1048 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1049 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001050 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001051
1052 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1053
1054 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1055 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001056 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001057
1058 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1059
1060 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1061 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001062 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001063
1064 printf("--- Move BSS 2 to new port ---\n\n");
1065
1066 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1067 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001068 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001069
1070 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1071
1072 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1073 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001074 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001075
Jacob Erlbeck45017722013-10-18 13:04:47 +02001076 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1077
1078 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1079 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001080 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001081
1082 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1083
1084 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1085 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001086 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001087
1088 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1089
1090 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1091
1092 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1093 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001094 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001095
1096 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1097
1098 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1099
1100 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1101 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001102 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001103
1104 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1105
1106 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1107
1108 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1109
1110 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1111
1112 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1113
1114 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1115
1116 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1117
1118 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1119
1120 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1121
1122 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1123
1124 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1125
1126 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1127
1128 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1129
1130 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1131
1132 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1133 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001134 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001135
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001136 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001137
Jacob Erlbeck45017722013-10-18 13:04:47 +02001138 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1139
1140 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1141
1142 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1143
1144 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1145
1146 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1147
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001148 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1149
1150 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1151
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001152 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001153
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001154 gbprox_reset(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001155 gprs_ns_destroy(nsi);
1156 nsi = NULL;
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001157}
1158
1159static void test_gbproxy_ident_changes()
1160{
1161 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1162 struct sockaddr_in bss_peer[1] = {{0},};
1163 struct sockaddr_in sgsn_peer= {0};
1164 uint16_t nsei[2] = {0x1000, 0x2000};
1165 uint16_t nsvci[2] = {0x1001, 0x2001};
1166 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1167
1168 bssgp_nsi = nsi;
1169 gbcfg.nsi = bssgp_nsi;
1170 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1171
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001172 configure_sgsn_peer(&sgsn_peer);
1173 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001174
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001175 printf("=== %s ===\n", __func__);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001176 printf("--- Initialise SGSN ---\n\n");
1177
Jacob Erlbeck12356062014-08-27 12:44:25 +02001178 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001179 gprs_dump_nsi(nsi);
1180
1181 printf("--- Initialise BSS 1 ---\n\n");
1182
1183 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1184 gprs_dump_nsi(nsi);
1185
1186 printf("--- Setup BVCI 1 ---\n\n");
1187
1188 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1189 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001190 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001191
1192 printf("--- Setup BVCI 2 ---\n\n");
1193
1194 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1195 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001196 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001197
1198 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1199
1200 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1201 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1202
1203 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1204
1205 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1206 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1207
1208 printf("--- Change NSEI ---\n\n");
1209
1210 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1211 gprs_dump_nsi(nsi);
1212
1213 printf("--- Setup BVCI 1 ---\n\n");
1214
1215 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1216 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001217 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001218
1219 printf("--- Setup BVCI 3 ---\n\n");
1220
1221 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1222 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001223 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001224
1225 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1226
1227 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1228 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1229
1230 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1231 " (should fail) ---\n\n");
1232
1233 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001234 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001235 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001236 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001237
1238 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1239
1240 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1241 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1242
1243 printf("--- Change NSVCI ---\n\n");
1244
1245 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1246 gprs_dump_nsi(nsi);
1247
1248 printf("--- Setup BVCI 1 ---\n\n");
1249
1250 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1251 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001252 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001253
1254 printf("--- Setup BVCI 4 ---\n\n");
1255
1256 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1257 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001258 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001259
1260 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1261
1262 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1263 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1264
1265 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1266 " (should fail) ---\n\n");
1267
1268 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001269 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001270 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001271 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001272
1273 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1274
1275 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1276 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1277
1278 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1279
1280 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1281 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1282
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001283 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001284 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001285
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001286 gbprox_reset(&gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001287 gprs_ns_destroy(nsi);
1288 nsi = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001289}
1290
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001291static void test_gbproxy_ra_patching()
1292{
1293 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1294 struct sockaddr_in bss_peer[1] = {{0},};
1295 struct sockaddr_in sgsn_peer= {0};
1296 struct gprs_ra_id rai_bss =
1297 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1298 struct gprs_ra_id rai_sgsn =
1299 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1300 struct gprs_ra_id rai_unknown =
1301 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001302 uint16_t cell_id = 0x7530;
Jacob Erlbeck43037632014-06-06 18:49:23 +02001303 const char *err_msg = NULL;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001304 const uint32_t ptmsi = 0xefe2b700;
1305 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001306 const uint32_t foreign_tlli = 0xbbc54679;
1307 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck31132872014-08-11 17:26:21 +02001308 struct gbproxy_tlli_info *tlli_info;
1309 struct gbproxy_peer *peer;
1310
1311 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001312
1313 bssgp_nsi = nsi;
1314 gbcfg.nsi = bssgp_nsi;
1315 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck2504bc42014-05-19 10:14:58 +02001316 gbcfg.core_mcc = 123;
1317 gbcfg.core_mnc = 456;
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001318 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freyther2d10ad12014-08-04 14:22:13 +02001319 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001320 gbcfg.patch_ptmsi = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001321
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001322 configure_sgsn_peer(&sgsn_peer);
1323 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001324
Jacob Erlbeck43037632014-06-06 18:49:23 +02001325 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001326 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck43037632014-06-06 18:49:23 +02001327 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1328 gbcfg.match_re, err_msg);
1329 exit(1);
1330 }
1331
1332
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001333 printf("=== %s ===\n", __func__);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001334 printf("--- Initialise SGSN ---\n\n");
1335
Jacob Erlbeck12356062014-08-27 12:44:25 +02001336 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001337 gprs_dump_nsi(nsi);
1338
1339 printf("--- Initialise BSS 1 ---\n\n");
1340
1341 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1342 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1343 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001344 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001345
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001346 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001347 OSMO_ASSERT(peer != NULL);
1348
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001349 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1350
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001351 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1352 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001353
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001354 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001355 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001356
1357 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1358
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001359 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1360 foreign_tlli, &rai_bss, cell_id,
1361 GPRS_SAPI_GMM, 0,
1362 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001363
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001364 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1365 foreign_tlli, 0, NULL, 0,
1366 GPRS_SAPI_GMM, 0,
1367 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001368
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001369 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1370 foreign_tlli, &rai_bss, cell_id,
1371 GPRS_SAPI_GMM, 3,
1372 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001373
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001374 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1375 foreign_tlli, 1, imsi, sizeof(imsi),
1376 GPRS_SAPI_GMM, 1,
1377 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001378
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001379 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001380 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001381 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1382 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1383 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1384 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1385 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1386 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1387 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1388 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001389
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001390 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1391 local_tlli, &rai_bss, cell_id,
1392 GPRS_SAPI_GMM, 4,
1393 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck31132872014-08-11 17:26:21 +02001394
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001395 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001396 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001397 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1398 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1399 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1400 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1401 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1402 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1403 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1404 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001405
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001406 /* Replace APN (1) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001407 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1408 local_tlli, &rai_bss, cell_id,
1409 GPRS_SAPI_GMM, 3,
1410 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001411
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001412 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001413 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001414 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1415 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1416 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1417 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1418 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1419 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1420 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1421 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001422
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001423 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1424 local_tlli, 1, imsi, sizeof(imsi),
1425 GPRS_SAPI_GMM, 2,
1426 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeckab7366f2014-06-06 18:47:36 +02001427
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001428 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001429 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001430 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1431 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1432 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1433 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001434
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001435 /* Replace APN (2) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001436 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1437 local_tlli, &rai_bss, cell_id,
1438 GPRS_SAPI_GMM, 3,
1439 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001440
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001441 gbcfg.core_apn[0] = 0;
1442 gbcfg.core_apn_size = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001443
1444 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001445 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1446 local_tlli, &rai_bss, cell_id,
1447 GPRS_SAPI_GMM, 3,
1448 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001449
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001450 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001451
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001452 /* Detach */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001453 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1454 local_tlli, &rai_bss, cell_id,
1455 GPRS_SAPI_GMM, 6,
1456 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001457
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001458 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1459 local_tlli, 1, imsi, sizeof(imsi),
1460 GPRS_SAPI_GMM, 5,
1461 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001462
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001463 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001464
1465 printf("--- RA update ---\n\n");
1466
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001467 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1468 foreign_tlli, &rai_bss, 0x7080,
1469 GPRS_SAPI_GMM, 5,
1470 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001471
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001472 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1473 foreign_tlli, 1, imsi, sizeof(imsi),
1474 GPRS_SAPI_GMM, 6,
1475 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001476
1477 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001478 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1479 local_tlli, &rai_bss, cell_id,
1480 GPRS_SAPI_GMM, 3,
1481 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001482
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001483 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001484
Jacob Erlbeckf95340d2014-08-11 15:07:37 +02001485 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001486 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1487 local_tlli, &rai_bss, cell_id,
1488 GPRS_SAPI_GMM, 6,
1489 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001490
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001491 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001492 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001493
1494 printf("--- Bad cases ---\n\n");
1495
Jacob Erlbeck43037632014-06-06 18:49:23 +02001496 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001497 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1498 local_tlli, &rai_bss, cell_id,
1499 GPRS_SAPI_GMM, 3,
1500 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001501
Jacob Erlbeck90a1fd12014-05-27 13:49:04 +02001502 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001503 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001504
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001505 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001506 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001507
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001508 gbprox_reset(&gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001509 gprs_ns_destroy(nsi);
1510 nsi = NULL;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001511}
1512
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001513static void test_gbproxy_ptmsi_patching()
1514{
1515 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1516 struct sockaddr_in bss_peer[1] = {{0},};
1517 struct sockaddr_in sgsn_peer= {0};
1518 struct gprs_ra_id rai_bss =
1519 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1520 struct gprs_ra_id rai_sgsn =
1521 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001522 struct gprs_ra_id rai_wrong_mcc_sgsn =
1523 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001524 struct gprs_ra_id rai_unknown =
1525 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1526 uint16_t cell_id = 0x1234;
1527
1528 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001529 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1530 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001531 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001532 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1533 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001534 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1535
1536 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001537 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1538 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001539 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001540 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1541 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001542 const uint32_t foreign_bss_tlli = 0x8000dead;
1543
1544 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1545 struct gbproxy_tlli_info *tlli_info;
1546 struct gbproxy_peer *peer;
1547 unsigned bss_nu = 0;
1548 unsigned sgsn_nu = 0;
1549
1550 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001551 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1552 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1553 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1554 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1555 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001556
1557 bssgp_nsi = nsi;
1558 gbcfg.nsi = bssgp_nsi;
1559 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1560 gbcfg.core_mcc = 123;
1561 gbcfg.core_mnc = 456;
1562 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1563 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1564 gbcfg.patch_ptmsi = 1;
1565 gbcfg.bss_ptmsi_state = 0;
1566 gbcfg.sgsn_tlli_state = 1;
1567
1568 configure_sgsn_peer(&sgsn_peer);
1569 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1570
1571 printf("=== %s ===\n", __func__);
1572 printf("--- Initialise SGSN ---\n\n");
1573
Jacob Erlbeck12356062014-08-27 12:44:25 +02001574 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001575
1576 printf("--- Initialise BSS 1 ---\n\n");
1577
1578 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1579 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1580
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001581 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001582 OSMO_ASSERT(peer != NULL);
1583
1584 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1585
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001586 gprs_dump_nsi(nsi);
1587 dump_global(stdout, 0);
1588 dump_peers(stdout, 0, 0, &gbcfg);
1589
1590 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1591
1592 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1593 foreign_bss_tlli, &rai_unknown, cell_id,
1594 GPRS_SAPI_GMM, bss_nu++,
1595 dtap_attach_req, sizeof(dtap_attach_req));
1596
1597 dump_peers(stdout, 0, 0, &gbcfg);
1598
1599 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1600 random_sgsn_tlli, 0, NULL, 0,
1601 GPRS_SAPI_GMM, sgsn_nu++,
1602 dtap_identity_req, sizeof(dtap_identity_req));
1603
1604 dump_peers(stdout, 0, 0, &gbcfg);
1605
1606 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1607 foreign_bss_tlli, &rai_bss, cell_id,
1608 GPRS_SAPI_GMM, bss_nu++,
1609 dtap_identity_resp, sizeof(dtap_identity_resp));
1610
1611 dump_peers(stdout, 0, 0, &gbcfg);
1612
1613 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1614 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1615 GPRS_SAPI_GMM, sgsn_nu++,
1616 dtap_attach_acc, sizeof(dtap_attach_acc));
1617
1618 dump_peers(stdout, 0, 0, &gbcfg);
1619
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001620 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001621 OSMO_ASSERT(tlli_info);
1622 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1623 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1624 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1625 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1626 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1627 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1628 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1629 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1630 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1631 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1632
1633 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1634 local_bss_tlli, &rai_bss, cell_id,
1635 GPRS_SAPI_GMM, bss_nu++,
1636 dtap_attach_complete, sizeof(dtap_attach_complete));
1637
1638 dump_peers(stdout, 0, 0, &gbcfg);
1639
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001640 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001641 OSMO_ASSERT(tlli_info);
1642 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1643 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1644 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1645 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1646 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1647 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1648 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1649 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1650
1651 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1652 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1653 GPRS_SAPI_GMM, sgsn_nu++,
1654 dtap_gmm_information, sizeof(dtap_gmm_information));
1655
1656 dump_peers(stdout, 0, 0, &gbcfg);
1657
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001658 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001659 OSMO_ASSERT(tlli_info);
1660 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1661 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1662 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1663 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1664
Jacob Erlbeck03e02ac2014-09-05 18:08:12 +02001665 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1666 local_bss_tlli, &rai_bss, cell_id,
1667 GPRS_SAPI_GMM, bss_nu++,
1668 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1669
1670 dump_peers(stdout, 0, 0, &gbcfg);
1671
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001672 /* Non-DTAP */
1673 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1674 local_bss_tlli, &rai_bss, cell_id,
1675 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1676
1677 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1678 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1679 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1680
1681 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1682 local_bss_tlli, &rai_bss, cell_id,
1683 llc_ui_ll11_dns_query_ul,
1684 sizeof(llc_ui_ll11_dns_query_ul));
1685
1686 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1687 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1688 llc_ui_ll11_dns_resp_dl,
1689 sizeof(llc_ui_ll11_dns_resp_dl));
1690
1691 dump_peers(stdout, 0, 0, &gbcfg);
1692
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001693 /* Repeated RA Update Requests */
1694 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1695 local_bss_tlli, &rai_bss, 0x7080,
1696 GPRS_SAPI_GMM, bss_nu++,
1697 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1698
1699 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1700 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1701 GPRS_SAPI_GMM, sgsn_nu++,
1702 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1703
1704 dump_peers(stdout, 0, 0, &gbcfg);
1705
1706 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1707 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1708 OSMO_ASSERT(tlli_info);
1709 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1710 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1711 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1712 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1713 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1714 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1715 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1716 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1717 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1718 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1719
1720 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1721 local_bss_tlli2, &rai_bss, 0x7080,
1722 GPRS_SAPI_GMM, bss_nu++,
1723 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1724
1725 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1726 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1727 GPRS_SAPI_GMM, sgsn_nu++,
1728 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1729
1730 dump_peers(stdout, 0, 0, &gbcfg);
1731
1732 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1733 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1734 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1735 OSMO_ASSERT(tlli_info);
1736 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1737 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1738 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1739 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1740 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1741 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1742 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1743 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1744 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1745 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1746
1747 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1748 local_bss_tlli3, &rai_bss, 0x7080,
1749 GPRS_SAPI_GMM, bss_nu++,
1750 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1751
1752 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1753
1754 OSMO_ASSERT(tlli_info);
1755 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1756 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1757 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1758 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1759
1760 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1761 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1762 GPRS_SAPI_GMM, sgsn_nu++,
1763 dtap_gmm_information, sizeof(dtap_gmm_information));
1764
1765 dump_peers(stdout, 0, 0, &gbcfg);
1766
1767 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1768 OSMO_ASSERT(tlli_info);
1769 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1770 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1771 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1772 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1773
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001774 /* Other messages */
1775 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001776 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001777
1778 dump_peers(stdout, 0, 0, &gbcfg);
1779
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001780 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001781
1782 dump_peers(stdout, 0, 0, &gbcfg);
1783
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001784 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001785
1786 dump_peers(stdout, 0, 0, &gbcfg);
1787
1788 /* Bad case: Invalid BVCI */
1789 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001790 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001791 dump_global(stdout, 0);
1792
1793 /* Bad case: Invalid RAI */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001794 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001795
1796 dump_global(stdout, 0);
1797
1798 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001799 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001800 &rai_wrong_mcc_sgsn);
1801
1802 dump_global(stdout, 0);
1803
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001804 /* Detach */
1805 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001806 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001807 GPRS_SAPI_GMM, bss_nu++,
1808 dtap_detach_req, sizeof(dtap_detach_req));
1809
1810 dump_peers(stdout, 0, 0, &gbcfg);
1811
1812 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02001813 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001814 GPRS_SAPI_GMM, sgsn_nu++,
1815 dtap_detach_acc, sizeof(dtap_detach_acc));
1816
1817 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001818
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02001819 dump_global(stdout, 0);
1820
1821 gbprox_reset(&gbcfg);
1822 gprs_ns_destroy(nsi);
1823 nsi = NULL;
1824}
1825
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001826static void test_gbproxy_imsi_acquisition()
1827{
1828 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1829 struct sockaddr_in bss_peer[1] = {{0},};
1830 struct sockaddr_in sgsn_peer= {0};
1831 struct gprs_ra_id rai_bss =
1832 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1833 struct gprs_ra_id rai_sgsn =
1834 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1835 struct gprs_ra_id rai_wrong_mcc_sgsn =
1836 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1837 struct gprs_ra_id rai_unknown =
1838 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1839 uint16_t cell_id = 0x1234;
1840
1841 const uint32_t sgsn_ptmsi = 0xefe2b700;
1842 const uint32_t local_sgsn_tlli = 0xefe2b700;
1843 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1844
1845 const uint32_t bss_ptmsi = 0xc00f7304;
1846 const uint32_t local_bss_tlli = 0xc00f7304;
1847 const uint32_t foreign_bss_tlli = 0x8000dead;
1848
1849 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1850 struct gbproxy_tlli_info *tlli_info;
1851 struct gbproxy_peer *peer;
1852 unsigned bss_nu = 0;
1853 unsigned sgsn_nu = 0;
1854
1855 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1856
1857 bssgp_nsi = nsi;
1858 gbcfg.nsi = bssgp_nsi;
1859 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1860 gbcfg.core_mcc = 123;
1861 gbcfg.core_mnc = 456;
1862 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1863 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1864 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02001865 gbcfg.acquire_imsi = 1;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001866 gbcfg.bss_ptmsi_state = 0;
1867 gbcfg.sgsn_tlli_state = 1;
1868
1869 configure_sgsn_peer(&sgsn_peer);
1870 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1871
1872 printf("=== %s ===\n", __func__);
1873 printf("--- Initialise SGSN ---\n\n");
1874
Jacob Erlbeck12356062014-08-27 12:44:25 +02001875 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001876
1877 printf("--- Initialise BSS 1 ---\n\n");
1878
1879 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1880 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1881
1882 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1883 OSMO_ASSERT(peer != NULL);
1884
1885 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1886
1887 gprs_dump_nsi(nsi);
1888 dump_global(stdout, 0);
1889 dump_peers(stdout, 0, 0, &gbcfg);
1890
1891 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1892
1893 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1894 foreign_bss_tlli, &rai_unknown, cell_id,
1895 GPRS_SAPI_GMM, bss_nu++,
1896 dtap_attach_req, sizeof(dtap_attach_req));
1897
1898 dump_peers(stdout, 0, 0, &gbcfg);
1899
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02001900 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1901 foreign_bss_tlli, &rai_bss, cell_id,
1902 GPRS_SAPI_GMM, bss_nu++,
1903 dtap_identity_resp, sizeof(dtap_identity_resp));
1904
1905 dump_peers(stdout, 0, 0, &gbcfg);
1906
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02001907 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1908 random_sgsn_tlli, 0, NULL, 0,
1909 GPRS_SAPI_GMM, sgsn_nu++,
1910 dtap_identity_req, sizeof(dtap_identity_req));
1911
1912 dump_peers(stdout, 0, 0, &gbcfg);
1913
1914 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1915 foreign_bss_tlli, &rai_bss, cell_id,
1916 GPRS_SAPI_GMM, bss_nu++,
1917 dtap_identity_resp, sizeof(dtap_identity_resp));
1918
1919 dump_peers(stdout, 0, 0, &gbcfg);
1920
1921 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1922 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1923 GPRS_SAPI_GMM, sgsn_nu++,
1924 dtap_attach_acc, sizeof(dtap_attach_acc));
1925
1926 dump_peers(stdout, 0, 0, &gbcfg);
1927
1928 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1929 OSMO_ASSERT(tlli_info);
1930 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1931 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1932 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1933 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1934 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1935 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1936 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1937 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1938 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1939 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1940
1941 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1942 local_bss_tlli, &rai_bss, cell_id,
1943 GPRS_SAPI_GMM, bss_nu++,
1944 dtap_attach_complete, sizeof(dtap_attach_complete));
1945
1946 dump_peers(stdout, 0, 0, &gbcfg);
1947
1948 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1949 OSMO_ASSERT(tlli_info);
1950 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1951 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1952 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1953 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1954 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1955 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1956 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1957 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1958
1959 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1960 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1961 GPRS_SAPI_GMM, sgsn_nu++,
1962 dtap_gmm_information, sizeof(dtap_gmm_information));
1963
1964 dump_peers(stdout, 0, 0, &gbcfg);
1965
1966 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1967 OSMO_ASSERT(tlli_info);
1968 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1969 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1970 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1971 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1972
1973 /* Non-DTAP */
1974 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1975 local_bss_tlli, &rai_bss, cell_id,
1976 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1977
1978 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1979 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1980 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1981
1982 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1983 local_bss_tlli, &rai_bss, cell_id,
1984 llc_ui_ll11_dns_query_ul,
1985 sizeof(llc_ui_ll11_dns_query_ul));
1986
1987 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1988 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1989 llc_ui_ll11_dns_resp_dl,
1990 sizeof(llc_ui_ll11_dns_resp_dl));
1991
1992 dump_peers(stdout, 0, 0, &gbcfg);
1993
1994 /* Other messages */
1995 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
1996 local_bss_tlli, 1, 12);
1997
1998 dump_peers(stdout, 0, 0, &gbcfg);
1999
2000 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2001 local_sgsn_tlli, 1, 12);
2002
2003 dump_peers(stdout, 0, 0, &gbcfg);
2004
2005 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2006
2007 dump_peers(stdout, 0, 0, &gbcfg);
2008
2009 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2010
2011 dump_peers(stdout, 0, 0, &gbcfg);
2012
2013 /* Bad case: Invalid BVCI */
2014 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2015 local_bss_tlli, 1, 12);
2016 dump_global(stdout, 0);
2017
2018 /* Bad case: Invalid RAI */
2019 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2020
2021 dump_global(stdout, 0);
2022
2023 /* Bad case: Invalid MCC (LAC ok) */
2024 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2025 &rai_wrong_mcc_sgsn);
2026
2027 dump_global(stdout, 0);
2028
2029 /* Detach */
2030 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2031 local_bss_tlli, &rai_bss, cell_id,
2032 GPRS_SAPI_GMM, bss_nu++,
2033 dtap_detach_req, sizeof(dtap_detach_req));
2034
2035 dump_peers(stdout, 0, 0, &gbcfg);
2036
2037 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2038 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2039 GPRS_SAPI_GMM, sgsn_nu++,
2040 dtap_detach_acc, sizeof(dtap_detach_acc));
2041
2042 dump_peers(stdout, 0, 0, &gbcfg);
2043
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +02002044 /* Special case: Repeated Attach Requests */
2045
2046 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2047 foreign_bss_tlli, &rai_unknown, cell_id,
2048 GPRS_SAPI_GMM, bss_nu++,
2049 dtap_attach_req, sizeof(dtap_attach_req));
2050
2051 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2052 foreign_bss_tlli, &rai_unknown, cell_id,
2053 GPRS_SAPI_GMM, bss_nu++,
2054 dtap_attach_req, sizeof(dtap_attach_req));
2055
2056 dump_peers(stdout, 0, 0, &gbcfg);
2057
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002058 dump_global(stdout, 0);
2059
2060 gbprox_reset(&gbcfg);
2061 gprs_ns_destroy(nsi);
2062 nsi = NULL;
2063}
2064
Jacob Erlbeck12356062014-08-27 12:44:25 +02002065static void test_gbproxy_secondary_sgsn()
2066{
2067 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2068 struct sockaddr_in bss_peer[1] = {{0},};
2069 struct sockaddr_in sgsn_peer[2]= {{0},};
2070 struct gprs_ra_id rai_bss =
2071 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2072 struct gprs_ra_id rai_sgsn =
2073 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2074 struct gprs_ra_id rai_unknown =
2075 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2076 uint16_t cell_id = 0x1234;
2077
2078 const uint32_t sgsn_ptmsi = 0xefe2b700;
2079 const uint32_t local_sgsn_tlli = 0xefe2b700;
2080 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2081
2082 const uint32_t bss_ptmsi = 0xc00f7304;
2083 const uint32_t local_bss_tlli = 0xc00f7304;
2084 const uint32_t foreign_bss_tlli = 0x8000dead;
2085
2086 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2087 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2088 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2089 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2090 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2091 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2092
2093 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2094 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2095 struct gbproxy_tlli_info *tlli_info;
2096 struct gbproxy_peer *peer;
2097 unsigned bss_nu = 0;
2098 unsigned sgsn_nu = 0;
2099
2100 const char *err_msg = NULL;
2101 const char *filter_re = "999999";
2102
2103 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2104 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2105
2106 bssgp_nsi = nsi;
2107 gbcfg.nsi = bssgp_nsi;
2108 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2109 gbcfg.core_mcc = 123;
2110 gbcfg.core_mnc = 456;
2111 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2112 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2113 gbcfg.patch_ptmsi = 1;
2114 gbcfg.acquire_imsi = 1;
2115 gbcfg.bss_ptmsi_state = 0;
2116 gbcfg.sgsn_tlli_state = 1;
2117 gbcfg.route_to_sgsn2 = 1;
2118 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2119
2120 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2121 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2122 err_msg);
2123 OSMO_ASSERT(err_msg == NULL);
2124 }
2125
2126 configure_sgsn_peer(&sgsn_peer[0]);
2127 configure_sgsn2_peer(&sgsn_peer[1]);
2128 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2129
2130 printf("=== %s ===\n", __func__);
2131 printf("--- Initialise SGSN 1 ---\n\n");
2132
2133 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2134
2135 printf("--- Initialise SGSN 2 ---\n\n");
2136
2137 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2138
2139 printf("--- Initialise BSS 1 ---\n\n");
2140
2141 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2142 setup_bssgp(nsi, &bss_peer[0], 0x0);
2143 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2144 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2145 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2146 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2147
2148 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2149 OSMO_ASSERT(peer != NULL);
2150
2151 gprs_dump_nsi(nsi);
2152 dump_global(stdout, 0);
2153 dump_peers(stdout, 0, 0, &gbcfg);
2154
2155 printf("--- Flow control ---\n\n");
2156
2157 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2158 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2159 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2160
2161 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2162
2163 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2164 foreign_bss_tlli, &rai_unknown, cell_id,
2165 GPRS_SAPI_GMM, bss_nu++,
2166 dtap_attach_req, sizeof(dtap_attach_req));
2167
2168 dump_peers(stdout, 0, 0, &gbcfg);
2169
2170 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2171 foreign_bss_tlli, &rai_bss, cell_id,
2172 GPRS_SAPI_GMM, bss_nu++,
2173 dtap_identity_resp, sizeof(dtap_identity_resp));
2174
2175 dump_peers(stdout, 0, 0, &gbcfg);
2176
2177 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2178 random_sgsn_tlli, 0, NULL, 0,
2179 GPRS_SAPI_GMM, sgsn_nu++,
2180 dtap_identity_req, sizeof(dtap_identity_req));
2181
2182 dump_peers(stdout, 0, 0, &gbcfg);
2183
2184 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2185 foreign_bss_tlli, &rai_bss, cell_id,
2186 GPRS_SAPI_GMM, bss_nu++,
2187 dtap_identity_resp, sizeof(dtap_identity_resp));
2188
2189 dump_peers(stdout, 0, 0, &gbcfg);
2190
2191 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2192 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2193 GPRS_SAPI_GMM, sgsn_nu++,
2194 dtap_attach_acc, sizeof(dtap_attach_acc));
2195
2196 dump_peers(stdout, 0, 0, &gbcfg);
2197
2198 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2199 OSMO_ASSERT(tlli_info);
2200 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2201 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2202 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2203 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2204 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2205 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2206 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2207 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2208 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2209 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2210
2211 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2212 local_bss_tlli, &rai_bss, cell_id,
2213 GPRS_SAPI_GMM, bss_nu++,
2214 dtap_attach_complete, sizeof(dtap_attach_complete));
2215
2216 dump_peers(stdout, 0, 0, &gbcfg);
2217
2218 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2219 OSMO_ASSERT(tlli_info);
2220 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2221 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2222 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2223 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2224 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2225 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2226 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2227 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2228
2229 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2230 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2231 GPRS_SAPI_GMM, sgsn_nu++,
2232 dtap_gmm_information, sizeof(dtap_gmm_information));
2233
2234 dump_peers(stdout, 0, 0, &gbcfg);
2235
2236 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2237 OSMO_ASSERT(tlli_info);
2238 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2239 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2240 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2241 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2242
2243 /* Non-DTAP */
2244 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2245 local_bss_tlli, &rai_bss, cell_id,
2246 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2247
2248 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2249 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2250 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2251
2252 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2253 local_bss_tlli, &rai_bss, cell_id,
2254 llc_ui_ll11_dns_query_ul,
2255 sizeof(llc_ui_ll11_dns_query_ul));
2256
2257 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2258 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2259 llc_ui_ll11_dns_resp_dl,
2260 sizeof(llc_ui_ll11_dns_resp_dl));
2261
2262 dump_peers(stdout, 0, 0, &gbcfg);
2263
2264 /* Other messages */
2265 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2266 local_bss_tlli, 1, 12);
2267
2268 dump_peers(stdout, 0, 0, &gbcfg);
2269
2270 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2271 local_sgsn_tlli, 1, 12);
2272
2273 dump_peers(stdout, 0, 0, &gbcfg);
2274
2275 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2276
2277 dump_peers(stdout, 0, 0, &gbcfg);
2278
2279 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2280
2281 dump_peers(stdout, 0, 0, &gbcfg);
2282
2283 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2284
2285 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2286 foreign_bss_tlli2, &rai_unknown, cell_id,
2287 GPRS_SAPI_GMM, bss_nu++,
2288 dtap_attach_req, sizeof(dtap_attach_req));
2289
2290 dump_peers(stdout, 0, 0, &gbcfg);
2291
2292 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2293 foreign_bss_tlli2, &rai_bss, cell_id,
2294 GPRS_SAPI_GMM, bss_nu++,
2295 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2296
2297 dump_peers(stdout, 0, 0, &gbcfg);
2298
2299 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2300 random_sgsn_tlli2, 0, NULL, 0,
2301 GPRS_SAPI_GMM, sgsn_nu++,
2302 dtap_identity_req, sizeof(dtap_identity_req));
2303
2304 dump_peers(stdout, 0, 0, &gbcfg);
2305
2306 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2307 foreign_bss_tlli2, &rai_bss, cell_id,
2308 GPRS_SAPI_GMM, bss_nu++,
2309 dtap_identity_resp, sizeof(dtap_identity_resp));
2310
2311 dump_peers(stdout, 0, 0, &gbcfg);
2312
2313 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2314 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2315 GPRS_SAPI_GMM, sgsn_nu++,
2316 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2317
2318 dump_peers(stdout, 0, 0, &gbcfg);
2319
2320 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2321 OSMO_ASSERT(tlli_info);
2322 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2323 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2324 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2325 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2326 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2327 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2328 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2329 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2330 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2331 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2332
2333 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2334 local_bss_tlli2, &rai_bss, cell_id,
2335 GPRS_SAPI_GMM, bss_nu++,
2336 dtap_attach_complete, sizeof(dtap_attach_complete));
2337
2338 dump_peers(stdout, 0, 0, &gbcfg);
2339
2340 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2341 OSMO_ASSERT(tlli_info);
2342 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2343 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2344 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2345 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2346 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2347 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2348 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2349 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2350
2351 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2352 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2353 GPRS_SAPI_GMM, sgsn_nu++,
2354 dtap_gmm_information, sizeof(dtap_gmm_information));
2355
2356 dump_peers(stdout, 0, 0, &gbcfg);
2357
2358 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2359 OSMO_ASSERT(tlli_info);
2360 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2361 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2362 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2363 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2364
2365 /* Non-DTAP */
2366 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2367 local_bss_tlli2, &rai_bss, cell_id,
2368 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2369
2370 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2371 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2372 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2373
2374 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2375 local_bss_tlli2, &rai_bss, cell_id,
2376 llc_ui_ll11_dns_query_ul,
2377 sizeof(llc_ui_ll11_dns_query_ul));
2378
2379 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2380 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2381 llc_ui_ll11_dns_resp_dl,
2382 sizeof(llc_ui_ll11_dns_resp_dl));
2383
2384 dump_peers(stdout, 0, 0, &gbcfg);
2385
2386 /* Other messages */
2387 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2388 local_bss_tlli2, 1, 12);
2389
2390 dump_peers(stdout, 0, 0, &gbcfg);
2391
2392 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2393 local_sgsn_tlli2, 1, 12);
2394
2395 dump_peers(stdout, 0, 0, &gbcfg);
2396
2397 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2398
2399 dump_peers(stdout, 0, 0, &gbcfg);
2400
2401 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2402
2403 dump_peers(stdout, 0, 0, &gbcfg);
2404
2405 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2406
2407 /* Detach */
2408 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2409 local_bss_tlli, &rai_bss, cell_id,
2410 GPRS_SAPI_GMM, bss_nu++,
2411 dtap_detach_req, sizeof(dtap_detach_req));
2412
2413 dump_peers(stdout, 0, 0, &gbcfg);
2414
2415 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2416 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2417 GPRS_SAPI_GMM, sgsn_nu++,
2418 dtap_detach_acc, sizeof(dtap_detach_acc));
2419
2420 dump_peers(stdout, 0, 0, &gbcfg);
2421
2422 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2423
2424 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2425 local_bss_tlli2, &rai_bss, cell_id,
2426 GPRS_SAPI_GMM, bss_nu++,
2427 dtap_detach_req, sizeof(dtap_detach_req));
2428
2429 dump_peers(stdout, 0, 0, &gbcfg);
2430
2431 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2432 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2433 GPRS_SAPI_GMM, sgsn_nu++,
2434 dtap_detach_acc, sizeof(dtap_detach_acc));
2435
2436 dump_peers(stdout, 0, 0, &gbcfg);
2437
2438 dump_global(stdout, 0);
2439
2440 gbprox_reset(&gbcfg);
2441 gprs_ns_destroy(nsi);
2442 nsi = NULL;
2443}
2444
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002445/* TODO: Move tlv testing to libosmocore */
2446int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2447int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2448 uint8_t **value);
2449int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2450 size_t *value_len);
2451int lv_shift(uint8_t **data, size_t *data_len,
2452 uint8_t **value, size_t *value_len);
2453
2454static void check_tlv_match(uint8_t **data, size_t *data_len,
2455 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2456{
2457 uint8_t *value;
2458 size_t value_len;
2459 int rc;
2460
2461 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2462 OSMO_ASSERT(rc == 0);
2463
2464 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002465 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002466 OSMO_ASSERT(value_len == exp_len);
2467 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2468}
2469
2470static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2471 uint8_t tag, size_t len, const uint8_t *exp_val)
2472{
2473 uint8_t *value;
2474 int rc;
2475
2476 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2477 OSMO_ASSERT(rc == 0);
2478
2479 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002480 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002481 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2482}
2483
2484static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2485 size_t len, const uint8_t *exp_val)
2486{
2487 uint8_t *value;
2488 int rc;
2489
2490 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002491 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002492 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2493}
2494
2495static void check_lv_shift(uint8_t **data, size_t *data_len,
2496 size_t exp_len, const uint8_t *exp_val)
2497{
2498 uint8_t *value;
2499 size_t value_len;
2500 int rc;
2501
2502 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002503 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002504 OSMO_ASSERT(value_len == exp_len);
2505 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2506}
2507
2508static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2509 const uint8_t *test_data)
2510{
2511 uint8_t buf[300] = {0};
2512
2513 uint8_t *unchanged_ptr = buf - 1;
2514 size_t unchanged_len = 0xdead;
2515 size_t tmp_data_len = data_len;
2516 uint8_t *value = unchanged_ptr;
2517 size_t value_len = unchanged_len;
2518 uint8_t *data = buf;
2519
2520 OSMO_ASSERT(data_len <= sizeof(buf));
2521
2522 tlv_put(data, tag, len, test_data);
2523 if (data_len < len + 2) {
2524 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2525 tag, &value, &value_len));
2526 OSMO_ASSERT(tmp_data_len == 0);
2527 OSMO_ASSERT(data == buf + data_len);
2528 OSMO_ASSERT(value == unchanged_ptr);
2529 OSMO_ASSERT(value_len == unchanged_len);
2530 } else {
2531 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2532 tag, &value, &value_len));
2533 OSMO_ASSERT(value != unchanged_ptr);
2534 OSMO_ASSERT(value_len != unchanged_len);
2535 }
2536}
2537
2538static void check_tv_fixed_match_data_len(size_t data_len,
2539 uint8_t tag, size_t len,
2540 const uint8_t *test_data)
2541{
2542 uint8_t buf[300] = {0};
2543
2544 uint8_t *unchanged_ptr = buf - 1;
2545 size_t tmp_data_len = data_len;
2546 uint8_t *value = unchanged_ptr;
2547 uint8_t *data = buf;
2548
2549 OSMO_ASSERT(data_len <= sizeof(buf));
2550
2551 tv_fixed_put(data, tag, len, test_data);
2552
2553 if (data_len < len + 1) {
2554 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2555 tag, len, &value));
2556 OSMO_ASSERT(tmp_data_len == 0);
2557 OSMO_ASSERT(data == buf + data_len);
2558 OSMO_ASSERT(value == unchanged_ptr);
2559 } else {
2560 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2561 tag, len, &value));
2562 OSMO_ASSERT(value != unchanged_ptr);
2563 }
2564}
2565
2566static void check_v_fixed_shift_data_len(size_t data_len,
2567 size_t len, const uint8_t *test_data)
2568{
2569 uint8_t buf[300] = {0};
2570
2571 uint8_t *unchanged_ptr = buf - 1;
2572 size_t tmp_data_len = data_len;
2573 uint8_t *value = unchanged_ptr;
2574 uint8_t *data = buf;
2575
2576 OSMO_ASSERT(data_len <= sizeof(buf));
2577
2578 memcpy(data, test_data, len);
2579
2580 if (data_len < len) {
2581 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2582 len, &value));
2583 OSMO_ASSERT(tmp_data_len == 0);
2584 OSMO_ASSERT(data == buf + data_len);
2585 OSMO_ASSERT(value == unchanged_ptr);
2586 } else {
2587 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2588 len, &value));
2589 OSMO_ASSERT(value != unchanged_ptr);
2590 }
2591}
2592
2593static void check_lv_shift_data_len(size_t data_len,
2594 size_t len, const uint8_t *test_data)
2595{
2596 uint8_t buf[300] = {0};
2597
2598 uint8_t *unchanged_ptr = buf - 1;
2599 size_t unchanged_len = 0xdead;
2600 size_t tmp_data_len = data_len;
2601 uint8_t *value = unchanged_ptr;
2602 size_t value_len = unchanged_len;
2603 uint8_t *data = buf;
2604
2605 lv_put(data, len, test_data);
2606 if (data_len < len + 1) {
2607 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2608 &value, &value_len));
2609 OSMO_ASSERT(tmp_data_len == 0);
2610 OSMO_ASSERT(data == buf + data_len);
2611 OSMO_ASSERT(value == unchanged_ptr);
2612 OSMO_ASSERT(value_len == unchanged_len);
2613 } else {
2614 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2615 &value, &value_len));
2616 OSMO_ASSERT(value != unchanged_ptr);
2617 OSMO_ASSERT(value_len != unchanged_len);
2618 }
2619}
2620
2621static void test_tlv_shift_functions()
2622{
2623 uint8_t test_data[1024];
2624 uint8_t buf[1024];
2625 uint8_t *data_end;
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002626 unsigned i, len;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002627 uint8_t *data;
2628 size_t data_len;
2629 const uint8_t tag = 0x1a;
2630
2631 printf("Test shift functions\n");
2632
2633 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2634 test_data[i] = (uint8_t)i;
2635
2636 for (len = 0; len < 256; len++) {
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02002637 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02002638
2639 memset(buf, 0xee, sizeof(buf));
2640 data_end = data = buf;
2641
2642 for (i = 0; i < iterations; i++) {
2643 data_end = tlv_put(data_end, tag, len, test_data);
2644 data_end = tv_fixed_put(data_end, tag, len, test_data);
2645 /* v_fixed_put */
2646 memcpy(data_end, test_data, len);
2647 data_end += len;
2648 data_end = lv_put(data_end, len, test_data);
2649 }
2650
2651 data_len = data_end - data;
2652 OSMO_ASSERT(data_len <= sizeof(buf));
2653
2654 for (i = 0; i < iterations; i++) {
2655 check_tlv_match(&data, &data_len, tag, len, test_data);
2656 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2657 check_v_fixed_shift(&data, &data_len, len, test_data);
2658 check_lv_shift(&data, &data_len, len, test_data);
2659 }
2660
2661 OSMO_ASSERT(data == data_end);
2662
2663 /* Test at end of data */
2664
2665 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2666 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2667 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2668 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2669
2670 /* Test invalid data_len */
2671 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2672 check_tlv_match_data_len(data_len, tag, len, test_data);
2673 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2674 check_v_fixed_shift_data_len(data_len, len, test_data);
2675 check_lv_shift_data_len(data_len, len, test_data);
2676 }
2677 }
2678}
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002679
2680static void test_gbproxy_tlli_expire(void)
2681{
2682 struct gbproxy_config cfg = {0};
2683 struct gbproxy_peer *peer;
2684 const char *err_msg = NULL;
2685 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2686 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002687 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002688 const uint32_t tlli1 = 1234 | 0xc0000000;
2689 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002690 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002691 const char *filter_re = ".*";
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002692 time_t now = 1407479214;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002693
2694 printf("Test TLLI info expiry\n\n");
2695
2696 gbproxy_init_config(&cfg);
2697
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002698 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002699 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2700 err_msg);
2701 OSMO_ASSERT(err_msg == NULL);
2702 }
2703
2704 {
2705 struct gbproxy_tlli_info *tlli_info;
2706
2707 printf("Test TLLI replacement:\n");
2708
2709 cfg.tlli_max_len = 0;
2710 cfg.tlli_max_age = 0;
2711 peer = gbproxy_peer_alloc(&cfg, 20);
2712 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2713
2714 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002715 tlli_info = gbproxy_register_tlli(peer, tlli1,
2716 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002717 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002718 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002719 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2720
2721 /* replace the old entry */
2722 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002723 tlli_info = gbproxy_register_tlli(peer, tlli2,
2724 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002725 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002726 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002727 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2728
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002729 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002730
2731 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002732 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002733 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002734 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002735 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002736 OSMO_ASSERT(!tlli_info);
2737
2738 printf("\n");
2739
2740 gbproxy_peer_free(peer);
2741 }
2742
2743 {
2744 struct gbproxy_tlli_info *tlli_info;
2745
2746 printf("Test IMSI replacement:\n");
2747
2748 cfg.tlli_max_len = 0;
2749 cfg.tlli_max_age = 0;
2750 peer = gbproxy_peer_alloc(&cfg, 20);
2751 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2752
2753 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002754 tlli_info = gbproxy_register_tlli(peer, tlli1,
2755 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002756 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002757 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002758 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2759
2760 /* try to replace the old entry */
2761 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002762 tlli_info = gbproxy_register_tlli(peer, tlli1,
2763 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckccc59702014-08-07 20:18:47 +02002764 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002765 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002766 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2767
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002768 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002769
2770 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002771 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002772 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002773 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002774 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002775 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002776
2777 printf("\n");
2778
2779 gbproxy_peer_free(peer);
2780 }
2781
2782 {
2783 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002784 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002785
2786 printf("Test TLLI expiry, max_len == 1:\n");
2787
2788 cfg.tlli_max_len = 1;
2789 cfg.tlli_max_age = 0;
2790 peer = gbproxy_peer_alloc(&cfg, 20);
2791 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2792
2793 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002794 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002795 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2796
2797 /* replace the old entry */
2798 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002799 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002800 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2801
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002802 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002803 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002804 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2805
Jacob Erlbeckc404c082014-08-08 08:37:37 +02002806 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002807
2808 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002809 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002810 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002811 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002812 OSMO_ASSERT(tlli_info);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002813 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002814
2815 printf("\n");
2816
2817 gbproxy_peer_free(peer);
2818 }
2819
2820 {
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002821 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02002822 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002823
2824 printf("Test TLLI expiry, max_age == 1:\n");
2825
2826 cfg.tlli_max_len = 0;
2827 cfg.tlli_max_age = 1;
2828 peer = gbproxy_peer_alloc(&cfg, 20);
2829 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2830
2831 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002832 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002833 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2834
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002835 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002836 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002837 now + 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002838 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2839
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002840 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002841 OSMO_ASSERT(num_removed == 1);
2842 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2843
2844 dump_peers(stdout, 2, now + 2, &cfg);
2845
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002846 /* verify that 5678 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002847 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002848 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002849 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002850 OSMO_ASSERT(tlli_info);
2851 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2852
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002853 printf("\n");
2854
2855 gbproxy_peer_free(peer);
2856 }
2857
2858 {
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002859 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002860 int num_removed;
2861
2862 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2863
2864 cfg.tlli_max_len = 0;
2865 cfg.tlli_max_age = 1;
2866 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002867 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2868
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002869 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002870 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002871 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2872
2873 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002874 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002875 now + 1);
2876 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2877
2878 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002879 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2880 now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002881 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2882
2883 dump_peers(stdout, 2, now + 2, &cfg);
2884
2885 printf(" Remove stale TLLIs\n");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002886 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02002887 OSMO_ASSERT(num_removed == 2);
2888 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2889
2890 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002891
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002892 /* verify that tlli3 has survived */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002893 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002894 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002895 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002896 OSMO_ASSERT(!tlli_info);
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002897 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck383c8412014-08-12 16:30:30 +02002898 OSMO_ASSERT(tlli_info);
2899 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2900
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02002901 printf("\n");
2902
2903 gbproxy_peer_free(peer);
2904 }
2905}
2906
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002907static void test_gbproxy_imsi_matching(void)
2908{
2909 struct gbproxy_config cfg = {0};
2910 struct gbproxy_peer *peer;
2911 const char *err_msg = NULL;
2912 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2913 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2914 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2915 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2916 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2917 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2918 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2919 const char *filter_re1 = ".*";
2920 const char *filter_re2 = "^1234";
2921 const char *filter_re3 = "^4321";
2922 const char *filter_re4_bad = "^12[";
2923
2924 printf("=== Test IMSI/TMSI matching ===\n\n");
2925
2926 gbproxy_init_config(&cfg);
2927 OSMO_ASSERT(cfg.check_imsi == 0);
2928
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002929 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002930 OSMO_ASSERT(cfg.check_imsi == 1);
2931
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002932 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002933 OSMO_ASSERT(cfg.check_imsi == 1);
2934
2935 err_msg = NULL;
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002936 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002937 OSMO_ASSERT(err_msg != NULL);
2938 OSMO_ASSERT(cfg.check_imsi == 0);
2939
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002940 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002941 OSMO_ASSERT(cfg.check_imsi == 1);
2942
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002943 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002944 OSMO_ASSERT(cfg.check_imsi == 0);
2945
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002946 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02002947 OSMO_ASSERT(cfg.check_imsi == 1);
2948
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002949 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02002950 OSMO_ASSERT(cfg.check_imsi == 0);
2951
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002952 peer = gbproxy_peer_alloc(&cfg, 20);
2953
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002954 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002955 OSMO_ASSERT(cfg.check_imsi == 1);
2956
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002957 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
2958 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002959 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002960 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002961 * case. */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002962 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2963 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2964 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2965 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2966 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002967
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002968 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002969 OSMO_ASSERT(cfg.check_imsi == 1);
2970
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02002971 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
2972 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
2973 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
2974 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
2975 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
2976 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
2977 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02002978
2979 /* TODO: Check correct length but wrong type with is_mi_tmsi */
2980
2981 gbproxy_peer_free(peer);
2982}
2983
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02002984static struct log_info_cat gprs_categories[] = {
2985 [DGPRS] = {
2986 .name = "DGPRS",
2987 .description = "GPRS Packet Service",
2988 .enabled = 1, .loglevel = LOGL_DEBUG,
2989 },
2990 [DNS] = {
2991 .name = "DNS",
2992 .description = "GPRS Network Service (NS)",
2993 .enabled = 1, .loglevel = LOGL_INFO,
2994 },
2995 [DBSSGP] = {
2996 .name = "DBSSGP",
2997 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2998 .enabled = 1, .loglevel = LOGL_DEBUG,
2999 },
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02003000};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02003001
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02003002static struct log_info info = {
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02003003 .cat = gprs_categories,
3004 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02003005};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02003006
3007int main(int argc, char **argv)
3008{
3009 osmo_init_logging(&info);
3010 log_set_use_color(osmo_stderr_target, 0);
3011 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02003012 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02003013
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02003014 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02003015 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3016 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02003017
3018 rate_ctr_init(NULL);
3019
3020 setlinebuf(stdout);
3021
3022 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther5eaf1a22014-08-04 11:10:09 +02003023 gbproxy_init_config(&gbcfg);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003024 test_tlv_shift_functions();
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02003025 test_gbproxy();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02003026 test_gbproxy_ident_changes();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02003027 test_gbproxy_imsi_matching();
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02003028 test_gbproxy_ra_patching();
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02003029 test_gbproxy_ptmsi_patching();
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02003030 test_gbproxy_imsi_acquisition();
Jacob Erlbeck12356062014-08-27 12:44:25 +02003031 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02003032 test_gbproxy_tlli_expire();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02003033 printf("===== GbProxy test END\n\n");
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02003034
3035 exit(EXIT_SUCCESS);
3036}