blob: 37b7c0743862b87e165da0bbf846bfe809c6e4fb [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 Erlbecka4b5e892014-09-22 18:54:34 +020036#include <openbsc/gprs_gb_parse.h>
37#include <openbsc/gsm_04_08_gprs.h>
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020038#include <openbsc/debug.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020039
40#define REMOTE_BSS_ADDR 0x01020304
41#define REMOTE_SGSN_ADDR 0x05060708
42
Jacob Erlbeck45017722013-10-18 13:04:47 +020043#define SGSN_NSEI 0x0100
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020044
Jacob Erlbeck12356062014-08-27 12:44:25 +020045#define REMOTE_SGSN2_ADDR 0x15161718
46#define SGSN2_NSEI 0x0102
47
Jacob Erlbecka4b5e892014-09-22 18:54:34 +020048#define MATCH_ANY (-1)
49
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020050struct gbproxy_config gbcfg = {0};
51
Jacob Erlbecka4b5e892014-09-22 18:54:34 +020052struct llist_head *received_messages = NULL;
53
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020054static int dump_global(FILE *stream, int indent)
55{
56 unsigned int i;
57 const struct rate_ctr_group_desc *desc;
58 int rc;
59
60 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
61 if (rc < 0)
62 return rc;
63
64 desc = gbcfg.ctrg->desc;
65
66 for (i = 0; i < desc->num_ctr; i++) {
67 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
68 if (ctr->current) {
69 rc = fprintf(stream, "%*s %s: %llu\n",
70 indent, "",
71 desc->ctr_desc[i].description,
72 (long long)ctr->current);
73
74 if (rc < 0)
75 return rc;
76 }
77 }
78
79 return 0;
80}
81
Jacob Erlbeckc404c082014-08-08 08:37:37 +020082static int dump_peers(FILE *stream, int indent, time_t now,
83 struct gbproxy_config *cfg)
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020084{
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020085 struct gbproxy_peer *peer;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020086 struct gprs_ra_id raid;
87 unsigned int i;
88 const struct rate_ctr_group_desc *desc;
89 int rc;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020090
91 rc = fprintf(stream, "%*sPeers:\n", indent, "");
92 if (rc < 0)
93 return rc;
94
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +020095 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +020096 struct gbproxy_link_info *link_info;
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020097 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020098 gsm48_parse_ra(&raid, peer->ra);
99
100 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
101 "RAI %u-%u-%u-%u\n",
102 indent, "",
103 peer->nsei, peer->bvci,
104 peer->blocked ? "" : "not ",
105 raid.mcc, raid.mnc, raid.lac, raid.rac);
106
107 if (rc < 0)
108 return rc;
109
110 desc = peer->ctrg->desc;
111
112 for (i = 0; i < desc->num_ctr; i++) {
113 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
114 if (ctr->current) {
115 rc = fprintf(stream, "%*s %s: %llu\n",
116 indent, "",
117 desc->ctr_desc[i].description,
118 (long long)ctr->current);
119
120 if (rc < 0)
121 return rc;
122 }
123 }
124
125 fprintf(stream, "%*s TLLI-Cache: %d\n",
Jacob Erlbeck485e28c2014-09-19 16:03:07 +0200126 indent, "", state->logical_link_count);
127 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200128 char mi_buf[200];
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200129 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200130 int stored_msgs = 0;
131 struct llist_head *iter;
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200132 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200133 stored_msgs++;
134
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200135 if (link_info->imsi_len > 0) {
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200136 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
137 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200138 link_info->imsi,
139 link_info->imsi_len);
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200140 } else {
141 snprintf(mi_buf, sizeof(mi_buf), "(none)");
142 }
Jacob Erlbeck31132872014-08-11 17:26:21 +0200143 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200144 indent, "", link_info->tlli.current);
145 if (link_info->tlli.assigned)
146 fprintf(stream, "/%08x", link_info->tlli.assigned);
147 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200148 fprintf(stream, " -> %08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200149 link_info->sgsn_tlli.current);
150 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200151 fprintf(stream, "/%08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200152 link_info->sgsn_tlli.assigned);
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200153 }
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200154 fprintf(stream, ", IMSI %s, AGE %d",
155 mi_buf, (int)age);
156
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200157 if (stored_msgs)
158 fprintf(stream, ", STORED %d", stored_msgs);
159
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200160 if (cfg->check_imsi && link_info->imsi_matches)
Jacob Erlbeck12356062014-08-27 12:44:25 +0200161 fprintf(stream, ", IMSI matches");
162
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200163 if (link_info->imsi_acq_pending)
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200164 fprintf(stream, ", IMSI acquisition in progress");
165
Jacob Erlbeckd918f522014-09-17 10:56:38 +0200166 if (cfg->route_to_sgsn2)
167 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200168 link_info->sgsn_nsei);
Jacob Erlbeckd918f522014-09-17 10:56:38 +0200169
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200170 if (link_info->is_deregistered)
Jacob Erlbeckf9038d92014-09-12 15:09:56 +0200171 fprintf(stream, ", DE-REGISTERED");
172
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200173 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200174 if (rc < 0)
175 return rc;
176 }
177 }
178
179 return 0;
180}
181
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +0200182const uint8_t *convert_ra(struct gprs_ra_id *raid)
183{
184 static uint8_t buf[6];
185 gsm48_construct_ra(buf, raid);
186 return buf;
187}
188
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200189/* DTAP - Attach Request */
190static const unsigned char dtap_attach_req[] = {
191 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
192 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
193 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
194 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
195 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
196 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200197};
198
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +0200199/* DTAP - Attach Request (invalid RAI) */
200static const unsigned char dtap_attach_req2[] = {
201 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
202 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
203 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
204 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
205 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
206 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
207};
208
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200209/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
210static const unsigned char dtap_attach_req3[] = {
211 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
212 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
213 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
214 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
215 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
216 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
217};
218
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200219/* DTAP - Identity Request */
220static const unsigned char dtap_identity_req[] = {
221 0x08, 0x15, 0x01
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200222};
223
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200224/* DTAP - Identity Response */
225static const unsigned char dtap_identity_resp[] = {
226 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
227 0x16, 0x17, 0x18
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200228};
229
Jacob Erlbeck12356062014-08-27 12:44:25 +0200230/* DTAP - Identity Response, IMSI 2 */
231static const unsigned char dtap_identity2_resp[] = {
232 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
233 0x16, 0x17, 0x18
234};
235
Jacob Erlbeckd1056b32014-09-17 12:09:25 +0200236/* DTAP - Identity Response, IMSI 3 */
237static const unsigned char dtap_identity3_resp[] = {
238 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
239 0x26, 0x27, 0x28
240};
241
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200242/* DTAP - Attach Accept */
243static const unsigned char dtap_attach_acc[] = {
244 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
245 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
246 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200247};
248
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200249/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeck12356062014-08-27 12:44:25 +0200250static const unsigned char dtap_attach_acc2[] = {
251 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
252 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
253 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
254};
255
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200256/* DTAP - Attach Complete */
257static const unsigned char dtap_attach_complete[] = {
258 0x08, 0x03
Jacob Erlbeck31132872014-08-11 17:26:21 +0200259};
260
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +0200261/* DTAP - Attach Reject (GPRS services not allowed) */
262static const unsigned char dtap_attach_rej7[] = {
263 0x08, 0x04, 0x07
264};
265
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200266/* DTAP - GMM Information */
267static const unsigned char dtap_gmm_information[] = {
268 0x08, 0x21
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200269};
270
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200271/* DTAP - Routing Area Update Request */
272static const unsigned char dtap_ra_upd_req[] = {
273 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
274 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
275 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
276 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
277 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
278 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
279 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200280};
281
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200282/* DTAP - Routing Area Update Accept */
283static const unsigned char dtap_ra_upd_acc[] = {
284 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
285 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
286 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200287};
288
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200289/* DTAP - Routing Area Update Accept, P-TMSI 2 */
290static const unsigned char dtap_ra_upd_acc2[] = {
291 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
292 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
293 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
294};
295
296/* DTAP - Routing Area Update Accept, P-TMSI 3 */
297static const unsigned char dtap_ra_upd_acc3[] = {
298 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
299 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
300 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
301};
302
303/* DTAP - Routing Area Update Complete */
304static const unsigned char dtap_ra_upd_complete[] = {
305 0x08, 0x0a
306};
307
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200308/* DTAP - Routing Area Update Reject */
309/* cause = 10 ("Implicitly detached"), force_standby = 0 */
310static const unsigned char dtap_ra_upd_rej[] = {
311 0x08, 0x0b, 0x0a, 0x00,
312};
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200313
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200314/* DTAP - Activate PDP Context Request */
315static const unsigned char dtap_act_pdp_ctx_req[] = {
316 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200317 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
319 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
320 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
321 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200322 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200323};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200324
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200325/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200326/* normal detach, power_off = 1 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200327static const unsigned char dtap_detach_po_req[] = {
328 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
329 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200330};
331
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200332/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200333/* normal detach, power_off = 0 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200334static const unsigned char dtap_detach_req[] = {
335 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
336 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200337};
338
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200339/* DTAP - Detach Accept (MO) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200340static const unsigned char dtap_detach_acc[] = {
341 0x08, 0x06, 0x00
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200342};
343
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200344/* DTAP - Detach Request (MT) */
345/* normal detach, reattach required, implicitly detached */
346static const unsigned char dtap_mt_detach_rea_req[] = {
347 0x08, 0x05, 0x01, 0x25, 0x0a
348};
349
350/* DTAP - Detach Request (MT) */
351/* normal detach, reattach not required, implicitly detached */
352static const unsigned char dtap_mt_detach_req[] = {
353 0x08, 0x05, 0x02, 0x25, 0x0a
354};
355
356/* DTAP - Detach Accept (MT) */
357static const unsigned char dtap_mt_detach_acc[] = {
358 0x08, 0x06
359};
360
Jacob Erlbeck70e00de2014-08-15 17:20:06 +0200361/* GPRS-LLC - SAPI: LLGMM, U, XID */
362static const unsigned char llc_u_xid_ul[] = {
363 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
364 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
365};
366
367/* GPRS-LLC - SAPI: LLGMM, U, XID */
368static const unsigned char llc_u_xid_dl[] = {
369 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
370 0xe4, 0xa9, 0x1a, 0x9e
371};
372
373/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
374static const unsigned char llc_ui_ll11_dns_query_ul[] = {
375 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
376 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
377 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
378 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
379 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
380 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
381 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
382 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
383 0x8f, 0x07
384};
385
386/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
387static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
388 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
389 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
390 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
391 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
392 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
393 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
394 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
395 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
396 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
397 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
398 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
399 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
400 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
401 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
402 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
403 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
404 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
405 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
406 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
407 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
408 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
409 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
410 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
411 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
412 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
413 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
414};
415
Jacob Erlbeck45017722013-10-18 13:04:47 +0200416static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
417 struct sockaddr_in *peer, const unsigned char* data,
418 size_t data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200419
420static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
421 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
422{
423 /* GPRS Network Service, PDU type: NS_RESET,
424 */
425 unsigned char msg[12] = {
426 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
427 0x04, 0x82, 0x11, 0x22
428 };
429
430 msg[3] = cause;
431 msg[6] = nsvci / 256;
432 msg[7] = nsvci % 256;
433 msg[10] = nsei / 256;
434 msg[11] = nsei % 256;
435
436 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
437}
438
Jacob Erlbeck45017722013-10-18 13:04:47 +0200439static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
440 uint16_t nsvci, uint16_t nsei)
441{
442 /* GPRS Network Service, PDU type: NS_RESET_ACK,
443 */
444 unsigned char msg[9] = {
445 0x03, 0x01, 0x82, 0x11, 0x22,
446 0x04, 0x82, 0x11, 0x22
447 };
448
449 msg[3] = nsvci / 256;
450 msg[4] = nsvci % 256;
451 msg[7] = nsei / 256;
452 msg[8] = nsei % 256;
453
454 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
455}
456
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200457static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
458{
459 /* GPRS Network Service, PDU type: NS_ALIVE */
460 unsigned char msg[1] = {
461 0x0a
462 };
463
464 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
465}
466
467static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
468{
469 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
470 unsigned char msg[1] = {
471 0x0b
472 };
473
474 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
475}
476
477static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
478{
479 /* GPRS Network Service, PDU type: NS_UNBLOCK */
480 unsigned char msg[1] = {
481 0x06
482 };
483
484 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
485}
486
Jacob Erlbeck45017722013-10-18 13:04:47 +0200487static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
488{
489 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
490 unsigned char msg[1] = {
491 0x07
492 };
493
494 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
495}
496
497static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
498 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200499 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
500{
501 /* GPRS Network Service, PDU type: NS_UNITDATA */
502 unsigned char msg[4096] = {
503 0x00, 0x00, 0x00, 0x00
504 };
505
506 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
507
508 msg[2] = nsbvci / 256;
509 msg[3] = nsbvci % 256;
510 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
511
Jacob Erlbeck45017722013-10-18 13:04:47 +0200512 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200513}
514
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200515static void send_bssgp_ul_unitdata(
516 struct gprs_ns_inst *nsi, const char *text,
517 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
518 struct gprs_ra_id *raid, uint16_t cell_id,
519 const uint8_t *llc_msg, size_t llc_msg_size)
520{
521 /* GPRS Network Service, PDU type: NS_UNITDATA */
522 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
523 unsigned char msg[4096] = {
524 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
525 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
526 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
527 };
528
529 size_t bssgp_msg_size = 23 + llc_msg_size;
530
531 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
532
533 gsm48_construct_ra(msg + 10, raid);
534 msg[1] = (uint8_t)(tlli >> 24);
535 msg[2] = (uint8_t)(tlli >> 16);
536 msg[3] = (uint8_t)(tlli >> 8);
537 msg[4] = (uint8_t)(tlli >> 0);
538 msg[16] = cell_id / 256;
539 msg[17] = cell_id % 256;
540 msg[21] = llc_msg_size / 256;
541 msg[22] = llc_msg_size % 256;
542 memcpy(msg + 23, llc_msg, llc_msg_size);
543
544 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
545 src_addr, nsbvci, msg, bssgp_msg_size);
546}
547
548static void send_bssgp_dl_unitdata(
549 struct gprs_ns_inst *nsi, const char *text,
550 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
551 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
552 const uint8_t *llc_msg, size_t llc_msg_size)
553{
554 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
555 unsigned char msg[4096] = {
556 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
557 0x16, 0x82, 0x02, 0x58,
558 };
559 unsigned char racap_drx[] = {
560 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
561 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
562 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
563 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
564 };
565
566 size_t bssgp_msg_size = 0;
567
568 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
569
570 msg[1] = (uint8_t)(tlli >> 24);
571 msg[2] = (uint8_t)(tlli >> 16);
572 msg[3] = (uint8_t)(tlli >> 8);
573 msg[4] = (uint8_t)(tlli >> 0);
574
575 bssgp_msg_size = 12;
576
577 if (with_racap_drx) {
578 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
579 bssgp_msg_size += sizeof(racap_drx);
580 }
581
582 if (imsi) {
583 OSMO_ASSERT(imsi_size <= 127);
584 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
585 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
586 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
587 bssgp_msg_size += 2 + imsi_size;
588 }
589
590 if ((bssgp_msg_size % 4) != 0) {
591 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
592 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
593 msg[bssgp_msg_size + 1] = 0x80 | abytes;
594 memset(msg + bssgp_msg_size + 2, 0, abytes);
595 bssgp_msg_size += 2 + abytes;
596 }
597
598 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
599 if (llc_msg_size < 128) {
600 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
601 bssgp_msg_size += 2;
602 } else {
603 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
604 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
605 bssgp_msg_size += 3;
606 }
607 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
608 bssgp_msg_size += llc_msg_size;
609
610
611 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
612 src_addr, nsbvci, msg, bssgp_msg_size);
613}
614
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200615static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
616 uint16_t bvci)
617{
618 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
619 * BSSGP RESET */
Jacob Erlbeck8a600ae2014-08-06 12:38:10 +0200620 unsigned char msg[18] = {
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200621 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeck3f086322014-06-02 10:48:59 +0200622 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
623 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200624 };
625
626 msg[3] = bvci / 256;
627 msg[4] = bvci % 256;
628
Jacob Erlbeck45017722013-10-18 13:04:47 +0200629 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
630}
631
632static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
633 struct sockaddr_in *src_addr, uint16_t bvci)
634{
635 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
636 * BSSGP RESET_ACK */
637 static unsigned char msg[5] = {
638 0x23, 0x04, 0x82, 0x00,
639 0x00
640 };
641
642 msg[3] = bvci / 256;
643 msg[4] = bvci % 256;
644
645 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200646}
647
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200648static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
649 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200650 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200651 struct gprs_ra_id *raid)
652{
653 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
654 unsigned char msg[15] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200655 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
656 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200657 };
658
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200659 msg[3] = (uint8_t)(tlli >> 24);
660 msg[4] = (uint8_t)(tlli >> 16);
661 msg[5] = (uint8_t)(tlli >> 8);
662 msg[6] = (uint8_t)(tlli >> 0);
663
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200664 gsm48_construct_ra(msg + 9, raid);
665
666 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
667}
668
669static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
670 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200671 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200672 struct gprs_ra_id *raid)
673{
674 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
675 unsigned char msg[18] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200676 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
677 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200678 0x81, 0x01
679 };
680
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200681 msg[3] = (uint8_t)(tlli >> 24);
682 msg[4] = (uint8_t)(tlli >> 16);
683 msg[5] = (uint8_t)(tlli >> 8);
684 msg[6] = (uint8_t)(tlli >> 0);
685
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200686 gsm48_construct_ra(msg + 9, raid);
687
688 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
689}
690
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200691static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
692 struct sockaddr_in *src_addr,
693 uint16_t bvci, uint32_t tlli,
694 unsigned n_frames, unsigned n_octets)
695{
696 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
697 unsigned char msg[] = {
698 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
699 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
700 /* n octets */ 0xff, 0xff, 0xff
701 };
702
703 msg[3] = (uint8_t)(tlli >> 24);
704 msg[4] = (uint8_t)(tlli >> 16);
705 msg[5] = (uint8_t)(tlli >> 8);
706 msg[6] = (uint8_t)(tlli >> 0);
707 msg[9] = (uint8_t)(n_frames);
708 msg[12] = (uint8_t)(bvci >> 8);
709 msg[13] = (uint8_t)(bvci >> 0);
710 msg[16] = (uint8_t)(n_octets >> 16);
711 msg[17] = (uint8_t)(n_octets >> 8);
712 msg[18] = (uint8_t)(n_octets >> 0);
713
714 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
715}
716
Jacob Erlbeck12356062014-08-27 12:44:25 +0200717static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
718 struct sockaddr_in *src_addr,
719 uint16_t bvci, uint8_t tag)
720{
721 /* GPRS Network Service, PDU type: NS_UNITDATA,
722 * BSSGP FLOW_CONTROL_BVC */
723 unsigned char msg[] = {
724 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
725 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
726 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
727 };
728
729 msg[3] = tag;
730
731 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
732 msg, sizeof(msg));
733}
734
735static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
736 struct sockaddr_in *src_addr,
737 uint16_t bvci, uint8_t tag)
738{
739 /* GPRS Network Service, PDU type: NS_UNITDATA,
740 * BSSGP FLOW_CONTROL_BVC_ACK */
741 unsigned char msg[] = {
742 0x27, 0x1e, 0x81, /* Tag */ 0xce
743 };
744
745 msg[3] = tag;
746
747 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
748 msg, sizeof(msg));
749}
750
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200751static void send_llc_ul_ui(
752 struct gprs_ns_inst *nsi, const char *text,
753 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
754 struct gprs_ra_id *raid, uint16_t cell_id,
755 unsigned sapi, unsigned nu,
756 const uint8_t *msg, size_t msg_size)
757{
758 unsigned char llc_msg[4096] = {
759 0x00, 0xc0, 0x01
760 };
761
762 size_t llc_msg_size = 3 + msg_size + 3;
763 uint8_t e_bit = 0;
764 uint8_t pm_bit = 1;
765 unsigned fcs;
766
767 nu &= 0x01ff;
768
769 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
770
771 llc_msg[0] = (sapi & 0x0f);
772 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
773 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
774
775 memcpy(llc_msg + 3, msg, msg_size);
776
777 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
778 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
779 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
780 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
781
782 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
783 src_addr, nsbvci, tlli, raid, cell_id,
784 llc_msg, llc_msg_size);
785}
786
787static void send_llc_dl_ui(
788 struct gprs_ns_inst *nsi, const char *text,
789 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
790 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
791 unsigned sapi, unsigned nu,
792 const uint8_t *msg, size_t msg_size)
793{
794 /* GPRS Network Service, PDU type: NS_UNITDATA */
795 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
796 unsigned char llc_msg[4096] = {
797 0x00, 0x00, 0x01
798 };
799
800 size_t llc_msg_size = 3 + msg_size + 3;
801 uint8_t e_bit = 0;
802 uint8_t pm_bit = 1;
803 unsigned fcs;
804
805 nu &= 0x01ff;
806
807 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
808
809 llc_msg[0] = 0x40 | (sapi & 0x0f);
810 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
811 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
812
813 memcpy(llc_msg + 3, msg, msg_size);
814
815 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
816 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
817 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
818 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
819
820 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
821 src_addr, nsbvci, tlli,
822 with_racap_drx, imsi, imsi_size,
823 llc_msg, llc_msg_size);
824}
825
826
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200827static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
828 uint16_t nsvci, uint16_t nsei)
829{
830 printf("Setup NS-VC: remote 0x%08x:%d, "
831 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
832 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
833 nsvci, nsvci, nsei, nsei);
834
835 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
836 send_ns_alive(nsi, src_addr);
837 send_ns_unblock(nsi, src_addr);
838 send_ns_alive_ack(nsi, src_addr);
839}
840
841static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
842 uint16_t bvci)
843{
844 printf("Setup BSSGP: remote 0x%08x:%d, "
845 "BVCI 0x%04x(%d)\n\n",
846 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
847 bvci, bvci);
848
849 send_bssgp_reset(nsi, src_addr, bvci);
850}
851
Jacob Erlbeck12356062014-08-27 12:44:25 +0200852static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
853 uint32_t sgsn_nsei)
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200854{
Jacob Erlbeck12356062014-08-27 12:44:25 +0200855 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
856 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200857 send_ns_alive_ack(nsi, sgsn_peer);
858 send_ns_unblock_ack(nsi, sgsn_peer);
859 send_ns_alive(nsi, sgsn_peer);
860}
861
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200862static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
863{
864 sgsn_peer->sin_family = AF_INET;
865 sgsn_peer->sin_port = htons(32000);
866 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
867}
868
Jacob Erlbeck12356062014-08-27 12:44:25 +0200869static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
870{
871 sgsn_peer->sin_family = AF_INET;
872 sgsn_peer->sin_port = htons(32001);
873 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
874}
875
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200876static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
877{
878 size_t i;
879
880 for (i = 0; i < size; ++i) {
881 bss_peers[i].sin_family = AF_INET;
882 bss_peers[i].sin_port = htons((i + 1) * 1111);
883 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
884 }
885}
886
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200887int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
888 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
889
890/* override */
891int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
892 struct msgb *msg, uint16_t bvci)
893{
894 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
895 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200896 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200897
898 switch (event) {
899 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200900 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200901 default:
902 break;
903 }
904 return 0;
905}
906
907/* override */
908ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
909 const struct sockaddr *dest_addr, socklen_t addrlen)
910{
911 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
912 const struct sockaddr *, socklen_t);
913 static sendto_t real_sendto = NULL;
914 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200915 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200916
917 if (!real_sendto)
918 real_sendto = dlsym(RTLD_NEXT, "sendto");
919
920 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200921 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
922 dest_host, dest_port,
923 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200924 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200925 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
926 dest_host, dest_port,
927 len, osmo_hexdump(buf, len));
Jacob Erlbeck12356062014-08-27 12:44:25 +0200928 else if (dest_host == REMOTE_SGSN2_ADDR)
929 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
930 dest_host, dest_port,
931 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200932 else
933 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
934
935 return len;
936}
937
938/* override */
939int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
940{
Jacob Erlbeck45017722013-10-18 13:04:47 +0200941 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
942 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200943 uint16_t bvci = msgb_bvci(msg);
944 uint16_t nsei = msgb_nsei(msg);
945
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200946 size_t len = msgb_length(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200947
Jacob Erlbeck45017722013-10-18 13:04:47 +0200948 if (!real_gprs_ns_sendmsg)
949 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
950
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200951 if (nsei == SGSN_NSEI)
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200952 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
953 "msg length %d (%s)\n",
954 bvci, len, __func__);
Jacob Erlbeck12356062014-08-27 12:44:25 +0200955 else if (nsei == SGSN2_NSEI)
956 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
957 "msg length %d (%s)\n",
958 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200959 else
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200960 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
961 "msg length %d (%s)\n",
962 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200963
Jacob Erlbecka4b5e892014-09-22 18:54:34 +0200964 if (received_messages) {
965 struct msgb *msg_copy;
966 msg_copy = gprs_msgb_copy(msg, "received_messages");
967 llist_add_tail(&msg_copy->list, received_messages);
968 }
969
Jacob Erlbeck45017722013-10-18 13:04:47 +0200970 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200971}
972
Jacob Erlbecka4b5e892014-09-22 18:54:34 +0200973/* Get the next message from the receive FIFO
974 *
975 * \returns a pointer to the message which will be invalidated at the next call
976 * to expect_msg. Returns NULL, if there is no message left.
977 */
978static struct msgb *expect_msg(void)
979{
980 static struct msgb *msg = NULL;
981
982 msgb_free(msg);
983 msg = NULL;
984
985 if (!received_messages)
986 return NULL;
987
988 if (llist_empty(received_messages))
989 return NULL;
990
991 msg = llist_entry(received_messages->next, struct msgb, list);
992 llist_del(&msg->list);
993
994 return msg;
995}
996
997struct expect_result {
998 struct msgb *msg;
999 struct gprs_gb_parse_context parse_ctx;
1000};
1001
1002static struct expect_result *expect_bssgp_msg(
1003 int match_nsei, int match_bvci, int match_pdu_type)
1004{
1005 static struct expect_result result;
1006 static const struct expect_result empty_result = {0,};
1007 static struct msgb *msg;
1008 uint16_t nsei;
1009 int rc;
1010
1011 memcpy(&result, &empty_result, sizeof(result));
1012
1013 msg = expect_msg();
1014 if (!msg)
1015 return NULL;
1016
1017 nsei = msgb_nsei(msg);
1018
1019 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1020 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1021 __func__, match_nsei, nsei);
1022 return NULL;
1023 }
1024
1025 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1026 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1027 __func__, match_bvci, msgb_bvci(msg));
1028 return NULL;
1029 }
1030
1031 result.msg = msg;
1032
1033 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1034 result.parse_ctx.peer_nsei = nsei;
1035
1036 if (!msgb_bssgph(msg)) {
1037 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1038 return NULL;
1039 }
1040
1041 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1042 &result.parse_ctx);
1043
1044 if (!rc) {
1045 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1046 return NULL;
1047 }
1048
1049 if (match_pdu_type != MATCH_ANY &&
1050 match_pdu_type != result.parse_ctx.pdu_type) {
1051 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1052 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1053 return NULL;
1054 }
1055
1056 return &result;
1057}
1058
1059static struct expect_result *expect_llc_msg(
1060 int match_nsei, int match_bvci, int match_sapi, int match_type)
1061{
1062 static struct expect_result *result;
1063
1064 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1065 if (!result)
1066 return NULL;
1067
1068 if (!result->parse_ctx.llc) {
1069 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1070 return NULL;
1071 }
1072
1073 if (match_sapi != MATCH_ANY &&
1074 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1075 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1076 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1077 return NULL;
1078 }
1079
1080 if (match_type != MATCH_ANY &&
1081 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1082 fprintf(stderr,
1083 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1084 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1085 return NULL;
1086 }
1087
1088 return result;
1089}
1090
1091static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1092 int match_type)
1093{
1094 static struct expect_result *result;
1095
1096 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1097 if (!result)
1098 return NULL;
1099
1100 if (!result->parse_ctx.g48_hdr) {
1101 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1102 return NULL;
1103 }
1104
1105 if (match_type != MATCH_ANY &&
1106 match_type != result->parse_ctx.g48_hdr->msg_type) {
1107 fprintf(stderr,
1108 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1109 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1110 return NULL;
1111 }
1112
1113 return result;
1114}
1115
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001116static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1117 struct rate_ctr_group *ctrg)
1118{
1119 unsigned int i;
1120
1121 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1122 struct rate_ctr *ctr = &ctrg->ctr[i];
1123 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1124 fprintf(stream, " %s%s: %llu%s",
1125 prefix, ctrg->desc->ctr_desc[i].description,
1126 (long long)ctr->current,
1127 "\n");
1128 };
1129}
1130
1131/* Signal handler for signals from NS layer */
1132static int test_signal(unsigned int subsys, unsigned int signal,
1133 void *handler_data, void *signal_data)
1134{
1135 struct ns_signal_data *nssd = signal_data;
1136 int rc;
1137
1138 if (subsys != SS_L_NS)
1139 return 0;
1140
1141 switch (signal) {
1142 case S_NS_RESET:
1143 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1144 nssd->nsvc->nsvci,
1145 gprs_ns_ll_str(nssd->nsvc));
1146 break;
1147
1148 case S_NS_ALIVE_EXP:
1149 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1150 nssd->nsvc->nsvci,
1151 gprs_ns_ll_str(nssd->nsvc));
1152 break;
1153
1154 case S_NS_BLOCK:
1155 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1156 nssd->nsvc->nsvci,
1157 gprs_ns_ll_str(nssd->nsvc));
1158 break;
1159
1160 case S_NS_UNBLOCK:
1161 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1162 nssd->nsvc->nsvci,
1163 gprs_ns_ll_str(nssd->nsvc));
1164 break;
1165
1166 case S_NS_REPLACED:
1167 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1168 nssd->nsvc->nsvci,
1169 gprs_ns_ll_str(nssd->nsvc));
1170 printf(" -> 0x%04x/%s\n",
1171 nssd->old_nsvc->nsvci,
1172 gprs_ns_ll_str(nssd->old_nsvc));
1173 break;
1174
1175 default:
1176 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1177 nssd->nsvc->nsvci,
1178 gprs_ns_ll_str(nssd->nsvc));
1179 break;
1180 }
1181 printf("\n");
1182 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1183 return rc;
1184}
1185
1186static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1187{
1188 struct msgb *msg;
1189 int ret;
1190 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
1191 fprintf(stderr, "message too long: %d\n", data_len);
1192 return -1;
1193 }
1194
1195 msg = gprs_ns_msgb_alloc();
1196 memmove(msg->data, data, data_len);
1197 msg->l2h = msg->data;
1198 msgb_put(msg, data_len);
1199
1200 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1201 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1202 osmo_hexdump(data, data_len));
1203
1204 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1205
1206 printf("result (%s) = %d\n\n", text, ret);
1207
1208 msgb_free(msg);
1209
1210 return ret;
1211}
1212
1213static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1214{
1215 struct gprs_nsvc *nsvc;
1216
1217 printf("Current NS-VCIs:\n");
1218 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1219 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001220 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001221 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck45017722013-10-18 13:04:47 +02001222 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1223 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1224 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001225 );
1226 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1227 }
1228 printf("\n");
1229}
1230
1231static void test_gbproxy()
1232{
1233 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1234 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck45017722013-10-18 13:04:47 +02001235 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001236
1237 bssgp_nsi = nsi;
1238 gbcfg.nsi = bssgp_nsi;
1239 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1240
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001241 configure_sgsn_peer(&sgsn_peer);
1242 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001243
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001244 printf("=== %s ===\n", __func__);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001245 printf("--- Initialise SGSN ---\n\n");
1246
Jacob Erlbeck12356062014-08-27 12:44:25 +02001247 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001248 gprs_dump_nsi(nsi);
1249
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001250 printf("--- Initialise BSS 1 ---\n\n");
1251
1252 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1253 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1254 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001255 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001256
Jacob Erlbeck45017722013-10-18 13:04:47 +02001257 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1258
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001259 printf("--- Initialise BSS 2 ---\n\n");
1260
1261 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1262 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1263 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001264 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001265
Jacob Erlbeck45017722013-10-18 13:04:47 +02001266 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1267
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001268 printf("--- Move BSS 1 to new port ---\n\n");
1269
1270 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1271 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001272 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001273
1274 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1275
1276 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1277 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001278 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001279
1280 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1281
1282 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1283 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001284 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001285
1286 printf("--- Move BSS 2 to new port ---\n\n");
1287
1288 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1289 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001290 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001291
1292 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1293
1294 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1295 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001296 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001297
Jacob Erlbeck45017722013-10-18 13:04:47 +02001298 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1299
1300 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1301 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001302 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001303
1304 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1305
1306 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1307 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001308 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001309
1310 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1311
1312 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1313
1314 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1315 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001316 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001317
1318 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1319
1320 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1321
1322 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1323 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001324 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001325
1326 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1327
1328 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1329
1330 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1331
1332 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1333
1334 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1335
1336 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1337
1338 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1339
1340 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1341
1342 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1343
1344 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1345
1346 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1347
1348 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1349
1350 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1351
1352 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1353
1354 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1355 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001356 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001357
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001358 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001359
Jacob Erlbeck45017722013-10-18 13:04:47 +02001360 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1361
1362 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1363
1364 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1365
1366 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1367
1368 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1369
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001370 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1371
1372 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1373
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02001374 /* Find peer */
1375 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1376 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1377 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1378 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1379 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1380 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1381
1382
1383 /* Cleanup */
1384 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1385 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1386 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1387 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1388 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1389
1390 dump_peers(stdout, 0, 0, &gbcfg);
1391
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001392 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001393
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001394 gbprox_reset(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001395 gprs_ns_destroy(nsi);
1396 nsi = NULL;
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001397}
1398
1399static void test_gbproxy_ident_changes()
1400{
1401 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1402 struct sockaddr_in bss_peer[1] = {{0},};
1403 struct sockaddr_in sgsn_peer= {0};
1404 uint16_t nsei[2] = {0x1000, 0x2000};
1405 uint16_t nsvci[2] = {0x1001, 0x2001};
1406 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1407
1408 bssgp_nsi = nsi;
1409 gbcfg.nsi = bssgp_nsi;
1410 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1411
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001412 configure_sgsn_peer(&sgsn_peer);
1413 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001414
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001415 printf("=== %s ===\n", __func__);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001416 printf("--- Initialise SGSN ---\n\n");
1417
Jacob Erlbeck12356062014-08-27 12:44:25 +02001418 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001419 gprs_dump_nsi(nsi);
1420
1421 printf("--- Initialise BSS 1 ---\n\n");
1422
1423 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1424 gprs_dump_nsi(nsi);
1425
1426 printf("--- Setup BVCI 1 ---\n\n");
1427
1428 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1429 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001430 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001431
1432 printf("--- Setup BVCI 2 ---\n\n");
1433
1434 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1435 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001436 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001437
1438 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1439
1440 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1441 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1442
1443 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1444
1445 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1446 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1447
1448 printf("--- Change NSEI ---\n\n");
1449
1450 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1451 gprs_dump_nsi(nsi);
1452
1453 printf("--- Setup BVCI 1 ---\n\n");
1454
1455 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1456 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001457 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001458
1459 printf("--- Setup BVCI 3 ---\n\n");
1460
1461 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1462 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001463 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001464
1465 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1466
1467 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1468 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1469
1470 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1471 " (should fail) ---\n\n");
1472
1473 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001474 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001475 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001476 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001477
1478 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1479
1480 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1481 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1482
1483 printf("--- Change NSVCI ---\n\n");
1484
1485 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1486 gprs_dump_nsi(nsi);
1487
1488 printf("--- Setup BVCI 1 ---\n\n");
1489
1490 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1491 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001492 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001493
1494 printf("--- Setup BVCI 4 ---\n\n");
1495
1496 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1497 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001498 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001499
1500 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1501
1502 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1503 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1504
1505 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1506 " (should fail) ---\n\n");
1507
1508 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001509 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001510 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001511 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001512
1513 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1514
1515 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1516 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1517
1518 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1519
1520 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1521 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1522
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001523 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001524 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001525
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001526 gbprox_reset(&gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001527 gprs_ns_destroy(nsi);
1528 nsi = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001529}
1530
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001531static void test_gbproxy_ra_patching()
1532{
1533 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1534 struct sockaddr_in bss_peer[1] = {{0},};
1535 struct sockaddr_in sgsn_peer= {0};
1536 struct gprs_ra_id rai_bss =
1537 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1538 struct gprs_ra_id rai_sgsn =
1539 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1540 struct gprs_ra_id rai_unknown =
1541 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001542 uint16_t cell_id = 0x7530;
Jacob Erlbeck43037632014-06-06 18:49:23 +02001543 const char *err_msg = NULL;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001544 const uint32_t ptmsi = 0xefe2b700;
1545 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001546 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02001547 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001548 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001549 struct gbproxy_link_info *link_info;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001550 struct gbproxy_peer *peer;
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001551 LLIST_HEAD(rcv_list);
1552 struct expect_result *er;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001553
1554 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001555
1556 bssgp_nsi = nsi;
1557 gbcfg.nsi = bssgp_nsi;
1558 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck2504bc42014-05-19 10:14:58 +02001559 gbcfg.core_mcc = 123;
1560 gbcfg.core_mnc = 456;
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001561 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freyther2d10ad12014-08-04 14:22:13 +02001562 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001563 gbcfg.patch_ptmsi = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001564
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001565 configure_sgsn_peer(&sgsn_peer);
1566 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001567
Jacob Erlbeck43037632014-06-06 18:49:23 +02001568 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02001569 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck43037632014-06-06 18:49:23 +02001570 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1571 gbcfg.match_re, err_msg);
1572 exit(1);
1573 }
1574
1575
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001576 printf("=== %s ===\n", __func__);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001577 printf("--- Initialise SGSN ---\n\n");
1578
Jacob Erlbeck12356062014-08-27 12:44:25 +02001579 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001580 gprs_dump_nsi(nsi);
1581
1582 printf("--- Initialise BSS 1 ---\n\n");
1583
1584 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001585
1586 received_messages = &rcv_list;
1587
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001588 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1589 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001590 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001591
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001592 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001593 OSMO_ASSERT(peer != NULL);
1594
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001595 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1596
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001597 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1598
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001599 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1600
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001601 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001602
1603 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1604
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001605 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001606
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001607 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1608
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001609 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001610 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001611
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001612 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1613 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1614
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001615 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1616
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001617 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1618 foreign_tlli, &rai_bss, cell_id,
1619 GPRS_SAPI_GMM, 0,
1620 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001621
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001622 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001623 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001624
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001625 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1626 foreign_tlli, 0, NULL, 0,
1627 GPRS_SAPI_GMM, 0,
1628 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001629
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001630 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1631
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001632 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1633 foreign_tlli, &rai_bss, cell_id,
1634 GPRS_SAPI_GMM, 3,
1635 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001636
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001637 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1638
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001639 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1640 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1641
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001642 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1643 foreign_tlli, 1, imsi, sizeof(imsi),
1644 GPRS_SAPI_GMM, 1,
1645 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001646
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001647 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1648
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001649 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1650
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02001651 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1652 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1653 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1654
1655 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1656 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1657 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1658
1659 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1660 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1661 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1662
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001663 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1664 OSMO_ASSERT(link_info);
1665 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1666 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1667 OSMO_ASSERT(!link_info->tlli.bss_validated);
1668 OSMO_ASSERT(!link_info->tlli.net_validated);
1669 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1670 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1671 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1672 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001673
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001674 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1675 local_tlli, &rai_bss, cell_id,
1676 GPRS_SAPI_GMM, 4,
1677 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck31132872014-08-11 17:26:21 +02001678
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001679 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1680
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001681 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1682
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001683 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1684 OSMO_ASSERT(link_info);
1685 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1686 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1687 OSMO_ASSERT(link_info->tlli.bss_validated);
1688 OSMO_ASSERT(!link_info->tlli.net_validated);
1689 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1690 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1691 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1692 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001693
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001694 /* Replace APN (1) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001695 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1696 local_tlli, &rai_bss, cell_id,
1697 GPRS_SAPI_GMM, 3,
1698 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001699
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001700 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1701
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001702 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1703
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001704 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1705 OSMO_ASSERT(link_info);
1706 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1707 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1708 OSMO_ASSERT(link_info->tlli.bss_validated);
1709 OSMO_ASSERT(!link_info->tlli.net_validated);
1710 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1711 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1712 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1713 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001714
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001715 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1716 local_tlli, 1, imsi, sizeof(imsi),
1717 GPRS_SAPI_GMM, 2,
1718 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeckab7366f2014-06-06 18:47:36 +02001719
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001720 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1721
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001722 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1723
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001724 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1725 OSMO_ASSERT(link_info);
1726 OSMO_ASSERT(link_info->tlli.assigned == 0);
1727 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1728 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1729 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001730
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001731 /* Replace APN (2) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001732 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1733 local_tlli, &rai_bss, cell_id,
1734 GPRS_SAPI_GMM, 3,
1735 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001736
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001737 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1738 OSMO_ASSERT(er->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
1739
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001740 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1741
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001742 gbcfg.core_apn[0] = 0;
1743 gbcfg.core_apn_size = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001744
1745 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001746 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1747 local_tlli, &rai_bss, cell_id,
1748 GPRS_SAPI_GMM, 3,
1749 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001750
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001751 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1752 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1753
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001754 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1755
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001756 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001757
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001758 /* Detach */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001759 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1760 local_tlli, &rai_bss, cell_id,
1761 GPRS_SAPI_GMM, 6,
1762 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001763
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001764 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1765
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001766 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1767 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1768
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001769 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1770 local_tlli, 1, imsi, sizeof(imsi),
1771 GPRS_SAPI_GMM, 5,
1772 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001773
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001774 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1775
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001776 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001777
1778 printf("--- RA update ---\n\n");
1779
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001780 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1781 foreign_tlli, &rai_bss, 0x7080,
1782 GPRS_SAPI_GMM, 5,
1783 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001784
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001785 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1786
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001787 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1788
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001789 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1790 foreign_tlli, 1, imsi, sizeof(imsi),
1791 GPRS_SAPI_GMM, 6,
1792 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001793
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001794 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1795
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001796 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1797
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001798 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001799 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1800 local_tlli, &rai_bss, cell_id,
1801 GPRS_SAPI_GMM, 3,
1802 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001803
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001804 OSMO_ASSERT(er = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1805 OSMO_ASSERT(er->parse_ctx.apn_ie_len == 0);
1806
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001807 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1808
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001809 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001810
Jacob Erlbeckf95340d2014-08-11 15:07:37 +02001811 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001812 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1813 local_tlli, &rai_bss, cell_id,
1814 GPRS_SAPI_GMM, 6,
1815 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001816
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001817 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1818
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001819 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1820
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001821 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001822 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001823
1824 printf("--- Bad cases ---\n\n");
1825
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02001826 /* The RAI in the Attach Request message differs from the RAI in the
1827 * BSSGP message, only patch the latter */
1828
1829 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1830 foreign_tlli2, &rai_bss, cell_id,
1831 GPRS_SAPI_GMM, 0,
1832 dtap_attach_req2, sizeof(dtap_attach_req2));
1833
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001834 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1835
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001836 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1837
Jacob Erlbeck43037632014-06-06 18:49:23 +02001838 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001839 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1840 local_tlli, &rai_bss, cell_id,
1841 GPRS_SAPI_GMM, 3,
1842 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001843
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001844 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1845
Jacob Erlbeck90a1fd12014-05-27 13:49:04 +02001846 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001847 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001848
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001849 /* TODO: The following breaks with the current libosmocore, enable it
1850 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1851 * is integrated */
1852 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1853 OSMO_ASSERT(expect_msg());
1854
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001855 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001856 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001857
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001858 OSMO_ASSERT(!expect_msg());
1859 received_messages = NULL;
1860
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001861 gbprox_reset(&gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001862 gprs_ns_destroy(nsi);
1863 nsi = NULL;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001864}
1865
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001866static void test_gbproxy_ptmsi_assignment()
1867{
1868 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1869 struct sockaddr_in bss_peer[1] = {{0},};
1870 struct sockaddr_in sgsn_peer= {0};
1871 struct gprs_ra_id rai_bss =
1872 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1873 struct gprs_ra_id rai_unknown =
1874 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1875 uint16_t cell_id = 0x1234;
1876
1877 const uint32_t ptmsi = 0xefe2b700;
1878 const uint32_t local_tlli = 0xefe2b700;
1879
1880 const uint32_t foreign_tlli1 = 0x8000dead;
1881 const uint32_t foreign_tlli2 = 0x8000beef;
1882
1883 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1884 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1885
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001886 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001887 struct gbproxy_peer *peer;
1888 unsigned bss_nu = 0;
1889 unsigned sgsn_nu = 0;
1890
1891 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1892
1893 bssgp_nsi = nsi;
1894 gbcfg.nsi = bssgp_nsi;
1895 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1896 gbcfg.core_mcc = 0;
1897 gbcfg.core_mnc = 0;
1898 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1899 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1900 gbcfg.patch_ptmsi = 0;
1901 gbcfg.bss_ptmsi_state = 0;
1902 gbcfg.sgsn_tlli_state = 1;
1903
1904 configure_sgsn_peer(&sgsn_peer);
1905 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1906
1907 printf("=== %s ===\n", __func__);
1908 printf("--- Initialise SGSN ---\n\n");
1909
1910 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
1911
1912 printf("--- Initialise BSS 1 ---\n\n");
1913
1914 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1915 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1916
1917 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1918 OSMO_ASSERT(peer != NULL);
1919
1920 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1921
1922 gprs_dump_nsi(nsi);
1923 dump_global(stdout, 0);
1924 dump_peers(stdout, 0, 0, &gbcfg);
1925
1926 printf("--- Establish first LLC connection ---\n\n");
1927
1928 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1929 foreign_tlli1, &rai_unknown, cell_id,
1930 GPRS_SAPI_GMM, bss_nu++,
1931 dtap_attach_req, sizeof(dtap_attach_req));
1932
1933 dump_peers(stdout, 0, 0, &gbcfg);
1934
1935 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1936 foreign_tlli1, 0, NULL, 0,
1937 GPRS_SAPI_GMM, sgsn_nu++,
1938 dtap_identity_req, sizeof(dtap_identity_req));
1939
1940 dump_peers(stdout, 0, 0, &gbcfg);
1941
1942 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1943 foreign_tlli1, &rai_bss, cell_id,
1944 GPRS_SAPI_GMM, bss_nu++,
1945 dtap_identity_resp, sizeof(dtap_identity_resp));
1946
1947 dump_peers(stdout, 0, 0, &gbcfg);
1948
1949 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1950 foreign_tlli1, 1, imsi1, sizeof(imsi1),
1951 GPRS_SAPI_GMM, sgsn_nu++,
1952 dtap_attach_acc, sizeof(dtap_attach_acc));
1953
1954 dump_peers(stdout, 0, 0, &gbcfg);
1955
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001956 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
1957 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1958 OSMO_ASSERT(link_info);
1959 OSMO_ASSERT(link_info == link_info2);
1960 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1961 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1962 OSMO_ASSERT(!link_info->tlli.bss_validated);
1963 OSMO_ASSERT(!link_info->tlli.net_validated);
1964 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001965
1966 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1967 local_tlli, &rai_bss, cell_id,
1968 GPRS_SAPI_GMM, bss_nu++,
1969 dtap_attach_complete, sizeof(dtap_attach_complete));
1970
1971 dump_peers(stdout, 0, 0, &gbcfg);
1972
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001973 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
1974 OSMO_ASSERT(link_info);
1975 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1976 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
1977 OSMO_ASSERT(link_info->tlli.bss_validated);
1978 OSMO_ASSERT(!link_info->tlli.net_validated);
1979 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001980
1981
1982 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1983 local_tlli, 1, imsi1, sizeof(imsi1),
1984 GPRS_SAPI_GMM, sgsn_nu++,
1985 dtap_gmm_information, sizeof(dtap_gmm_information));
1986
1987 dump_peers(stdout, 0, 0, &gbcfg);
1988
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001989 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
1990 OSMO_ASSERT(link_info);
1991 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
1992 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001993
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001994 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
1995 OSMO_ASSERT(link_info == link_info2);
1996 OSMO_ASSERT(link_info->tlli.assigned == 0);
1997 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1998 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001999
2000 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2001
2002 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2003 foreign_tlli2, &rai_unknown, cell_id,
2004 GPRS_SAPI_GMM, bss_nu++,
2005 dtap_attach_req, sizeof(dtap_attach_req));
2006
2007 dump_peers(stdout, 0, 0, &gbcfg);
2008
2009 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2010 foreign_tlli2, 0, NULL, 0,
2011 GPRS_SAPI_GMM, sgsn_nu++,
2012 dtap_identity_req, sizeof(dtap_identity_req));
2013
2014 dump_peers(stdout, 0, 0, &gbcfg);
2015
2016 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2017 foreign_tlli2, &rai_bss, cell_id,
2018 GPRS_SAPI_GMM, bss_nu++,
2019 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2020
2021 dump_peers(stdout, 0, 0, &gbcfg);
2022
2023 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2024 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2025 GPRS_SAPI_GMM, sgsn_nu++,
2026 dtap_attach_acc, sizeof(dtap_attach_acc));
2027
2028 dump_peers(stdout, 0, 0, &gbcfg);
2029
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002030 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2031 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2032 OSMO_ASSERT(link_info);
2033 OSMO_ASSERT(link_info == link_info2);
2034 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2035 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2036 OSMO_ASSERT(!link_info->tlli.bss_validated);
2037 OSMO_ASSERT(!link_info->tlli.net_validated);
2038 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002039
2040 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2041 local_tlli, &rai_bss, cell_id,
2042 GPRS_SAPI_GMM, bss_nu++,
2043 dtap_attach_complete, sizeof(dtap_attach_complete));
2044
2045 dump_peers(stdout, 0, 0, &gbcfg);
2046
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002047 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2048 OSMO_ASSERT(link_info);
2049 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2050 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2051 OSMO_ASSERT(link_info->tlli.bss_validated);
2052 OSMO_ASSERT(!link_info->tlli.net_validated);
2053 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002054
2055 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2056 local_tlli, 1, imsi2, sizeof(imsi2),
2057 GPRS_SAPI_GMM, sgsn_nu++,
2058 dtap_gmm_information, sizeof(dtap_gmm_information));
2059
2060 dump_peers(stdout, 0, 0, &gbcfg);
2061
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002062 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2063 OSMO_ASSERT(link_info);
2064 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2065 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002066
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002067 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2068 OSMO_ASSERT(link_info == link_info2);
2069 OSMO_ASSERT(link_info->tlli.assigned == 0);
2070 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2071 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002072
2073 dump_global(stdout, 0);
2074
2075 gbprox_reset(&gbcfg);
2076 gprs_ns_destroy(nsi);
2077 nsi = NULL;
2078}
2079
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002080static void test_gbproxy_ptmsi_patching()
2081{
2082 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2083 struct sockaddr_in bss_peer[1] = {{0},};
2084 struct sockaddr_in sgsn_peer= {0};
2085 struct gprs_ra_id rai_bss =
2086 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2087 struct gprs_ra_id rai_sgsn =
2088 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002089 struct gprs_ra_id rai_wrong_mcc_sgsn =
2090 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002091 struct gprs_ra_id rai_unknown =
2092 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2093 uint16_t cell_id = 0x1234;
2094
2095 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002096 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2097 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002098 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002099 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2100 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002101 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002102 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002103
2104 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002105 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2106 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002107 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002108 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2109 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002110 const uint32_t foreign_bss_tlli = 0x8000dead;
2111
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002112
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002113 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002114 struct gbproxy_link_info *link_info;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002115 struct gbproxy_peer *peer;
2116 unsigned bss_nu = 0;
2117 unsigned sgsn_nu = 0;
2118
2119 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002120 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2121 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2122 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2123 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2124 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002125
2126 bssgp_nsi = nsi;
2127 gbcfg.nsi = bssgp_nsi;
2128 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2129 gbcfg.core_mcc = 123;
2130 gbcfg.core_mnc = 456;
2131 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2132 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2133 gbcfg.patch_ptmsi = 1;
2134 gbcfg.bss_ptmsi_state = 0;
2135 gbcfg.sgsn_tlli_state = 1;
2136
2137 configure_sgsn_peer(&sgsn_peer);
2138 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2139
2140 printf("=== %s ===\n", __func__);
2141 printf("--- Initialise SGSN ---\n\n");
2142
Jacob Erlbeck12356062014-08-27 12:44:25 +02002143 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002144
2145 printf("--- Initialise BSS 1 ---\n\n");
2146
2147 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2148 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2149
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02002150 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002151 OSMO_ASSERT(peer != NULL);
2152
2153 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2154
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002155 gprs_dump_nsi(nsi);
2156 dump_global(stdout, 0);
2157 dump_peers(stdout, 0, 0, &gbcfg);
2158
2159 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2160
2161 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2162 foreign_bss_tlli, &rai_unknown, cell_id,
2163 GPRS_SAPI_GMM, bss_nu++,
2164 dtap_attach_req, sizeof(dtap_attach_req));
2165
2166 dump_peers(stdout, 0, 0, &gbcfg);
2167
2168 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2169 random_sgsn_tlli, 0, NULL, 0,
2170 GPRS_SAPI_GMM, sgsn_nu++,
2171 dtap_identity_req, sizeof(dtap_identity_req));
2172
2173 dump_peers(stdout, 0, 0, &gbcfg);
2174
2175 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2176 foreign_bss_tlli, &rai_bss, cell_id,
2177 GPRS_SAPI_GMM, bss_nu++,
2178 dtap_identity_resp, sizeof(dtap_identity_resp));
2179
2180 dump_peers(stdout, 0, 0, &gbcfg);
2181
2182 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2183 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2184 GPRS_SAPI_GMM, sgsn_nu++,
2185 dtap_attach_acc, sizeof(dtap_attach_acc));
2186
2187 dump_peers(stdout, 0, 0, &gbcfg);
2188
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002189 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2190 OSMO_ASSERT(link_info);
2191 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2192 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2193 OSMO_ASSERT(!link_info->tlli.bss_validated);
2194 OSMO_ASSERT(!link_info->tlli.net_validated);
2195 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2196 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2197 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2198 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2199 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2200 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002201
2202 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2203 local_bss_tlli, &rai_bss, cell_id,
2204 GPRS_SAPI_GMM, bss_nu++,
2205 dtap_attach_complete, sizeof(dtap_attach_complete));
2206
2207 dump_peers(stdout, 0, 0, &gbcfg);
2208
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002209 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2210 OSMO_ASSERT(link_info);
2211 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2212 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2213 OSMO_ASSERT(link_info->tlli.bss_validated);
2214 OSMO_ASSERT(!link_info->tlli.net_validated);
2215 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2216 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2217 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2218 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002219
2220 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2221 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2222 GPRS_SAPI_GMM, sgsn_nu++,
2223 dtap_gmm_information, sizeof(dtap_gmm_information));
2224
2225 dump_peers(stdout, 0, 0, &gbcfg);
2226
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002227 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2228 OSMO_ASSERT(link_info);
2229 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2230 OSMO_ASSERT(link_info->tlli.assigned == 0);
2231 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2232 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002233
Jacob Erlbeck03e02ac2014-09-05 18:08:12 +02002234 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2235 local_bss_tlli, &rai_bss, cell_id,
2236 GPRS_SAPI_GMM, bss_nu++,
2237 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2238
2239 dump_peers(stdout, 0, 0, &gbcfg);
2240
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002241 /* Non-DTAP */
2242 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2243 local_bss_tlli, &rai_bss, cell_id,
2244 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2245
2246 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2247 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2248 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2249
2250 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2251 local_bss_tlli, &rai_bss, cell_id,
2252 llc_ui_ll11_dns_query_ul,
2253 sizeof(llc_ui_ll11_dns_query_ul));
2254
2255 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2256 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2257 llc_ui_ll11_dns_resp_dl,
2258 sizeof(llc_ui_ll11_dns_resp_dl));
2259
2260 dump_peers(stdout, 0, 0, &gbcfg);
2261
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002262 /* Repeated RA Update Requests */
2263 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2264 local_bss_tlli, &rai_bss, 0x7080,
2265 GPRS_SAPI_GMM, bss_nu++,
2266 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2267
2268 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2269 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2270 GPRS_SAPI_GMM, sgsn_nu++,
2271 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2272
2273 dump_peers(stdout, 0, 0, &gbcfg);
2274
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002275 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2276 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2277 OSMO_ASSERT(link_info);
2278 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2279 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2280 OSMO_ASSERT(!link_info->tlli.bss_validated);
2281 OSMO_ASSERT(!link_info->tlli.net_validated);
2282 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2283 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2284 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2285 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2286 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2287 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002288
2289 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2290 local_bss_tlli2, &rai_bss, 0x7080,
2291 GPRS_SAPI_GMM, bss_nu++,
2292 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2293
2294 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2295 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2296 GPRS_SAPI_GMM, sgsn_nu++,
2297 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2298
2299 dump_peers(stdout, 0, 0, &gbcfg);
2300
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002301 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2302 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2303 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2304 OSMO_ASSERT(link_info);
2305 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2306 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2307 OSMO_ASSERT(!link_info->tlli.bss_validated);
2308 OSMO_ASSERT(!link_info->tlli.net_validated);
2309 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2310 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2311 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2312 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2313 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2314 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002315
2316 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2317 local_bss_tlli3, &rai_bss, 0x7080,
2318 GPRS_SAPI_GMM, bss_nu++,
2319 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2320
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002321 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002322
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002323 OSMO_ASSERT(link_info);
2324 OSMO_ASSERT(link_info->tlli.bss_validated);
2325 OSMO_ASSERT(!link_info->tlli.net_validated);
2326 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2327 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002328
2329 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2330 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2331 GPRS_SAPI_GMM, sgsn_nu++,
2332 dtap_gmm_information, sizeof(dtap_gmm_information));
2333
2334 dump_peers(stdout, 0, 0, &gbcfg);
2335
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002336 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2337 OSMO_ASSERT(link_info);
2338 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2339 OSMO_ASSERT(link_info->tlli.assigned == 0);
2340 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2341 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002342
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002343 /* Other messages */
2344 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002345 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002346
2347 dump_peers(stdout, 0, 0, &gbcfg);
2348
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002349 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002350
2351 dump_peers(stdout, 0, 0, &gbcfg);
2352
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002353 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002354
2355 dump_peers(stdout, 0, 0, &gbcfg);
2356
2357 /* Bad case: Invalid BVCI */
2358 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002359 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002360 dump_global(stdout, 0);
2361
2362 /* Bad case: Invalid RAI */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002363 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002364
2365 dump_global(stdout, 0);
2366
2367 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002368 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002369 &rai_wrong_mcc_sgsn);
2370
2371 dump_global(stdout, 0);
2372
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002373 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2374 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2375 unknown_sgsn_tlli, 1, NULL, 0,
2376 GPRS_SAPI_GMM, 2,
2377 dtap_gmm_information, sizeof(dtap_gmm_information));
2378
2379 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2380 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2381 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2382 GPRS_SAPI_GMM, 3,
2383 dtap_gmm_information, sizeof(dtap_gmm_information));
2384
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002385 /* Detach */
2386 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002387 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002388 GPRS_SAPI_GMM, bss_nu++,
2389 dtap_detach_req, sizeof(dtap_detach_req));
2390
2391 dump_peers(stdout, 0, 0, &gbcfg);
2392
2393 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002394 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002395 GPRS_SAPI_GMM, sgsn_nu++,
2396 dtap_detach_acc, sizeof(dtap_detach_acc));
2397
2398 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002399
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002400 dump_global(stdout, 0);
2401
2402 gbprox_reset(&gbcfg);
2403 gprs_ns_destroy(nsi);
2404 nsi = NULL;
2405}
2406
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002407static void test_gbproxy_imsi_acquisition()
2408{
2409 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2410 struct sockaddr_in bss_peer[1] = {{0},};
2411 struct sockaddr_in sgsn_peer= {0};
2412 struct gprs_ra_id rai_bss =
2413 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2414 struct gprs_ra_id rai_sgsn =
2415 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2416 struct gprs_ra_id rai_wrong_mcc_sgsn =
2417 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2418 struct gprs_ra_id rai_unknown =
2419 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2420 uint16_t cell_id = 0x1234;
2421
2422 const uint32_t sgsn_ptmsi = 0xefe2b700;
2423 const uint32_t local_sgsn_tlli = 0xefe2b700;
2424 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck9e9051f2014-09-18 09:57:47 +02002425 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002426
2427 const uint32_t bss_ptmsi = 0xc00f7304;
2428 const uint32_t local_bss_tlli = 0xc00f7304;
2429 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002430 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002431
2432 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002433 struct gbproxy_link_info *link_info;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002434 struct gbproxy_peer *peer;
2435 unsigned bss_nu = 0;
2436 unsigned sgsn_nu = 0;
2437
2438 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2439
2440 bssgp_nsi = nsi;
2441 gbcfg.nsi = bssgp_nsi;
2442 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2443 gbcfg.core_mcc = 123;
2444 gbcfg.core_mnc = 456;
2445 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2446 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2447 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02002448 gbcfg.acquire_imsi = 1;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002449 gbcfg.bss_ptmsi_state = 0;
2450 gbcfg.sgsn_tlli_state = 1;
2451
2452 configure_sgsn_peer(&sgsn_peer);
2453 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2454
2455 printf("=== %s ===\n", __func__);
2456 printf("--- Initialise SGSN ---\n\n");
2457
Jacob Erlbeck12356062014-08-27 12:44:25 +02002458 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002459
2460 printf("--- Initialise BSS 1 ---\n\n");
2461
2462 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2463 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2464
2465 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2466 OSMO_ASSERT(peer != NULL);
2467
2468 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2469
2470 gprs_dump_nsi(nsi);
2471 dump_global(stdout, 0);
2472 dump_peers(stdout, 0, 0, &gbcfg);
2473
2474 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2475
2476 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002477 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002478 GPRS_SAPI_GMM, bss_nu++,
2479 dtap_attach_req, sizeof(dtap_attach_req));
2480
2481 dump_peers(stdout, 0, 0, &gbcfg);
2482
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02002483 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2484 foreign_bss_tlli, &rai_bss, cell_id,
2485 GPRS_SAPI_GMM, bss_nu++,
2486 dtap_identity_resp, sizeof(dtap_identity_resp));
2487
2488 dump_peers(stdout, 0, 0, &gbcfg);
2489
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002490 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2491 random_sgsn_tlli, 0, NULL, 0,
2492 GPRS_SAPI_GMM, sgsn_nu++,
2493 dtap_identity_req, sizeof(dtap_identity_req));
2494
2495 dump_peers(stdout, 0, 0, &gbcfg);
2496
2497 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2498 foreign_bss_tlli, &rai_bss, cell_id,
2499 GPRS_SAPI_GMM, bss_nu++,
2500 dtap_identity_resp, sizeof(dtap_identity_resp));
2501
2502 dump_peers(stdout, 0, 0, &gbcfg);
2503
2504 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2505 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2506 GPRS_SAPI_GMM, sgsn_nu++,
2507 dtap_attach_acc, sizeof(dtap_attach_acc));
2508
2509 dump_peers(stdout, 0, 0, &gbcfg);
2510
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002511 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2512 OSMO_ASSERT(link_info);
2513 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2514 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2515 OSMO_ASSERT(!link_info->tlli.bss_validated);
2516 OSMO_ASSERT(!link_info->tlli.net_validated);
2517 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2518 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2519 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2520 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2521 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2522 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002523
2524 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2525 local_bss_tlli, &rai_bss, cell_id,
2526 GPRS_SAPI_GMM, bss_nu++,
2527 dtap_attach_complete, sizeof(dtap_attach_complete));
2528
2529 dump_peers(stdout, 0, 0, &gbcfg);
2530
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002531 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2532 OSMO_ASSERT(link_info);
2533 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2534 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2535 OSMO_ASSERT(link_info->tlli.bss_validated);
2536 OSMO_ASSERT(!link_info->tlli.net_validated);
2537 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2538 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2539 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2540 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002541
2542 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2543 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2544 GPRS_SAPI_GMM, sgsn_nu++,
2545 dtap_gmm_information, sizeof(dtap_gmm_information));
2546
2547 dump_peers(stdout, 0, 0, &gbcfg);
2548
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002549 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2550 OSMO_ASSERT(link_info);
2551 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2552 OSMO_ASSERT(link_info->tlli.assigned == 0);
2553 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2554 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002555
2556 /* Non-DTAP */
2557 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2558 local_bss_tlli, &rai_bss, cell_id,
2559 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2560
2561 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2562 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2563 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2564
2565 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2566 local_bss_tlli, &rai_bss, cell_id,
2567 llc_ui_ll11_dns_query_ul,
2568 sizeof(llc_ui_ll11_dns_query_ul));
2569
2570 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2571 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2572 llc_ui_ll11_dns_resp_dl,
2573 sizeof(llc_ui_ll11_dns_resp_dl));
2574
2575 dump_peers(stdout, 0, 0, &gbcfg);
2576
2577 /* Other messages */
2578 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2579 local_bss_tlli, 1, 12);
2580
2581 dump_peers(stdout, 0, 0, &gbcfg);
2582
2583 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2584 local_sgsn_tlli, 1, 12);
2585
2586 dump_peers(stdout, 0, 0, &gbcfg);
2587
2588 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2589
2590 dump_peers(stdout, 0, 0, &gbcfg);
2591
2592 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2593
2594 dump_peers(stdout, 0, 0, &gbcfg);
2595
2596 /* Bad case: Invalid BVCI */
2597 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2598 local_bss_tlli, 1, 12);
2599 dump_global(stdout, 0);
2600
2601 /* Bad case: Invalid RAI */
2602 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2603
2604 dump_global(stdout, 0);
2605
2606 /* Bad case: Invalid MCC (LAC ok) */
2607 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2608 &rai_wrong_mcc_sgsn);
2609
2610 dump_global(stdout, 0);
2611
2612 /* Detach */
2613 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2614 local_bss_tlli, &rai_bss, cell_id,
2615 GPRS_SAPI_GMM, bss_nu++,
2616 dtap_detach_req, sizeof(dtap_detach_req));
2617
2618 dump_peers(stdout, 0, 0, &gbcfg);
2619
2620 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2621 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2622 GPRS_SAPI_GMM, sgsn_nu++,
2623 dtap_detach_acc, sizeof(dtap_detach_acc));
2624
2625 dump_peers(stdout, 0, 0, &gbcfg);
2626
Jacob Erlbeck9e9051f2014-09-18 09:57:47 +02002627 /* RA Update request */
2628
2629 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2630 foreign_bss_tlli, &rai_unknown, 0x7080,
2631 GPRS_SAPI_GMM, bss_nu++,
2632 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2633
2634 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2635 foreign_bss_tlli, &rai_bss, cell_id,
2636 GPRS_SAPI_GMM, bss_nu++,
2637 dtap_identity_resp, sizeof(dtap_identity_resp));
2638
2639 dump_peers(stdout, 0, 0, &gbcfg);
2640
2641 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2642 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2643 GPRS_SAPI_GMM, sgsn_nu++,
2644 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2645
2646 dump_peers(stdout, 0, 0, &gbcfg);
2647
2648 /* Detach */
2649
2650 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2651 local_bss_tlli, &rai_bss, cell_id,
2652 GPRS_SAPI_GMM, bss_nu++,
2653 dtap_detach_req, sizeof(dtap_detach_req));
2654
2655 dump_peers(stdout, 0, 0, &gbcfg);
2656
2657 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2658 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2659 GPRS_SAPI_GMM, sgsn_nu++,
2660 dtap_detach_acc, sizeof(dtap_detach_acc));
2661
2662 dump_peers(stdout, 0, 0, &gbcfg);
2663
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +02002664 /* Special case: Repeated Attach Requests */
2665
2666 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2667 foreign_bss_tlli, &rai_unknown, cell_id,
2668 GPRS_SAPI_GMM, bss_nu++,
2669 dtap_attach_req, sizeof(dtap_attach_req));
2670
2671 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2672 foreign_bss_tlli, &rai_unknown, cell_id,
2673 GPRS_SAPI_GMM, bss_nu++,
2674 dtap_attach_req, sizeof(dtap_attach_req));
2675
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002676 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2677 foreign_bss_tlli, &rai_bss, cell_id,
2678 GPRS_SAPI_GMM, bss_nu++,
2679 dtap_detach_req, sizeof(dtap_detach_req));
2680
2681 dump_peers(stdout, 0, 0, &gbcfg);
2682
2683 /* Special case: Detach from an unknown TLLI */
2684
2685 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2686 other_bss_tlli, &rai_bss, cell_id,
2687 GPRS_SAPI_GMM, bss_nu++,
2688 dtap_detach_req, sizeof(dtap_detach_req));
2689
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +02002690 dump_peers(stdout, 0, 0, &gbcfg);
2691
Jacob Erlbeck9e9051f2014-09-18 09:57:47 +02002692 /* Special case: Repeated RA Update Requests */
2693
2694 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2695 foreign_bss_tlli, &rai_unknown, 0x7080,
2696 GPRS_SAPI_GMM, bss_nu++,
2697 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2698
2699 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2700 foreign_bss_tlli, &rai_unknown, 0x7080,
2701 GPRS_SAPI_GMM, bss_nu++,
2702 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2703
2704 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2705 foreign_bss_tlli, &rai_bss, cell_id,
2706 GPRS_SAPI_GMM, bss_nu++,
2707 dtap_detach_req, sizeof(dtap_detach_req));
2708
2709 dump_peers(stdout, 0, 0, &gbcfg);
2710
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002711 dump_global(stdout, 0);
2712
2713 gbprox_reset(&gbcfg);
2714 gprs_ns_destroy(nsi);
2715 nsi = NULL;
2716}
2717
Jacob Erlbeck12356062014-08-27 12:44:25 +02002718static void test_gbproxy_secondary_sgsn()
2719{
2720 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2721 struct sockaddr_in bss_peer[1] = {{0},};
2722 struct sockaddr_in sgsn_peer[2]= {{0},};
2723 struct gprs_ra_id rai_bss =
2724 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2725 struct gprs_ra_id rai_sgsn =
2726 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2727 struct gprs_ra_id rai_unknown =
2728 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2729 uint16_t cell_id = 0x1234;
2730
2731 const uint32_t sgsn_ptmsi = 0xefe2b700;
2732 const uint32_t local_sgsn_tlli = 0xefe2b700;
2733 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2734
2735 const uint32_t bss_ptmsi = 0xc00f7304;
2736 const uint32_t local_bss_tlli = 0xc00f7304;
2737 const uint32_t foreign_bss_tlli = 0x8000dead;
2738
2739 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2740 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2741 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2742 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2743 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2744 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2745
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02002746 const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
Jacob Erlbeckd918f522014-09-17 10:56:38 +02002747 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02002748 const uint32_t local_bss_tlli3 = 0xead4775a;
2749 const uint32_t foreign_bss_tlli3 = 0x8000feed;
2750
Jacob Erlbeck12356062014-08-27 12:44:25 +02002751 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2752 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02002753 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002754 struct gbproxy_link_info *link_info;
2755 struct gbproxy_link_info *other_info;
Jacob Erlbeck12356062014-08-27 12:44:25 +02002756 struct gbproxy_peer *peer;
2757 unsigned bss_nu = 0;
2758 unsigned sgsn_nu = 0;
2759
2760 const char *err_msg = NULL;
2761 const char *filter_re = "999999";
2762
2763 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2764 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2765
2766 bssgp_nsi = nsi;
2767 gbcfg.nsi = bssgp_nsi;
2768 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2769 gbcfg.core_mcc = 123;
2770 gbcfg.core_mnc = 456;
2771 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2772 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2773 gbcfg.patch_ptmsi = 1;
2774 gbcfg.acquire_imsi = 1;
2775 gbcfg.bss_ptmsi_state = 0;
2776 gbcfg.sgsn_tlli_state = 1;
2777 gbcfg.route_to_sgsn2 = 1;
2778 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2779
2780 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2781 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2782 err_msg);
2783 OSMO_ASSERT(err_msg == NULL);
2784 }
2785
2786 configure_sgsn_peer(&sgsn_peer[0]);
2787 configure_sgsn2_peer(&sgsn_peer[1]);
2788 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2789
2790 printf("=== %s ===\n", __func__);
2791 printf("--- Initialise SGSN 1 ---\n\n");
2792
2793 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2794
2795 printf("--- Initialise SGSN 2 ---\n\n");
2796
2797 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2798
2799 printf("--- Initialise BSS 1 ---\n\n");
2800
2801 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2802 setup_bssgp(nsi, &bss_peer[0], 0x0);
2803 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2804 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2805 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2806 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2807
2808 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2809 OSMO_ASSERT(peer != NULL);
2810
2811 gprs_dump_nsi(nsi);
2812 dump_global(stdout, 0);
2813 dump_peers(stdout, 0, 0, &gbcfg);
2814
2815 printf("--- Flow control ---\n\n");
2816
2817 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2818 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2819 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2820
2821 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2822
2823 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2824 foreign_bss_tlli, &rai_unknown, cell_id,
2825 GPRS_SAPI_GMM, bss_nu++,
2826 dtap_attach_req, sizeof(dtap_attach_req));
2827
2828 dump_peers(stdout, 0, 0, &gbcfg);
2829
2830 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2831 foreign_bss_tlli, &rai_bss, cell_id,
2832 GPRS_SAPI_GMM, bss_nu++,
2833 dtap_identity_resp, sizeof(dtap_identity_resp));
2834
2835 dump_peers(stdout, 0, 0, &gbcfg);
2836
2837 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2838 random_sgsn_tlli, 0, NULL, 0,
2839 GPRS_SAPI_GMM, sgsn_nu++,
2840 dtap_identity_req, sizeof(dtap_identity_req));
2841
2842 dump_peers(stdout, 0, 0, &gbcfg);
2843
2844 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2845 foreign_bss_tlli, &rai_bss, cell_id,
2846 GPRS_SAPI_GMM, bss_nu++,
2847 dtap_identity_resp, sizeof(dtap_identity_resp));
2848
2849 dump_peers(stdout, 0, 0, &gbcfg);
2850
2851 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2852 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2853 GPRS_SAPI_GMM, sgsn_nu++,
2854 dtap_attach_acc, sizeof(dtap_attach_acc));
2855
2856 dump_peers(stdout, 0, 0, &gbcfg);
2857
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002858 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2859 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2860 OSMO_ASSERT(link_info);
2861 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2862 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2863 OSMO_ASSERT(!link_info->tlli.bss_validated);
2864 OSMO_ASSERT(!link_info->tlli.net_validated);
2865 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2866 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2867 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2868 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2869 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2870 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck12356062014-08-27 12:44:25 +02002871
2872 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2873 local_bss_tlli, &rai_bss, cell_id,
2874 GPRS_SAPI_GMM, bss_nu++,
2875 dtap_attach_complete, sizeof(dtap_attach_complete));
2876
2877 dump_peers(stdout, 0, 0, &gbcfg);
2878
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002879 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2880 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2881 OSMO_ASSERT(link_info);
2882 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2883 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2884 OSMO_ASSERT(link_info->tlli.bss_validated);
2885 OSMO_ASSERT(!link_info->tlli.net_validated);
2886 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2887 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2888 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2889 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck12356062014-08-27 12:44:25 +02002890
2891 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2892 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2893 GPRS_SAPI_GMM, sgsn_nu++,
2894 dtap_gmm_information, sizeof(dtap_gmm_information));
2895
2896 dump_peers(stdout, 0, 0, &gbcfg);
2897
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002898 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
2899 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2900 OSMO_ASSERT(link_info);
2901 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2902 OSMO_ASSERT(link_info->tlli.assigned == 0);
2903 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2904 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck12356062014-08-27 12:44:25 +02002905
2906 /* Non-DTAP */
2907 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2908 local_bss_tlli, &rai_bss, cell_id,
2909 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2910
2911 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2912 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2913 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2914
2915 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2916 local_bss_tlli, &rai_bss, cell_id,
2917 llc_ui_ll11_dns_query_ul,
2918 sizeof(llc_ui_ll11_dns_query_ul));
2919
2920 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2921 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2922 llc_ui_ll11_dns_resp_dl,
2923 sizeof(llc_ui_ll11_dns_resp_dl));
2924
2925 dump_peers(stdout, 0, 0, &gbcfg);
2926
2927 /* Other messages */
2928 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2929 local_bss_tlli, 1, 12);
2930
2931 dump_peers(stdout, 0, 0, &gbcfg);
2932
2933 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2934 local_sgsn_tlli, 1, 12);
2935
2936 dump_peers(stdout, 0, 0, &gbcfg);
2937
2938 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2939
2940 dump_peers(stdout, 0, 0, &gbcfg);
2941
2942 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2943
2944 dump_peers(stdout, 0, 0, &gbcfg);
2945
2946 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2947
2948 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2949 foreign_bss_tlli2, &rai_unknown, cell_id,
2950 GPRS_SAPI_GMM, bss_nu++,
2951 dtap_attach_req, sizeof(dtap_attach_req));
2952
2953 dump_peers(stdout, 0, 0, &gbcfg);
2954
2955 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2956 foreign_bss_tlli2, &rai_bss, cell_id,
2957 GPRS_SAPI_GMM, bss_nu++,
2958 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2959
2960 dump_peers(stdout, 0, 0, &gbcfg);
2961
2962 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2963 random_sgsn_tlli2, 0, NULL, 0,
2964 GPRS_SAPI_GMM, sgsn_nu++,
2965 dtap_identity_req, sizeof(dtap_identity_req));
2966
2967 dump_peers(stdout, 0, 0, &gbcfg);
2968
2969 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2970 foreign_bss_tlli2, &rai_bss, cell_id,
2971 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck9aa21cd2014-09-17 12:05:08 +02002972 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeck12356062014-08-27 12:44:25 +02002973
2974 dump_peers(stdout, 0, 0, &gbcfg);
2975
2976 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2977 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2978 GPRS_SAPI_GMM, sgsn_nu++,
2979 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2980
2981 dump_peers(stdout, 0, 0, &gbcfg);
2982
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002983 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
2984 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
2985 OSMO_ASSERT(link_info);
2986 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2987 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
2988 OSMO_ASSERT(!link_info->tlli.bss_validated);
2989 OSMO_ASSERT(!link_info->tlli.net_validated);
2990 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2991 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2992 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
2993 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2994 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2995 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck12356062014-08-27 12:44:25 +02002996
2997 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2998 local_bss_tlli2, &rai_bss, cell_id,
2999 GPRS_SAPI_GMM, bss_nu++,
3000 dtap_attach_complete, sizeof(dtap_attach_complete));
3001
3002 dump_peers(stdout, 0, 0, &gbcfg);
3003
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003004 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3005 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3006 OSMO_ASSERT(link_info);
3007 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3008 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3009 OSMO_ASSERT(link_info->tlli.bss_validated);
3010 OSMO_ASSERT(!link_info->tlli.net_validated);
3011 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3012 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3013 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3014 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003015
3016 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3017 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3018 GPRS_SAPI_GMM, sgsn_nu++,
3019 dtap_gmm_information, sizeof(dtap_gmm_information));
3020
3021 dump_peers(stdout, 0, 0, &gbcfg);
3022
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003023 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3024 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3025 OSMO_ASSERT(link_info);
3026 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3027 OSMO_ASSERT(link_info->tlli.assigned == 0);
3028 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3029 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003030
3031 /* Non-DTAP */
3032 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3033 local_bss_tlli2, &rai_bss, cell_id,
3034 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3035
3036 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3037 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3038 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3039
3040 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3041 local_bss_tlli2, &rai_bss, cell_id,
3042 llc_ui_ll11_dns_query_ul,
3043 sizeof(llc_ui_ll11_dns_query_ul));
3044
3045 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3046 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3047 llc_ui_ll11_dns_resp_dl,
3048 sizeof(llc_ui_ll11_dns_resp_dl));
3049
3050 dump_peers(stdout, 0, 0, &gbcfg);
3051
3052 /* Other messages */
3053 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3054 local_bss_tlli2, 1, 12);
3055
3056 dump_peers(stdout, 0, 0, &gbcfg);
3057
3058 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3059 local_sgsn_tlli2, 1, 12);
3060
3061 dump_peers(stdout, 0, 0, &gbcfg);
3062
3063 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3064
3065 dump_peers(stdout, 0, 0, &gbcfg);
3066
3067 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3068
3069 dump_peers(stdout, 0, 0, &gbcfg);
3070
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003071 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3072
3073 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3074 foreign_bss_tlli3, &rai_unknown, cell_id,
3075 GPRS_SAPI_GMM, bss_nu++,
3076 dtap_attach_req, sizeof(dtap_attach_req));
3077
3078 dump_peers(stdout, 0, 0, &gbcfg);
3079
3080 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3081 foreign_bss_tlli3, &rai_bss, cell_id,
3082 GPRS_SAPI_GMM, bss_nu++,
3083 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3084
3085 dump_peers(stdout, 0, 0, &gbcfg);
3086
3087 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3088 random_sgsn_tlli3, 0, NULL, 0,
3089 GPRS_SAPI_GMM, sgsn_nu++,
3090 dtap_identity_req, sizeof(dtap_identity_req));
3091
3092 dump_peers(stdout, 0, 0, &gbcfg);
3093
3094 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3095 foreign_bss_tlli3, &rai_bss, cell_id,
3096 GPRS_SAPI_GMM, bss_nu++,
3097 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3098
3099 dump_peers(stdout, 0, 0, &gbcfg);
3100
3101 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3102 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3103 GPRS_SAPI_GMM, sgsn_nu++,
3104 dtap_attach_acc, sizeof(dtap_attach_acc));
3105
3106 dump_peers(stdout, 0, 0, &gbcfg);
3107
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003108 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3109 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3110 OSMO_ASSERT(link_info);
3111 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3112 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3113 OSMO_ASSERT(!link_info->tlli.bss_validated);
3114 OSMO_ASSERT(!link_info->tlli.net_validated);
3115 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3116 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3117 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3118 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3119 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3120 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003121
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003122 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3123 local_bss_tlli3, &rai_bss, cell_id,
3124 GPRS_SAPI_GMM, bss_nu++,
3125 dtap_attach_complete, sizeof(dtap_attach_complete));
3126
3127 dump_peers(stdout, 0, 0, &gbcfg);
3128
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003129 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003130 OSMO_ASSERT(other_info);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003131 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3132 OSMO_ASSERT(link_info);
3133 OSMO_ASSERT(link_info != other_info);
3134 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3135 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3136 OSMO_ASSERT(link_info->tlli.bss_validated);
3137 OSMO_ASSERT(!link_info->tlli.net_validated);
3138 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3139 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3140 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3141 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003142
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003143 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3144 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3145 GPRS_SAPI_GMM, sgsn_nu++,
3146 dtap_gmm_information, sizeof(dtap_gmm_information));
3147
3148 dump_peers(stdout, 0, 0, &gbcfg);
3149
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003150 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003151 OSMO_ASSERT(other_info);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003152 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3153 OSMO_ASSERT(link_info);
3154 OSMO_ASSERT(link_info != other_info);
3155 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3156 OSMO_ASSERT(link_info->tlli.assigned == 0);
3157 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3158 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003159
3160
Jacob Erlbeck12356062014-08-27 12:44:25 +02003161 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3162
3163 /* Detach */
3164 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3165 local_bss_tlli, &rai_bss, cell_id,
3166 GPRS_SAPI_GMM, bss_nu++,
3167 dtap_detach_req, sizeof(dtap_detach_req));
3168
3169 dump_peers(stdout, 0, 0, &gbcfg);
3170
3171 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3172 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3173 GPRS_SAPI_GMM, sgsn_nu++,
3174 dtap_detach_acc, sizeof(dtap_detach_acc));
3175
3176 dump_peers(stdout, 0, 0, &gbcfg);
3177
3178 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3179
3180 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3181 local_bss_tlli2, &rai_bss, cell_id,
3182 GPRS_SAPI_GMM, bss_nu++,
3183 dtap_detach_req, sizeof(dtap_detach_req));
3184
3185 dump_peers(stdout, 0, 0, &gbcfg);
3186
3187 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3188 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3189 GPRS_SAPI_GMM, sgsn_nu++,
3190 dtap_detach_acc, sizeof(dtap_detach_acc));
3191
3192 dump_peers(stdout, 0, 0, &gbcfg);
3193
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003194 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3195
3196 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3197 local_bss_tlli3, &rai_bss, cell_id,
3198 GPRS_SAPI_GMM, bss_nu++,
3199 dtap_detach_req, sizeof(dtap_detach_req));
3200
3201 dump_peers(stdout, 0, 0, &gbcfg);
3202
3203 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3204 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3205 GPRS_SAPI_GMM, sgsn_nu++,
3206 dtap_detach_acc, sizeof(dtap_detach_acc));
3207
3208 dump_peers(stdout, 0, 0, &gbcfg);
3209
Jacob Erlbeck12356062014-08-27 12:44:25 +02003210 dump_global(stdout, 0);
3211
3212 gbprox_reset(&gbcfg);
3213 gprs_ns_destroy(nsi);
3214 nsi = NULL;
3215}
3216
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003217static void test_gbproxy_keep_info()
3218{
3219 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3220 struct sockaddr_in bss_peer[1] = {{0},};
3221 struct sockaddr_in sgsn_peer= {0};
3222 struct gprs_ra_id rai_bss =
3223 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3224 uint16_t cell_id = 0x1234;
3225
3226 const uint32_t ptmsi = 0xefe2b700;
3227 const uint32_t local_tlli = 0xefe2b700;
3228 const uint32_t foreign_tlli = 0xafe2b700;
3229
3230 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003231 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003232 struct gbproxy_peer *peer;
3233 unsigned bss_nu = 0;
3234 unsigned sgsn_nu = 0;
3235
3236 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3237
3238 bssgp_nsi = nsi;
3239 gbcfg.nsi = bssgp_nsi;
3240 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3241 gbcfg.patch_ptmsi = 0;
3242 gbcfg.acquire_imsi = 1;
3243 gbcfg.bss_ptmsi_state = 0;
3244 gbcfg.sgsn_tlli_state = 1;
3245 gbcfg.core_mcc = 0;
3246 gbcfg.core_mnc = 0;
3247 gbcfg.core_apn = NULL;
3248 gbcfg.core_apn_size = 0;
3249 gbcfg.route_to_sgsn2 = 0;
3250 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003251 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003252
3253 configure_sgsn_peer(&sgsn_peer);
3254 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3255
3256 printf("=== %s ===\n", __func__);
3257 printf("--- Initialise SGSN ---\n\n");
3258
3259 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3260
3261 printf("--- Initialise BSS 1 ---\n\n");
3262
3263 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3264 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3265
3266 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3267 OSMO_ASSERT(peer != NULL);
3268
3269 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3270
3271 gprs_dump_nsi(nsi);
3272 dump_global(stdout, 0);
3273 dump_peers(stdout, 0, 0, &gbcfg);
3274
3275 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3276
3277 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3278 foreign_tlli, &rai_bss, cell_id,
3279 GPRS_SAPI_GMM, bss_nu++,
3280 dtap_attach_req, sizeof(dtap_attach_req));
3281
3282 dump_peers(stdout, 0, 0, &gbcfg);
3283
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003284 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3285 OSMO_ASSERT(link_info);
3286 OSMO_ASSERT(link_info->imsi_len == 0);
3287 OSMO_ASSERT(!link_info->is_deregistered);
3288 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003289
3290 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3291 foreign_tlli, &rai_bss, cell_id,
3292 GPRS_SAPI_GMM, bss_nu++,
3293 dtap_identity_resp, sizeof(dtap_identity_resp));
3294
3295 dump_peers(stdout, 0, 0, &gbcfg);
3296
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003297 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3298 OSMO_ASSERT(link_info);
3299 OSMO_ASSERT(link_info->imsi_len > 0);
3300 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003301
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003302 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3303 foreign_tlli, 0, NULL, 0,
3304 GPRS_SAPI_GMM, sgsn_nu++,
3305 dtap_identity_req, sizeof(dtap_identity_req));
3306
3307 dump_peers(stdout, 0, 0, &gbcfg);
3308
3309 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3310 foreign_tlli, &rai_bss, cell_id,
3311 GPRS_SAPI_GMM, bss_nu++,
3312 dtap_identity_resp, sizeof(dtap_identity_resp));
3313
3314 dump_peers(stdout, 0, 0, &gbcfg);
3315
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003316 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3317 OSMO_ASSERT(link_info);
3318 OSMO_ASSERT(link_info->imsi_len > 0);
3319 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003320
3321 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3322 foreign_tlli, 1, imsi, sizeof(imsi),
3323 GPRS_SAPI_GMM, sgsn_nu++,
3324 dtap_attach_acc, sizeof(dtap_attach_acc));
3325
3326 dump_peers(stdout, 0, 0, &gbcfg);
3327
3328 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3329 local_tlli, &rai_bss, cell_id,
3330 GPRS_SAPI_GMM, bss_nu++,
3331 dtap_attach_complete, sizeof(dtap_attach_complete));
3332
3333 dump_peers(stdout, 0, 0, &gbcfg);
3334
3335 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3336 local_tlli, 1, imsi, sizeof(imsi),
3337 GPRS_SAPI_GMM, sgsn_nu++,
3338 dtap_gmm_information, sizeof(dtap_gmm_information));
3339
3340 dump_peers(stdout, 0, 0, &gbcfg);
3341
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003342 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3343 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003344
3345 /* Detach (MO) */
3346 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3347 local_tlli, &rai_bss, cell_id,
3348 GPRS_SAPI_GMM, bss_nu++,
3349 dtap_detach_req, sizeof(dtap_detach_req));
3350
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003351 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3352 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003353
3354 dump_peers(stdout, 0, 0, &gbcfg);
3355
3356 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3357 local_tlli, 1, imsi, sizeof(imsi),
3358 GPRS_SAPI_GMM, sgsn_nu++,
3359 dtap_detach_acc, sizeof(dtap_detach_acc));
3360
3361 dump_peers(stdout, 0, 0, &gbcfg);
3362
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003363 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3364 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3365 OSMO_ASSERT(link_info);
3366 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003367
3368 /* Re-Attach */
3369 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3370 foreign_tlli, &rai_bss, cell_id,
3371 GPRS_SAPI_GMM, bss_nu++,
3372 dtap_attach_req3, sizeof(dtap_attach_req3));
3373
3374 dump_peers(stdout, 0, 0, &gbcfg);
3375
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003376 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3377 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3378 OSMO_ASSERT(link_info);
3379 OSMO_ASSERT(link_info == link_info2);
3380 OSMO_ASSERT(link_info->imsi_len != 0);
3381 OSMO_ASSERT(!link_info->is_deregistered);
3382 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003383
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003384 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3385 foreign_tlli, 1, imsi, sizeof(imsi),
3386 GPRS_SAPI_GMM, sgsn_nu++,
3387 dtap_attach_acc, sizeof(dtap_attach_acc));
3388
3389 dump_peers(stdout, 0, 0, &gbcfg);
3390
3391 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3392 local_tlli, &rai_bss, cell_id,
3393 GPRS_SAPI_GMM, bss_nu++,
3394 dtap_attach_complete, sizeof(dtap_attach_complete));
3395
3396 dump_peers(stdout, 0, 0, &gbcfg);
3397
3398 /* Detach (MT) */
3399 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3400 local_tlli, 1, imsi, sizeof(imsi),
3401 GPRS_SAPI_GMM, sgsn_nu++,
3402 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3403
3404 dump_peers(stdout, 0, 0, &gbcfg);
3405
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003406 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3407 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003408
3409 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3410 local_tlli, &rai_bss, cell_id,
3411 GPRS_SAPI_GMM, bss_nu++,
3412 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3413
3414 dump_peers(stdout, 0, 0, &gbcfg);
3415
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003416 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3417 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3418 OSMO_ASSERT(link_info);
3419 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003420
3421 /* Re-Attach */
3422 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3423 foreign_tlli, &rai_bss, cell_id,
3424 GPRS_SAPI_GMM, bss_nu++,
3425 dtap_attach_req3, sizeof(dtap_attach_req3));
3426
3427 dump_peers(stdout, 0, 0, &gbcfg);
3428
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003429 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3430 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3431 OSMO_ASSERT(link_info);
3432 OSMO_ASSERT(link_info == link_info2);
3433 OSMO_ASSERT(link_info->imsi_len != 0);
3434 OSMO_ASSERT(!link_info->is_deregistered);
3435 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003436
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003437 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3438 foreign_tlli, 1, imsi, sizeof(imsi),
3439 GPRS_SAPI_GMM, sgsn_nu++,
3440 dtap_attach_acc, sizeof(dtap_attach_acc));
3441
3442 dump_peers(stdout, 0, 0, &gbcfg);
3443
3444 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3445 local_tlli, &rai_bss, cell_id,
3446 GPRS_SAPI_GMM, bss_nu++,
3447 dtap_attach_complete, sizeof(dtap_attach_complete));
3448
3449 dump_peers(stdout, 0, 0, &gbcfg);
3450
3451 /* Detach (MT) */
3452 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3453 local_tlli, 1, imsi, sizeof(imsi),
3454 GPRS_SAPI_GMM, sgsn_nu++,
3455 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3456
3457 dump_peers(stdout, 0, 0, &gbcfg);
3458
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003459 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3460 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003461
3462 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3463 local_tlli, &rai_bss, cell_id,
3464 GPRS_SAPI_GMM, bss_nu++,
3465 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3466
3467 dump_peers(stdout, 0, 0, &gbcfg);
3468
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003469 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3470 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3471 OSMO_ASSERT(link_info);
3472 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003473
3474 /* Re-Attach */
3475 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3476 foreign_tlli, &rai_bss, cell_id,
3477 GPRS_SAPI_GMM, bss_nu++,
3478 dtap_attach_req3, sizeof(dtap_attach_req3));
3479
3480 dump_peers(stdout, 0, 0, &gbcfg);
3481
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003482 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3483 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3484 OSMO_ASSERT(link_info);
3485 OSMO_ASSERT(link_info == link_info2);
3486 OSMO_ASSERT(link_info->imsi_len != 0);
3487 OSMO_ASSERT(!link_info->is_deregistered);
3488 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003489
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003490 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3491 foreign_tlli, 1, imsi, sizeof(imsi),
3492 GPRS_SAPI_GMM, sgsn_nu++,
3493 dtap_attach_acc, sizeof(dtap_attach_acc));
3494
3495 dump_peers(stdout, 0, 0, &gbcfg);
3496
3497 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3498 local_tlli, &rai_bss, cell_id,
3499 GPRS_SAPI_GMM, bss_nu++,
3500 dtap_attach_complete, sizeof(dtap_attach_complete));
3501
3502 dump_peers(stdout, 0, 0, &gbcfg);
3503
3504 /* RA update procedure (reject -> Detach) */
3505 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3506 local_tlli, &rai_bss, 0x7080,
3507 GPRS_SAPI_GMM, bss_nu++,
3508 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3509
3510 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3511 local_tlli, 1, imsi, sizeof(imsi),
3512 GPRS_SAPI_GMM, sgsn_nu++,
3513 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3514
3515 dump_peers(stdout, 0, 0, &gbcfg);
3516
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003517 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3518 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3519 OSMO_ASSERT(link_info);
3520 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003521
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003522 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3523 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3524 foreign_tlli, &rai_bss, cell_id,
3525 GPRS_SAPI_GMM, bss_nu++,
3526 dtap_attach_req, sizeof(dtap_attach_req));
3527
3528 dump_peers(stdout, 0, 0, &gbcfg);
3529
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003530 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3531 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3532 OSMO_ASSERT(link_info);
3533 OSMO_ASSERT(link_info != link_info2);
3534 OSMO_ASSERT(link_info->imsi_len == 0);
3535 OSMO_ASSERT(!link_info->is_deregistered);
3536 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003537
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02003538 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3539 foreign_tlli, &rai_bss, cell_id,
3540 GPRS_SAPI_GMM, bss_nu++,
3541 dtap_identity_resp, sizeof(dtap_identity_resp));
3542
3543 dump_peers(stdout, 0, 0, &gbcfg);
3544
3545 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3546 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3547 OSMO_ASSERT(link_info);
3548 OSMO_ASSERT(link_info == link_info2);
3549 OSMO_ASSERT(link_info->imsi_len != 0);
3550 OSMO_ASSERT(!link_info->is_deregistered);
3551 OSMO_ASSERT(!link_info->imsi_acq_pending);
3552
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003553 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3554 foreign_tlli, 1, imsi, sizeof(imsi),
3555 GPRS_SAPI_GMM, sgsn_nu++,
3556 dtap_attach_acc, sizeof(dtap_attach_acc));
3557
3558 dump_peers(stdout, 0, 0, &gbcfg);
3559
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003560 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3561 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3562 OSMO_ASSERT(link_info);
3563 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeck99b41132014-09-22 09:28:27 +02003564 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003565
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003566 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3567 local_tlli, &rai_bss, cell_id,
3568 GPRS_SAPI_GMM, bss_nu++,
3569 dtap_attach_complete, sizeof(dtap_attach_complete));
3570
3571 dump_peers(stdout, 0, 0, &gbcfg);
3572
3573 /* Detach (MT) */
3574 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3575 local_tlli, 1, imsi, sizeof(imsi),
3576 GPRS_SAPI_GMM, sgsn_nu++,
3577 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3578
3579 dump_peers(stdout, 0, 0, &gbcfg);
3580
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003581 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3582 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003583
3584 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3585 local_tlli, &rai_bss, cell_id,
3586 GPRS_SAPI_GMM, bss_nu++,
3587 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3588
3589 dump_peers(stdout, 0, 0, &gbcfg);
3590
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003591 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3592 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3593 OSMO_ASSERT(link_info);
3594 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003595
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02003596 /* Attach rejected */
3597
3598 gbproxy_delete_link_infos(peer);
3599
3600 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3601 foreign_tlli, &rai_bss, cell_id,
3602 GPRS_SAPI_GMM, bss_nu++,
3603 dtap_attach_req, sizeof(dtap_attach_req));
3604
3605 dump_peers(stdout, 0, 0, &gbcfg);
3606
3607 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3608 OSMO_ASSERT(link_info);
3609 OSMO_ASSERT(link_info->imsi_len == 0);
3610 OSMO_ASSERT(!link_info->is_deregistered);
3611 OSMO_ASSERT(link_info->imsi_acq_pending);
3612
3613 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3614 foreign_tlli, &rai_bss, cell_id,
3615 GPRS_SAPI_GMM, bss_nu++,
3616 dtap_identity_resp, sizeof(dtap_identity_resp));
3617
3618 dump_peers(stdout, 0, 0, &gbcfg);
3619
3620 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3621 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3622 OSMO_ASSERT(link_info);
3623 OSMO_ASSERT(link_info == link_info2);
3624 OSMO_ASSERT(link_info->imsi_len != 0);
3625 OSMO_ASSERT(!link_info->is_deregistered);
3626 OSMO_ASSERT(!link_info->imsi_acq_pending);
3627
3628 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
3629 foreign_tlli, 1, imsi, sizeof(imsi),
3630 GPRS_SAPI_GMM, sgsn_nu++,
3631 dtap_attach_rej7, sizeof(dtap_attach_rej7));
3632
3633 dump_peers(stdout, 0, 0, &gbcfg);
3634
Jacob Erlbeck538bee02014-09-22 10:42:05 +02003635 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3636
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02003637 /* Attach (incomplete) and Detach (MO) */
3638
3639 gbproxy_delete_link_infos(peer);
3640
3641 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3642 foreign_tlli, &rai_bss, cell_id,
3643 GPRS_SAPI_GMM, bss_nu++,
3644 dtap_attach_req, sizeof(dtap_attach_req));
3645
3646 dump_peers(stdout, 0, 0, &gbcfg);
3647
3648 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3649 OSMO_ASSERT(link_info);
3650 OSMO_ASSERT(link_info->imsi_len == 0);
3651 OSMO_ASSERT(!link_info->is_deregistered);
3652 OSMO_ASSERT(link_info->imsi_acq_pending);
3653
3654 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
3655 foreign_tlli, &rai_bss, cell_id,
3656 GPRS_SAPI_GMM, bss_nu++,
3657 dtap_detach_req, sizeof(dtap_detach_req));
3658
3659 dump_peers(stdout, 0, 0, &gbcfg);
3660
3661 /* Attach (incomplete) and Detach (MT) */
3662
3663 gbproxy_delete_link_infos(peer);
3664
3665 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3666 foreign_tlli, &rai_bss, cell_id,
3667 GPRS_SAPI_GMM, bss_nu++,
3668 dtap_attach_req, sizeof(dtap_attach_req));
3669
3670 dump_peers(stdout, 0, 0, &gbcfg);
3671
3672 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3673 OSMO_ASSERT(link_info);
3674 OSMO_ASSERT(link_info->imsi_len == 0);
3675 OSMO_ASSERT(!link_info->is_deregistered);
3676 OSMO_ASSERT(link_info->imsi_acq_pending);
3677
3678 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
3679 foreign_tlli, 1, imsi, sizeof(imsi),
3680 GPRS_SAPI_GMM, sgsn_nu++,
3681 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3682
3683 dump_peers(stdout, 0, 0, &gbcfg);
3684
3685 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3686 OSMO_ASSERT(link_info);
3687
3688 send_llc_ul_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3689 foreign_tlli, &rai_bss, cell_id,
3690 GPRS_SAPI_GMM, bss_nu++,
3691 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3692
3693 dump_peers(stdout, 0, 0, &gbcfg);
3694
3695 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
3696 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3697 OSMO_ASSERT(link_info);
3698 OSMO_ASSERT(link_info->is_deregistered);
3699
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003700 dump_global(stdout, 0);
3701
3702 gbprox_reset(&gbcfg);
3703 gprs_ns_destroy(nsi);
3704 nsi = NULL;
3705}
3706
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003707/* TODO: Move tlv testing to libosmocore */
3708int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
3709int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
3710 uint8_t **value);
3711int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
3712 size_t *value_len);
3713int lv_shift(uint8_t **data, size_t *data_len,
3714 uint8_t **value, size_t *value_len);
3715
3716static void check_tlv_match(uint8_t **data, size_t *data_len,
3717 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
3718{
3719 uint8_t *value;
3720 size_t value_len;
3721 int rc;
3722
3723 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
3724 OSMO_ASSERT(rc == 0);
3725
3726 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003727 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003728 OSMO_ASSERT(value_len == exp_len);
3729 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3730}
3731
3732static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
3733 uint8_t tag, size_t len, const uint8_t *exp_val)
3734{
3735 uint8_t *value;
3736 int rc;
3737
3738 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
3739 OSMO_ASSERT(rc == 0);
3740
3741 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003742 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003743 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3744}
3745
3746static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
3747 size_t len, const uint8_t *exp_val)
3748{
3749 uint8_t *value;
3750 int rc;
3751
3752 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003753 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003754 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
3755}
3756
3757static void check_lv_shift(uint8_t **data, size_t *data_len,
3758 size_t exp_len, const uint8_t *exp_val)
3759{
3760 uint8_t *value;
3761 size_t value_len;
3762 int rc;
3763
3764 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003765 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003766 OSMO_ASSERT(value_len == exp_len);
3767 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
3768}
3769
3770static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
3771 const uint8_t *test_data)
3772{
3773 uint8_t buf[300] = {0};
3774
3775 uint8_t *unchanged_ptr = buf - 1;
3776 size_t unchanged_len = 0xdead;
3777 size_t tmp_data_len = data_len;
3778 uint8_t *value = unchanged_ptr;
3779 size_t value_len = unchanged_len;
3780 uint8_t *data = buf;
3781
3782 OSMO_ASSERT(data_len <= sizeof(buf));
3783
3784 tlv_put(data, tag, len, test_data);
3785 if (data_len < len + 2) {
3786 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
3787 tag, &value, &value_len));
3788 OSMO_ASSERT(tmp_data_len == 0);
3789 OSMO_ASSERT(data == buf + data_len);
3790 OSMO_ASSERT(value == unchanged_ptr);
3791 OSMO_ASSERT(value_len == unchanged_len);
3792 } else {
3793 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
3794 tag, &value, &value_len));
3795 OSMO_ASSERT(value != unchanged_ptr);
3796 OSMO_ASSERT(value_len != unchanged_len);
3797 }
3798}
3799
3800static void check_tv_fixed_match_data_len(size_t data_len,
3801 uint8_t tag, size_t len,
3802 const uint8_t *test_data)
3803{
3804 uint8_t buf[300] = {0};
3805
3806 uint8_t *unchanged_ptr = buf - 1;
3807 size_t tmp_data_len = data_len;
3808 uint8_t *value = unchanged_ptr;
3809 uint8_t *data = buf;
3810
3811 OSMO_ASSERT(data_len <= sizeof(buf));
3812
3813 tv_fixed_put(data, tag, len, test_data);
3814
3815 if (data_len < len + 1) {
3816 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
3817 tag, len, &value));
3818 OSMO_ASSERT(tmp_data_len == 0);
3819 OSMO_ASSERT(data == buf + data_len);
3820 OSMO_ASSERT(value == unchanged_ptr);
3821 } else {
3822 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
3823 tag, len, &value));
3824 OSMO_ASSERT(value != unchanged_ptr);
3825 }
3826}
3827
3828static void check_v_fixed_shift_data_len(size_t data_len,
3829 size_t len, const uint8_t *test_data)
3830{
3831 uint8_t buf[300] = {0};
3832
3833 uint8_t *unchanged_ptr = buf - 1;
3834 size_t tmp_data_len = data_len;
3835 uint8_t *value = unchanged_ptr;
3836 uint8_t *data = buf;
3837
3838 OSMO_ASSERT(data_len <= sizeof(buf));
3839
3840 memcpy(data, test_data, len);
3841
3842 if (data_len < len) {
3843 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
3844 len, &value));
3845 OSMO_ASSERT(tmp_data_len == 0);
3846 OSMO_ASSERT(data == buf + data_len);
3847 OSMO_ASSERT(value == unchanged_ptr);
3848 } else {
3849 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
3850 len, &value));
3851 OSMO_ASSERT(value != unchanged_ptr);
3852 }
3853}
3854
3855static void check_lv_shift_data_len(size_t data_len,
3856 size_t len, const uint8_t *test_data)
3857{
3858 uint8_t buf[300] = {0};
3859
3860 uint8_t *unchanged_ptr = buf - 1;
3861 size_t unchanged_len = 0xdead;
3862 size_t tmp_data_len = data_len;
3863 uint8_t *value = unchanged_ptr;
3864 size_t value_len = unchanged_len;
3865 uint8_t *data = buf;
3866
3867 lv_put(data, len, test_data);
3868 if (data_len < len + 1) {
3869 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
3870 &value, &value_len));
3871 OSMO_ASSERT(tmp_data_len == 0);
3872 OSMO_ASSERT(data == buf + data_len);
3873 OSMO_ASSERT(value == unchanged_ptr);
3874 OSMO_ASSERT(value_len == unchanged_len);
3875 } else {
3876 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
3877 &value, &value_len));
3878 OSMO_ASSERT(value != unchanged_ptr);
3879 OSMO_ASSERT(value_len != unchanged_len);
3880 }
3881}
3882
3883static void test_tlv_shift_functions()
3884{
3885 uint8_t test_data[1024];
3886 uint8_t buf[1024];
3887 uint8_t *data_end;
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003888 unsigned i, len;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003889 uint8_t *data;
3890 size_t data_len;
3891 const uint8_t tag = 0x1a;
3892
3893 printf("Test shift functions\n");
3894
3895 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3896 test_data[i] = (uint8_t)i;
3897
3898 for (len = 0; len < 256; len++) {
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02003899 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02003900
3901 memset(buf, 0xee, sizeof(buf));
3902 data_end = data = buf;
3903
3904 for (i = 0; i < iterations; i++) {
3905 data_end = tlv_put(data_end, tag, len, test_data);
3906 data_end = tv_fixed_put(data_end, tag, len, test_data);
3907 /* v_fixed_put */
3908 memcpy(data_end, test_data, len);
3909 data_end += len;
3910 data_end = lv_put(data_end, len, test_data);
3911 }
3912
3913 data_len = data_end - data;
3914 OSMO_ASSERT(data_len <= sizeof(buf));
3915
3916 for (i = 0; i < iterations; i++) {
3917 check_tlv_match(&data, &data_len, tag, len, test_data);
3918 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
3919 check_v_fixed_shift(&data, &data_len, len, test_data);
3920 check_lv_shift(&data, &data_len, len, test_data);
3921 }
3922
3923 OSMO_ASSERT(data == data_end);
3924
3925 /* Test at end of data */
3926
3927 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
3928 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
3929 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
3930 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
3931
3932 /* Test invalid data_len */
3933 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
3934 check_tlv_match_data_len(data_len, tag, len, test_data);
3935 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
3936 check_v_fixed_shift_data_len(data_len, len, test_data);
3937 check_lv_shift_data_len(data_len, len, test_data);
3938 }
3939 }
3940}
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02003941
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003942struct gbproxy_link_info *register_tlli(
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003943 struct gbproxy_peer *peer, uint32_t tlli,
3944 const uint8_t *imsi, size_t imsi_len, time_t now)
3945{
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003946 struct gbproxy_link_info *link_info;
Jacob Erlbeck070702b2014-09-19 13:17:55 +02003947 int imsi_matches = -1;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003948 int tlli_already_known = 0;
3949
3950 /* Check, whether the IMSI matches */
3951 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeck070702b2014-09-19 13:17:55 +02003952 imsi_matches = gbproxy_check_imsi(peer, imsi, imsi_len);
3953 if (imsi_matches < 0)
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003954 return NULL;
3955 }
3956
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003957 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003958
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003959 if (!link_info) {
3960 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003961
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003962 if (link_info) {
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003963 /* TLLI has changed somehow, adjust it */
3964 LOGP(DGPRS, LOGL_INFO,
3965 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003966 link_info->tlli.current, tlli);
3967 link_info->tlli.current = tlli;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003968 }
3969 }
3970
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003971 if (!link_info) {
3972 link_info = gbproxy_link_info_alloc(peer);
3973 link_info->tlli.current = tlli;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003974 } else {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003975 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003976 tlli_already_known = 1;
3977 }
3978
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003979 OSMO_ASSERT(link_info != NULL);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003980
3981 if (!tlli_already_known)
3982 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
3983
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003984 gbproxy_attach_link_info(peer, now, link_info);
3985 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003986
Jacob Erlbeck070702b2014-09-19 13:17:55 +02003987 if (imsi_matches >= 0)
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003988 link_info->imsi_matches = imsi_matches;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003989
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003990 return link_info;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02003991}
3992
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02003993static void test_gbproxy_tlli_expire(void)
3994{
3995 struct gbproxy_config cfg = {0};
3996 struct gbproxy_peer *peer;
3997 const char *err_msg = NULL;
3998 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
3999 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004000 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004001 const uint32_t tlli1 = 1234 | 0xc0000000;
4002 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004003 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004004 const char *filter_re = ".*";
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004005 time_t now = 1407479214;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004006
4007 printf("Test TLLI info expiry\n\n");
4008
4009 gbproxy_init_config(&cfg);
4010
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004011 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004012 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4013 err_msg);
4014 OSMO_ASSERT(err_msg == NULL);
4015 }
4016
4017 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004018 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004019
4020 printf("Test TLLI replacement:\n");
4021
4022 cfg.tlli_max_len = 0;
4023 cfg.tlli_max_age = 0;
4024 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004025 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004026
4027 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004028 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004029 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004030 OSMO_ASSERT(link_info);
4031 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004032 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004033
4034 /* replace the old entry */
4035 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004036 link_info = register_tlli(peer, tlli2,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004037 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004038 OSMO_ASSERT(link_info);
4039 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004040 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004041
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004042 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004043
4044 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004045 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4046 OSMO_ASSERT(link_info);
4047 OSMO_ASSERT(link_info->tlli.current == tlli2);
4048 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4049 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004050
4051 printf("\n");
4052
4053 gbproxy_peer_free(peer);
4054 }
4055
4056 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004057 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004058
4059 printf("Test IMSI replacement:\n");
4060
4061 cfg.tlli_max_len = 0;
4062 cfg.tlli_max_age = 0;
4063 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004064 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004065
4066 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004067 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004068 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004069 OSMO_ASSERT(link_info);
4070 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004071 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004072
4073 /* try to replace the old entry */
4074 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004075 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004076 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004077 OSMO_ASSERT(link_info);
4078 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004079 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004080
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004081 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004082
4083 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004084 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4085 OSMO_ASSERT(!link_info);
4086 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4087 OSMO_ASSERT(link_info);
4088 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004089
4090 printf("\n");
4091
4092 gbproxy_peer_free(peer);
4093 }
4094
4095 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004096 struct gbproxy_link_info *link_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004097 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004098
4099 printf("Test TLLI expiry, max_len == 1:\n");
4100
4101 cfg.tlli_max_len = 1;
4102 cfg.tlli_max_age = 0;
4103 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004104 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004105
4106 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004107 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004108 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004109
4110 /* replace the old entry */
4111 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004112 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004113 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004114
Jacob Erlbeckc4fb4c22014-09-19 16:40:21 +02004115 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004116 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004117 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004118
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004119 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004120
4121 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004122 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4123 OSMO_ASSERT(!link_info);
4124 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4125 OSMO_ASSERT(link_info);
4126 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004127
4128 printf("\n");
4129
4130 gbproxy_peer_free(peer);
4131 }
4132
4133 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004134 struct gbproxy_link_info *link_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004135 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004136
4137 printf("Test TLLI expiry, max_age == 1:\n");
4138
4139 cfg.tlli_max_len = 0;
4140 cfg.tlli_max_age = 1;
4141 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004142 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004143
4144 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004145 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004146 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004147
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004148 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004149 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004150 now + 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004151 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004152
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004153 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004154 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004155 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004156
4157 dump_peers(stdout, 2, now + 2, &cfg);
4158
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004159 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004160 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4161 OSMO_ASSERT(!link_info);
4162 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4163 OSMO_ASSERT(link_info);
4164 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004165
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004166 printf("\n");
4167
4168 gbproxy_peer_free(peer);
4169 }
4170
4171 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004172 struct gbproxy_link_info *link_info;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004173 int num_removed;
4174
4175 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4176
4177 cfg.tlli_max_len = 0;
4178 cfg.tlli_max_age = 1;
4179 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004180 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004181
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004182 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004183 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004184 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004185
4186 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004187 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004188 now + 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004189 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004190
4191 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004192 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004193 now + 2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004194 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004195
4196 dump_peers(stdout, 2, now + 2, &cfg);
4197
4198 printf(" Remove stale TLLIs\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004199 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004200 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004201 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004202
4203 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004204
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004205 /* verify that tlli3 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004206 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4207 OSMO_ASSERT(!link_info);
4208 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4209 OSMO_ASSERT(!link_info);
4210 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4211 OSMO_ASSERT(link_info);
4212 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004213
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004214 printf("\n");
4215
4216 gbproxy_peer_free(peer);
4217 }
4218}
4219
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004220static void test_gbproxy_imsi_matching(void)
4221{
4222 struct gbproxy_config cfg = {0};
4223 struct gbproxy_peer *peer;
4224 const char *err_msg = NULL;
4225 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4226 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4227 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4228 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4229 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4230 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4231 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4232 const char *filter_re1 = ".*";
4233 const char *filter_re2 = "^1234";
4234 const char *filter_re3 = "^4321";
4235 const char *filter_re4_bad = "^12[";
4236
4237 printf("=== Test IMSI/TMSI matching ===\n\n");
4238
4239 gbproxy_init_config(&cfg);
4240 OSMO_ASSERT(cfg.check_imsi == 0);
4241
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004242 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004243 OSMO_ASSERT(cfg.check_imsi == 1);
4244
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004245 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004246 OSMO_ASSERT(cfg.check_imsi == 1);
4247
4248 err_msg = NULL;
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004249 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004250 OSMO_ASSERT(err_msg != NULL);
4251 OSMO_ASSERT(cfg.check_imsi == 0);
4252
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004253 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004254 OSMO_ASSERT(cfg.check_imsi == 1);
4255
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004256 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004257 OSMO_ASSERT(cfg.check_imsi == 0);
4258
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004259 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02004260 OSMO_ASSERT(cfg.check_imsi == 1);
4261
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004262 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02004263 OSMO_ASSERT(cfg.check_imsi == 0);
4264
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004265 peer = gbproxy_peer_alloc(&cfg, 20);
4266
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004267 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004268 OSMO_ASSERT(cfg.check_imsi == 1);
4269
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004270 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
4271 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004272 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004273 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004274 * case. */
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004275 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4276 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4277 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4278 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
4279 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004280
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004281 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004282 OSMO_ASSERT(cfg.check_imsi == 1);
4283
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004284 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
4285 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
4286 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4287 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4288 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4289 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
4290 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004291
4292 /* TODO: Check correct length but wrong type with is_mi_tmsi */
4293
4294 gbproxy_peer_free(peer);
4295}
4296
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004297static struct log_info_cat gprs_categories[] = {
4298 [DGPRS] = {
4299 .name = "DGPRS",
4300 .description = "GPRS Packet Service",
4301 .enabled = 1, .loglevel = LOGL_DEBUG,
4302 },
4303 [DNS] = {
4304 .name = "DNS",
4305 .description = "GPRS Network Service (NS)",
4306 .enabled = 1, .loglevel = LOGL_INFO,
4307 },
4308 [DBSSGP] = {
4309 .name = "DBSSGP",
4310 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4311 .enabled = 1, .loglevel = LOGL_DEBUG,
4312 },
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004313};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004314
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004315static struct log_info info = {
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004316 .cat = gprs_categories,
4317 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004318};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004319
4320int main(int argc, char **argv)
4321{
4322 osmo_init_logging(&info);
4323 log_set_use_color(osmo_stderr_target, 0);
4324 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02004325 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004326
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004327 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004328 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4329 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004330
4331 rate_ctr_init(NULL);
4332
4333 setlinebuf(stdout);
4334
4335 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther5eaf1a22014-08-04 11:10:09 +02004336 gbproxy_init_config(&gbcfg);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02004337 test_tlv_shift_functions();
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004338 test_gbproxy();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004339 test_gbproxy_ident_changes();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004340 test_gbproxy_imsi_matching();
Jacob Erlbeck571aec32014-09-18 09:21:20 +02004341 test_gbproxy_ptmsi_assignment();
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02004342 test_gbproxy_ra_patching();
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02004343 test_gbproxy_ptmsi_patching();
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02004344 test_gbproxy_imsi_acquisition();
Jacob Erlbeck12356062014-08-27 12:44:25 +02004345 test_gbproxy_secondary_sgsn();
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004346 test_gbproxy_keep_info();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004347 test_gbproxy_tlli_expire();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004348 printf("===== GbProxy test END\n\n");
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004349
4350 exit(EXIT_SUCCESS);
4351}