blob: b8e9cbe583167ae3bc32d52c74120f9a98948806 [file] [log] [blame]
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -04001#include <stdio.h>
2#include <stdlib.h>
3#include <inttypes.h>
4
5#include <openbsc/gprs_llc.h>
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02006#include <openbsc/gprs_utils.h>
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -04007
Jacob Erlbeckf3a271f2014-12-11 16:54:14 +01008#include <openbsc/gprs_gsup_messages.h>
9
Jacob Erlbeck0572ee02015-01-12 11:14:18 +010010#include <openbsc/debug.h>
11
12#include <osmocom/core/application.h>
13
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -040014#define ASSERT_FALSE(x) if (x) { printf("Should have returned false.\n"); abort(); }
15#define ASSERT_TRUE(x) if (!x) { printf("Should have returned true.\n"); abort(); }
16
Jacob Erlbeck0572ee02015-01-12 11:14:18 +010017#define VERBOSE_FPRINTF(...)
18
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -040019/**
20 * GSM 04.64 8.4.2 Receipt of unacknowledged information
21 */
22static int nu_is_retransmission(uint16_t nu, uint16_t vur)
23{
24 int ret = gprs_llc_is_retransmit(nu, vur);
25 printf("N(U) = %d, V(UR) = %d => %s\n", nu, vur,
26 ret == 1 ? "retransmit" : "new");
27 return ret;
28}
29
30static void test_8_4_2()
31{
32 printf("Testing gprs_llc_is_retransmit.\n");
33
34 ASSERT_FALSE(nu_is_retransmission(0, 0));
35 ASSERT_TRUE (nu_is_retransmission(0, 1));
36
37 /* expect 1... check for retransmissions */
38 ASSERT_TRUE (nu_is_retransmission(0, 1));
39 ASSERT_TRUE (nu_is_retransmission(511, 1));
40 ASSERT_TRUE (nu_is_retransmission(483, 1));
41 ASSERT_TRUE (nu_is_retransmission(482, 1));
42 ASSERT_FALSE(nu_is_retransmission(481, 1));
43
44 /* expect 511... check for retransmissions */
45 ASSERT_FALSE(nu_is_retransmission(0, 240)); // ahead
46 ASSERT_FALSE(nu_is_retransmission(0, 511)); // ahead
47 ASSERT_FALSE(nu_is_retransmission(1, 511)); // ahead
48 ASSERT_FALSE(nu_is_retransmission(511, 511)); // same
49 ASSERT_TRUE (nu_is_retransmission(510, 511)); // behind
50 ASSERT_TRUE (nu_is_retransmission(481, 511)); // behind
51 ASSERT_FALSE(nu_is_retransmission(479, 511)); // wrapped
52}
53
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +020054static void apn_round_trip(const uint8_t *input, size_t len, const char *wanted_output)
55{
56 char output[len ? len : 1];
57 uint8_t encoded[len + 50];
58 char *out_str;
59 int enc_len;
60
61 /* decode and verify we have what we want */
62 out_str = gprs_apn_to_str(output, input, len);
63 OSMO_ASSERT(out_str);
64 OSMO_ASSERT(out_str == &output[0]);
65 OSMO_ASSERT(strlen(out_str) == strlen(wanted_output));
66 OSMO_ASSERT(strcmp(out_str, wanted_output) == 0);
67
68 /* encode and verify it */
69 if (len != 0) {
70 enc_len = gprs_str_to_apn(encoded, ARRAY_SIZE(encoded), wanted_output);
71 OSMO_ASSERT(enc_len == len);
72 OSMO_ASSERT(memcmp(encoded, input, enc_len) == 0);
73 } else {
74 enc_len = gprs_str_to_apn(encoded, 0, wanted_output);
75 OSMO_ASSERT(enc_len == -1);
76 }
77}
78
79static void test_gsm_03_03_apn(void)
80{
81
82 {
83 /* test invalid writes */
84 const uint8_t ref[10] = { 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF };
85 uint8_t output[10];
86 int enc_len;
87
88 memcpy(output, ref, ARRAY_SIZE(output));
89 enc_len = gprs_str_to_apn(output, 0, "");
90 OSMO_ASSERT(enc_len == -1);
91 OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
92
93 memcpy(output, ref, ARRAY_SIZE(output));
94 enc_len = gprs_str_to_apn(output, 0, "foo");
95 OSMO_ASSERT(enc_len == -1);
96 OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
97
98 memcpy(output, ref, ARRAY_SIZE(output));
99 enc_len = gprs_str_to_apn(output, 1, "foo");
100 OSMO_ASSERT(enc_len == -1);
101 OSMO_ASSERT(memcmp(ref + 1, output + 1, ARRAY_SIZE(ref) - 1) == 0);
102
103 memcpy(output, ref, ARRAY_SIZE(output));
104 enc_len = gprs_str_to_apn(output, 2, "foo");
105 OSMO_ASSERT(enc_len == -1);
106 OSMO_ASSERT(memcmp(ref + 2, output + 2, ARRAY_SIZE(ref) - 2) == 0);
107
108 memcpy(output, ref, ARRAY_SIZE(output));
109 enc_len = gprs_str_to_apn(output, 3, "foo");
110 OSMO_ASSERT(enc_len == -1);
111 OSMO_ASSERT(memcmp(ref + 3, output + 3, ARRAY_SIZE(ref) - 3) == 0);
112 }
113
114 {
115 /* single empty label */
116 uint8_t input[] = { 0x0 };
117 const char *output = "";
118 apn_round_trip(input, ARRAY_SIZE(input), output);
119 }
120
121 {
122 /* no label */
123 uint8_t input[] = { };
124 const char *output = "";
125 apn_round_trip(input, ARRAY_SIZE(input), output);
126 }
127
128 {
129 /* single label with A */
130 uint8_t input[] = { 0x1, 65 };
131 const char *output = "A";
132 apn_round_trip(input, ARRAY_SIZE(input), output);
133 OSMO_ASSERT(gprs_apn_to_str(NULL, input, ARRAY_SIZE(input) - 1) == NULL);
134 }
135
136 {
137 uint8_t input[] = { 0x3, 65, 66, 67, 0x2, 90, 122 };
138 const char *output = "ABC.Zz";
139 char tmp[strlen(output) + 1];
140 apn_round_trip(input, ARRAY_SIZE(input), output);
141 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 1) == NULL);
142 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 2) == NULL);
143 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 4) == NULL);
144 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 5) == NULL);
145 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 6) == NULL);
146 }
147}
148
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100149/* TODO: Move tlv testing to libosmocore */
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100150static void check_tlv_parse(uint8_t **data, size_t *data_len,
151 uint8_t exp_tag, size_t exp_len, const uint8_t *exp_val)
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100152{
153 uint8_t *value;
154 size_t value_len;
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100155 uint8_t tag;
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100156 int rc;
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100157 uint8_t *saved_data = *data;
158 size_t saved_data_len = *data_len;
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100159
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100160 rc = gprs_match_tlv(data, data_len, exp_tag ^ 1, NULL, NULL);
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100161 OSMO_ASSERT(rc == 0);
162
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100163 rc = gprs_match_tlv(data, data_len, exp_tag, &value, &value_len);
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100164 OSMO_ASSERT(rc == (int)value_len + 2);
165 OSMO_ASSERT(value_len == exp_len);
166 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100167
168 /* restore data/data_len */
169 *data = saved_data;
170 *data_len = saved_data_len;
171
172 rc = gprs_shift_tlv(data, data_len, &tag, &value, &value_len);
173 OSMO_ASSERT(rc == (int)value_len + 2);
174 OSMO_ASSERT(tag == exp_tag);
175 OSMO_ASSERT(value_len == exp_len);
176 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100177}
178
179static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
180 uint8_t tag, size_t len, const uint8_t *exp_val)
181{
182 uint8_t *value;
183 int rc;
184
185 rc = gprs_match_tv_fixed(data, data_len, tag ^ 1, len, NULL);
186 OSMO_ASSERT(rc == 0);
187
188 rc = gprs_match_tv_fixed(data, data_len, tag, len, &value);
189 OSMO_ASSERT(rc == (int)len + 1);
190 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
191}
192
193static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
194 size_t len, const uint8_t *exp_val)
195{
196 uint8_t *value;
197 int rc;
198
199 rc = gprs_shift_v_fixed(data, data_len, len, &value);
200 OSMO_ASSERT(rc == (int)len);
201 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
202}
203
204static void check_lv_shift(uint8_t **data, size_t *data_len,
205 size_t exp_len, const uint8_t *exp_val)
206{
207 uint8_t *value;
208 size_t value_len;
209 int rc;
210
211 rc = gprs_shift_lv(data, data_len, &value, &value_len);
212 OSMO_ASSERT(rc == (int)value_len + 1);
213 OSMO_ASSERT(value_len == exp_len);
214 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
215}
216
217static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
218 const uint8_t *test_data)
219{
220 uint8_t buf[300] = {0};
221
222 uint8_t *unchanged_ptr = buf - 1;
223 size_t unchanged_len = 0xdead;
224 size_t tmp_data_len = data_len;
225 uint8_t *value = unchanged_ptr;
226 size_t value_len = unchanged_len;
227 uint8_t *data = buf;
228
229 OSMO_ASSERT(data_len <= sizeof(buf));
230
231 tlv_put(data, tag, len, test_data);
232 if (data_len < len + 2) {
233 OSMO_ASSERT(-1 == gprs_match_tlv(&data, &tmp_data_len,
234 tag, &value, &value_len));
235 OSMO_ASSERT(tmp_data_len == 0);
236 OSMO_ASSERT(data == buf + data_len);
237 OSMO_ASSERT(value == unchanged_ptr);
238 OSMO_ASSERT(value_len == unchanged_len);
239 } else {
240 OSMO_ASSERT(0 <= gprs_match_tlv(&data, &tmp_data_len,
241 tag, &value, &value_len));
242 OSMO_ASSERT(value != unchanged_ptr);
243 OSMO_ASSERT(value_len != unchanged_len);
244 }
245}
246
247static void check_tv_fixed_match_data_len(size_t data_len,
248 uint8_t tag, size_t len,
249 const uint8_t *test_data)
250{
251 uint8_t buf[300] = {0};
252
253 uint8_t *unchanged_ptr = buf - 1;
254 size_t tmp_data_len = data_len;
255 uint8_t *value = unchanged_ptr;
256 uint8_t *data = buf;
257
258 OSMO_ASSERT(data_len <= sizeof(buf));
259
260 tv_fixed_put(data, tag, len, test_data);
261
262 if (data_len < len + 1) {
263 OSMO_ASSERT(-1 == gprs_match_tv_fixed(&data, &tmp_data_len,
264 tag, len, &value));
265 OSMO_ASSERT(tmp_data_len == 0);
266 OSMO_ASSERT(data == buf + data_len);
267 OSMO_ASSERT(value == unchanged_ptr);
268 } else {
269 OSMO_ASSERT(0 <= gprs_match_tv_fixed(&data, &tmp_data_len,
270 tag, len, &value));
271 OSMO_ASSERT(value != unchanged_ptr);
272 }
273}
274
275static void check_v_fixed_shift_data_len(size_t data_len,
276 size_t len, const uint8_t *test_data)
277{
278 uint8_t buf[300] = {0};
279
280 uint8_t *unchanged_ptr = buf - 1;
281 size_t tmp_data_len = data_len;
282 uint8_t *value = unchanged_ptr;
283 uint8_t *data = buf;
284
285 OSMO_ASSERT(data_len <= sizeof(buf));
286
287 memcpy(data, test_data, len);
288
289 if (data_len < len) {
290 OSMO_ASSERT(-1 == gprs_shift_v_fixed(&data, &tmp_data_len,
291 len, &value));
292 OSMO_ASSERT(tmp_data_len == 0);
293 OSMO_ASSERT(data == buf + data_len);
294 OSMO_ASSERT(value == unchanged_ptr);
295 } else {
296 OSMO_ASSERT(0 <= gprs_shift_v_fixed(&data, &tmp_data_len,
297 len, &value));
298 OSMO_ASSERT(value != unchanged_ptr);
299 }
300}
301
302static void check_lv_shift_data_len(size_t data_len,
303 size_t len, const uint8_t *test_data)
304{
305 uint8_t buf[300] = {0};
306
307 uint8_t *unchanged_ptr = buf - 1;
308 size_t unchanged_len = 0xdead;
309 size_t tmp_data_len = data_len;
310 uint8_t *value = unchanged_ptr;
311 size_t value_len = unchanged_len;
312 uint8_t *data = buf;
313
314 lv_put(data, len, test_data);
315 if (data_len < len + 1) {
316 OSMO_ASSERT(-1 == gprs_shift_lv(&data, &tmp_data_len,
317 &value, &value_len));
318 OSMO_ASSERT(tmp_data_len == 0);
319 OSMO_ASSERT(data == buf + data_len);
320 OSMO_ASSERT(value == unchanged_ptr);
321 OSMO_ASSERT(value_len == unchanged_len);
322 } else {
323 OSMO_ASSERT(0 <= gprs_shift_lv(&data, &tmp_data_len,
324 &value, &value_len));
325 OSMO_ASSERT(value != unchanged_ptr);
326 OSMO_ASSERT(value_len != unchanged_len);
327 }
328}
329
330static void test_tlv_shift_functions()
331{
332 uint8_t test_data[1024];
333 uint8_t buf[1024];
334 uint8_t *data_end;
335 unsigned i, len;
336 uint8_t *data;
337 size_t data_len;
338 const uint8_t tag = 0x1a;
339
340 printf("Test shift functions\n");
341
342 for (i = 0; i < ARRAY_SIZE(test_data); i++)
343 test_data[i] = (uint8_t)i;
344
345 for (len = 0; len < 256; len++) {
346 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
347
348 memset(buf, 0xee, sizeof(buf));
349 data_end = data = buf;
350
351 for (i = 0; i < iterations; i++) {
352 data_end = tlv_put(data_end, tag, len, test_data);
353 data_end = tv_fixed_put(data_end, tag, len, test_data);
354 /* v_fixed_put */
355 memcpy(data_end, test_data, len);
356 data_end += len;
357 data_end = lv_put(data_end, len, test_data);
358 }
359
360 data_len = data_end - data;
361 OSMO_ASSERT(data_len <= sizeof(buf));
362
363 for (i = 0; i < iterations; i++) {
Jacob Erlbeck697a5342014-12-11 12:05:29 +0100364 check_tlv_parse(&data, &data_len, tag, len, test_data);
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100365 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
366 check_v_fixed_shift(&data, &data_len, len, test_data);
367 check_lv_shift(&data, &data_len, len, test_data);
368 }
369
370 OSMO_ASSERT(data == data_end);
371
372 /* Test at end of data */
373
374 OSMO_ASSERT(-1 == gprs_match_tlv(&data, &data_len, tag, NULL, NULL));
375 OSMO_ASSERT(-1 == gprs_match_tv_fixed(&data, &data_len, tag, len, NULL));
376 OSMO_ASSERT((len ? -1 : 0) == gprs_shift_v_fixed(&data, &data_len, len, NULL));
377 OSMO_ASSERT(-1 == gprs_shift_lv(&data, &data_len, NULL, NULL));
378
379 /* Test invalid data_len */
380 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
381 check_tlv_match_data_len(data_len, tag, len, test_data);
382 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
383 check_v_fixed_shift_data_len(data_len, len, test_data);
384 check_lv_shift_data_len(data_len, len, test_data);
385 }
386 }
387}
388
Jacob Erlbeckf3a271f2014-12-11 16:54:14 +0100389/* Tests for gprs_gsup_messages.c */
390
391#define TEST_IMSI_IE 0x01, 0x08, 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
392#define TEST_IMSI_STR "123456789012345"
393
394static void test_gsup_messages_dec_enc(void)
395{
396 int test_idx;
397 int rc;
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100398 uint8_t buf[1024];
Jacob Erlbeckf3a271f2014-12-11 16:54:14 +0100399
400 static const uint8_t send_auth_info_req[] = {
401 0x08,
402 TEST_IMSI_IE
403 };
404
405 static const uint8_t send_auth_info_err[] = {
406 0x09,
407 TEST_IMSI_IE,
408 0x02, 0x01, 0x07 /* GPRS no allowed */
409 };
410
411 static const uint8_t send_auth_info_res[] = {
412 0x0a,
413 TEST_IMSI_IE,
414 0x03, 0x22, /* Auth tuple */
415 0x20, 0x10,
416 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
417 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
418 0x21, 0x04,
419 0x21, 0x22, 0x23, 0x24,
420 0x22, 0x08,
421 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
422 0x03, 0x22, /* Auth tuple */
423 0x20, 0x10,
424 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
425 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
426 0x21, 0x04,
427 0xa1, 0xa2, 0xa3, 0xa4,
428 0x22, 0x08,
429 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
430 };
431
432 static const uint8_t update_location_req[] = {
433 0x04,
434 TEST_IMSI_IE,
435 };
436
437 static const uint8_t update_location_err[] = {
438 0x05,
439 TEST_IMSI_IE,
440 0x02, 0x01, 0x07 /* GPRS no allowed */
441 };
442
443 static const uint8_t update_location_res[] = {
444 0x06,
445 TEST_IMSI_IE,
446 0x04, 0x00, /* PDP info complete */
447 0x05, 0x12,
448 0x10, 0x01, 0x01,
449 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
450 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
451 0x05, 0x11,
452 0x10, 0x01, 0x02,
453 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
454 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
455 };
456
457 static const uint8_t location_cancellation_req[] = {
458 0x1c,
459 TEST_IMSI_IE,
460 0x06, 0x01, 0x00,
461 };
462
463 static const uint8_t location_cancellation_err[] = {
464 0x1d,
465 TEST_IMSI_IE,
466 0x02, 0x01, 0x03 /* Illegal MS */
467 };
468
469 static const uint8_t location_cancellation_res[] = {
470 0x1e,
471 TEST_IMSI_IE,
472 };
473
474 static const struct test {
475 char *name;
476 const uint8_t *data;
477 size_t data_len;
478 } test_messages[] = {
479 {"Send Authentication Info Request",
480 send_auth_info_req, sizeof(send_auth_info_req)},
481 {"Send Authentication Info Error",
482 send_auth_info_err, sizeof(send_auth_info_err)},
483 {"Send Authentication Info Result",
484 send_auth_info_res, sizeof(send_auth_info_res)},
485 {"Update Location Request",
486 update_location_req, sizeof(update_location_req)},
487 {"Update Location Error",
488 update_location_err, sizeof(update_location_err)},
489 {"Update Location Result",
490 update_location_res, sizeof(update_location_res)},
491 {"Location Cancellation Request",
492 location_cancellation_req, sizeof(location_cancellation_req)},
493 {"Location Cancellation Error",
494 location_cancellation_err, sizeof(location_cancellation_err)},
495 {"Location Cancellation Result",
496 location_cancellation_res, sizeof(location_cancellation_res)},
497 };
498
499 printf("Test GSUP message decoding/encoding\n");
500
501 for (test_idx = 0; test_idx < ARRAY_SIZE(test_messages); test_idx++) {
502 const struct test *t = &test_messages[test_idx];
503 struct gprs_gsup_message gm = {0};
504 struct msgb *msg = msgb_alloc(4096, "gsup_test");
505
506 printf(" Testing %s\n", t->name);
507
508 rc = gprs_gsup_decode(t->data, t->data_len, &gm);
509 OSMO_ASSERT(rc >= 0);
510
511 gprs_gsup_encode(msg, &gm);
512
513 fprintf(stderr, " generated message: %s\n", msgb_hexdump(msg));
514 fprintf(stderr, " original message: %s\n", osmo_hexdump(t->data, t->data_len));
515 fprintf(stderr, " IMSI: %s\n", gm.imsi);
516 OSMO_ASSERT(strcmp(gm.imsi, TEST_IMSI_STR) == 0);
517 OSMO_ASSERT(msgb_length(msg) == t->data_len);
518 OSMO_ASSERT(memcmp(msgb_data(msg), t->data, t->data_len) == 0);
519
520 msgb_free(msg);
521 }
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100522
523 /* simple truncation test */
524 for (test_idx = 0; test_idx < ARRAY_SIZE(test_messages); test_idx++) {
525 int j;
526 const struct test *t = &test_messages[test_idx];
527 int ie_end = t->data_len;
528 struct gprs_gsup_message gm = {0};
529 int counter = 0;
530 int parse_err = 0;
531
532 for (j = t->data_len - 1; j >= 0; --j) {
533 rc = gprs_gsup_decode(t->data, j, &gm);
534 counter += 1;
535
536 VERBOSE_FPRINTF(stderr,
537 " partial message decoding: "
538 "orig_len = %d, trunc = %d, rc = %d, ie_end = %d\n",
539 t->data_len, j, rc, ie_end);
540 if (rc >= 0) {
541 VERBOSE_FPRINTF(stderr,
542 " remaing partial message: %s\n",
543 osmo_hexdump(t->data + j, ie_end - j));
544
545 OSMO_ASSERT(j <= ie_end - 2);
546 OSMO_ASSERT(t->data[j+0] <= GPRS_GSUP_KC_IE);
547 OSMO_ASSERT(t->data[j+1] <= ie_end - j - 2);
548
549 ie_end = j;
550 } else {
551 parse_err += 1;
552 }
553 }
554
555 fprintf(stderr,
556 " message %d: tested %d truncations, %d parse failures\n",
557 test_idx, counter, parse_err);
558 }
559
560 /* message modification test (relies on ASAN or valgrind being used) */
561 for (test_idx = 0; test_idx < ARRAY_SIZE(test_messages); test_idx++) {
562 int j;
563 const struct test *t = &test_messages[test_idx];
564 struct gprs_gsup_message gm = {0};
565 uint8_t val;
566 int counter = 0;
567 int parse_err = 0;
568
569 OSMO_ASSERT(sizeof(buf) >= t->data_len);
570
571 for (j = t->data_len - 1; j >= 0; --j) {
572 memcpy(buf, t->data, t->data_len);
573 val = 0;
574 do {
575 VERBOSE_FPRINTF(stderr,
576 "t = %d, len = %d, val = %d\n",
577 test_idx, j, val);
578 buf[j] = val;
579 rc = gprs_gsup_decode(buf, t->data_len, &gm);
580 counter += 1;
581 if (rc < 0)
582 parse_err += 1;
583
584 val += 1;
585 } while (val != (uint8_t)256);
586 }
587
588 fprintf(stderr,
589 " message %d: tested %d modifications, %d parse failures\n",
590 test_idx, counter, parse_err);
591 }
Jacob Erlbeckf3a271f2014-12-11 16:54:14 +0100592}
593
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100594const struct log_info_cat default_categories[] = {
595 [DGPRS] = {
596 .name = "DGPRS",
597 .description = "GPRS Packet Service",
598 .enabled = 0, .loglevel = LOGL_DEBUG,
599 },
600};
601
602static struct log_info info = {
603 .cat = default_categories,
604 .num_cat = ARRAY_SIZE(default_categories),
605};
606
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400607int main(int argc, char **argv)
608{
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100609 osmo_init_logging(&info);
610
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400611 test_8_4_2();
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +0200612 test_gsm_03_03_apn();
Jacob Erlbeckdcfd4562014-12-11 11:01:46 +0100613 test_tlv_shift_functions();
Jacob Erlbeckf3a271f2014-12-11 16:54:14 +0100614 test_gsup_messages_dec_enc();
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400615
616 printf("Done.\n");
617 return EXIT_SUCCESS;
618}