blob: 8e8bd603f1df67999a80ac6bb368919695e479c0 [file] [log] [blame]
Harald Welte8006f532019-02-13 22:23:13 +01001#include <osmocom/core/msgb.h>
Harald Weltefbd02fa2016-04-25 15:19:35 +02002#include <osmocom/gsm/tlv.h>
Harald Welte8006f532019-02-13 22:23:13 +01003#include <osmocom/gsm/gsm0808.h>
Harald Weltefbd02fa2016-04-25 15:19:35 +02004
5static void check_tlv_parse(uint8_t **data, size_t *data_len,
6 uint8_t exp_tag, size_t exp_len, const uint8_t *exp_val)
7{
8 uint8_t *value;
9 size_t value_len;
10 uint8_t tag;
11 int rc;
12 uint8_t *saved_data = *data;
13 size_t saved_data_len = *data_len;
14
15 rc = osmo_match_shift_tlv(data, data_len, exp_tag ^ 1, NULL, NULL);
16 OSMO_ASSERT(rc == 0);
17
18 rc = osmo_match_shift_tlv(data, data_len, exp_tag, &value, &value_len);
19 OSMO_ASSERT(rc == (int)value_len + 2);
20 OSMO_ASSERT(value_len == exp_len);
21 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
22
23 /* restore data/data_len */
24 *data = saved_data;
25 *data_len = saved_data_len;
26
27 rc = osmo_shift_tlv(data, data_len, &tag, &value, &value_len);
28 OSMO_ASSERT(rc == (int)value_len + 2);
29 OSMO_ASSERT(tag == exp_tag);
30 OSMO_ASSERT(value_len == exp_len);
31 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
32}
33
34static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
35 uint8_t tag, size_t len, const uint8_t *exp_val)
36{
37 uint8_t *value;
38 int rc;
39
40 rc = osmo_match_shift_tv_fixed(data, data_len, tag ^ 1, len, NULL);
41 OSMO_ASSERT(rc == 0);
42
43 rc = osmo_match_shift_tv_fixed(data, data_len, tag, len, &value);
44 OSMO_ASSERT(rc == (int)len + 1);
45 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
46}
47
48static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
49 size_t len, const uint8_t *exp_val)
50{
51 uint8_t *value;
52 int rc;
53
54 rc = osmo_shift_v_fixed(data, data_len, len, &value);
55 OSMO_ASSERT(rc == (int)len);
56 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
57}
58
59static void check_lv_shift(uint8_t **data, size_t *data_len,
60 size_t exp_len, const uint8_t *exp_val)
61{
62 uint8_t *value;
63 size_t value_len;
64 int rc;
65
66 rc = osmo_shift_lv(data, data_len, &value, &value_len);
67 OSMO_ASSERT(rc == (int)value_len + 1);
68 OSMO_ASSERT(value_len == exp_len);
69 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
70}
71
72static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
73 const uint8_t *test_data)
74{
Pau Espin Pedrol21be8372017-06-18 00:52:56 +020075 uint8_t buf[301] = {0};
76 *buf = 0xfe;
Harald Weltefbd02fa2016-04-25 15:19:35 +020077
Pau Espin Pedrol21be8372017-06-18 00:52:56 +020078 uint8_t *unchanged_ptr = buf;
Harald Weltefbd02fa2016-04-25 15:19:35 +020079 size_t unchanged_len = 0xdead;
80 size_t tmp_data_len = data_len;
81 uint8_t *value = unchanged_ptr;
82 size_t value_len = unchanged_len;
Pau Espin Pedrol21be8372017-06-18 00:52:56 +020083 uint8_t *data = buf + 1;
Harald Weltefbd02fa2016-04-25 15:19:35 +020084
Pau Espin Pedrol21be8372017-06-18 00:52:56 +020085 OSMO_ASSERT(data_len <= sizeof(buf) - 1);
Harald Weltefbd02fa2016-04-25 15:19:35 +020086
87 tlv_put(data, tag, len, test_data);
88 if (data_len < len + 2) {
89 OSMO_ASSERT(-1 == osmo_match_shift_tlv(&data, &tmp_data_len,
90 tag, &value, &value_len));
91 OSMO_ASSERT(tmp_data_len == 0);
Pau Espin Pedrol21be8372017-06-18 00:52:56 +020092 OSMO_ASSERT(data == buf + 1 + data_len);
Harald Weltefbd02fa2016-04-25 15:19:35 +020093 OSMO_ASSERT(value == unchanged_ptr);
94 OSMO_ASSERT(value_len == unchanged_len);
95 } else {
96 OSMO_ASSERT(0 <= osmo_match_shift_tlv(&data, &tmp_data_len,
97 tag, &value, &value_len));
98 OSMO_ASSERT(value != unchanged_ptr);
99 OSMO_ASSERT(value_len != unchanged_len);
100 }
101}
102
103static void check_tv_fixed_match_data_len(size_t data_len,
104 uint8_t tag, size_t len,
105 const uint8_t *test_data)
106{
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200107 uint8_t buf[301] = {0};
108 *buf = 0xfe;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200109
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200110 uint8_t *unchanged_ptr = buf;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200111 size_t tmp_data_len = data_len;
112 uint8_t *value = unchanged_ptr;
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200113 uint8_t *data = buf + 1;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200114
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200115 OSMO_ASSERT(data_len <= sizeof(buf) - 1);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200116
117 tv_fixed_put(data, tag, len, test_data);
118
119 if (data_len < len + 1) {
120 OSMO_ASSERT(-1 == osmo_match_shift_tv_fixed(&data, &tmp_data_len,
121 tag, len, &value));
122 OSMO_ASSERT(tmp_data_len == 0);
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200123 OSMO_ASSERT(data == buf + 1 + data_len);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200124 OSMO_ASSERT(value == unchanged_ptr);
125 } else {
126 OSMO_ASSERT(0 <= osmo_match_shift_tv_fixed(&data, &tmp_data_len,
127 tag, len, &value));
128 OSMO_ASSERT(value != unchanged_ptr);
129 }
130}
131
132static void check_v_fixed_shift_data_len(size_t data_len,
133 size_t len, const uint8_t *test_data)
134{
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200135 uint8_t buf[301] = {0};
136 *buf = 0xfe;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200137
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200138 uint8_t *unchanged_ptr = buf;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200139 size_t tmp_data_len = data_len;
140 uint8_t *value = unchanged_ptr;
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200141 uint8_t *data = buf + 1;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200142
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200143 OSMO_ASSERT(data_len <= sizeof(buf) - 1);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200144
145 memcpy(data, test_data, len);
146
147 if (data_len < len) {
148 OSMO_ASSERT(-1 == osmo_shift_v_fixed(&data, &tmp_data_len,
149 len, &value));
150 OSMO_ASSERT(tmp_data_len == 0);
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200151 OSMO_ASSERT(data == buf + 1 + data_len);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200152 OSMO_ASSERT(value == unchanged_ptr);
153 } else {
154 OSMO_ASSERT(0 <= osmo_shift_v_fixed(&data, &tmp_data_len,
155 len, &value));
156 OSMO_ASSERT(value != unchanged_ptr);
157 }
158}
159
160static void check_lv_shift_data_len(size_t data_len,
161 size_t len, const uint8_t *test_data)
162{
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200163 uint8_t buf[301] = {0};
164 *buf = 0xfe;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200165
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200166 uint8_t *unchanged_ptr = buf;
Harald Weltefbd02fa2016-04-25 15:19:35 +0200167 size_t unchanged_len = 0xdead;
168 size_t tmp_data_len = data_len;
169 uint8_t *value = unchanged_ptr;
170 size_t value_len = unchanged_len;
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200171 uint8_t *data = buf + 1;
172
173 OSMO_ASSERT(data_len <= sizeof(buf) - 1);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200174
175 lv_put(data, len, test_data);
176 if (data_len < len + 1) {
177 OSMO_ASSERT(-1 == osmo_shift_lv(&data, &tmp_data_len,
178 &value, &value_len));
179 OSMO_ASSERT(tmp_data_len == 0);
Pau Espin Pedrol21be8372017-06-18 00:52:56 +0200180 OSMO_ASSERT(data == buf + 1 + data_len);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200181 OSMO_ASSERT(value == unchanged_ptr);
182 OSMO_ASSERT(value_len == unchanged_len);
183 } else {
184 OSMO_ASSERT(0 <= osmo_shift_lv(&data, &tmp_data_len,
185 &value, &value_len));
186 OSMO_ASSERT(value != unchanged_ptr);
187 OSMO_ASSERT(value_len != unchanged_len);
188 }
189}
190
Harald Weltee61d4592022-11-03 11:05:58 +0100191static void test_tlv_shift_functions(void)
Harald Weltefbd02fa2016-04-25 15:19:35 +0200192{
193 uint8_t test_data[1024];
194 uint8_t buf[1024];
195 uint8_t *data_end;
196 unsigned i, len;
197 uint8_t *data;
198 size_t data_len;
199 const uint8_t tag = 0x1a;
200
201 printf("Test shift functions\n");
202
203 for (i = 0; i < ARRAY_SIZE(test_data); i++)
204 test_data[i] = (uint8_t)i;
205
206 for (len = 0; len < 256; len++) {
207 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
208
209 memset(buf, 0xee, sizeof(buf));
210 data_end = data = buf;
211
212 for (i = 0; i < iterations; i++) {
213 data_end = tlv_put(data_end, tag, len, test_data);
214 data_end = tv_fixed_put(data_end, tag, len, test_data);
215 /* v_fixed_put */
216 memcpy(data_end, test_data, len);
217 data_end += len;
218 data_end = lv_put(data_end, len, test_data);
219 }
220
221 data_len = data_end - data;
222 OSMO_ASSERT(data_len <= sizeof(buf));
223
224 for (i = 0; i < iterations; i++) {
225 check_tlv_parse(&data, &data_len, tag, len, test_data);
226 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
227 check_v_fixed_shift(&data, &data_len, len, test_data);
228 check_lv_shift(&data, &data_len, len, test_data);
229 }
230
231 OSMO_ASSERT(data == data_end);
232
233 /* Test at end of data */
234
235 OSMO_ASSERT(-1 == osmo_match_shift_tlv(&data, &data_len, tag, NULL, NULL));
236 OSMO_ASSERT(-1 == osmo_match_shift_tv_fixed(&data, &data_len, tag, len, NULL));
237 OSMO_ASSERT((len ? -1 : 0) == osmo_shift_v_fixed(&data, &data_len, len, NULL));
238 OSMO_ASSERT(-1 == osmo_shift_lv(&data, &data_len, NULL, NULL));
239
240 /* Test invalid data_len */
241 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
242 check_tlv_match_data_len(data_len, tag, len, test_data);
243 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
244 check_v_fixed_shift_data_len(data_len, len, test_data);
245 check_lv_shift_data_len(data_len, len, test_data);
246 }
247 }
248}
249
Stefan Sperlingc9bebbd2018-03-16 15:59:01 +0100250/* Most GSM related protocols clearly indicate that in case of duplicate
251 * IEs, only the first occurrence shall be used, while any further occurrences
252 * shall be ignored. See e.g. 3GPP TS 24.008 Section 8.6.3 */
Harald Weltee61d4592022-11-03 11:05:58 +0100253static void test_tlv_repeated_ie(void)
Stefan Sperlingc9bebbd2018-03-16 15:59:01 +0100254{
255 uint8_t test_data[768];
256 int i, rc;
257 const uint8_t tag = 0x1a;
258 struct tlv_parsed dec;
Neels Hofmeyra78b22b2018-04-13 03:36:49 +0200259 struct tlv_parsed dec3[3];
Stefan Sperlingc9bebbd2018-03-16 15:59:01 +0100260 struct tlv_definition def;
261
262 memset(&def, 0, sizeof(def));
263
264 /* tag:1:255, tag:1:254, tag:1:253, ..., tag:1:3, tag:1:2, tag:1:1, tag:1:0 */
265 for (i = 0; i < ARRAY_SIZE(test_data) - 1; i += 3) {
266 test_data[i] = tag;
267 test_data[i + 1] = 1;
268 test_data[i + 2] = (uint8_t)(0xff - i/2);
269 }
270
271 def.def[tag].type = TLV_TYPE_TLV;
272
273 rc = tlv_parse(&dec, &def, &test_data[1], sizeof(test_data) - 1, tag, 0);
274 OSMO_ASSERT(rc == i/3);
275 OSMO_ASSERT(dec.lv[tag].len == 1);
276 /* Value pointer should point at first value in test data array. */
277 OSMO_ASSERT(dec.lv[tag].val == &test_data[2]);
278 OSMO_ASSERT(*dec.lv[tag].val == test_data[2]);
Neels Hofmeyra78b22b2018-04-13 03:36:49 +0200279
280 /* Accept three decodings, pointing at first, second and third val */
281 rc = tlv_parse2(dec3, 3, &def, &test_data[1], sizeof(test_data) - 1, tag, 0);
282 OSMO_ASSERT(rc == i/3);
283 OSMO_ASSERT(dec3[0].lv[tag].len == 1);
284 OSMO_ASSERT(dec3[0].lv[tag].val == &test_data[2]);
285 OSMO_ASSERT(dec3[1].lv[tag].len == 1);
286 OSMO_ASSERT(dec3[1].lv[tag].val == &test_data[2 + 3]);
287 OSMO_ASSERT(dec3[2].lv[tag].len == 1);
288 OSMO_ASSERT(dec3[2].lv[tag].val == &test_data[2 + 3 + 3]);
Stefan Sperlingc9bebbd2018-03-16 15:59:01 +0100289}
290
Harald Weltee61d4592022-11-03 11:05:58 +0100291static void test_tlv_encoder(void)
Harald Welte8006f532019-02-13 22:23:13 +0100292{
293 const uint8_t enc_ies[] = {
294 0x17, 0x14, 0x06, 0x2b, 0x12, 0x2b, 0x0b, 0x40, 0x2b, 0xb7, 0x05, 0xd0, 0x63, 0x82, 0x95, 0x03, 0x05, 0x40,
295 0x07, 0x08, 0x43, 0x90,
296 0x2c, 0x04,
297 0x40, 0x42,
298 };
299 const uint8_t ie_order[] = { 0x2c, 0x40, 0x17 };
300 const uint8_t enc_ies_reordered[] = {
301 0x2c, 0x04,
302 0x40, 0x42,
303 0x17, 0x14, 0x06, 0x2b, 0x12, 0x2b, 0x0b, 0x40, 0x2b, 0xb7, 0x05, 0xd0, 0x63, 0x82, 0x95, 0x03, 0x05, 0x40,
304 0x07, 0x08, 0x43, 0x90,
305 };
306 struct tlv_parsed tp;
307 struct msgb *msg = msgb_alloc(1024, __func__);
308 int rc;
309
310 printf("Testing TLV encoder by decoding + re-encoding binary\n");
311
312 OSMO_ASSERT(msg);
313
314 /* decode BSSAP IEs specified above */
315 rc = osmo_bssap_tlv_parse(&tp, enc_ies, ARRAY_SIZE(enc_ies));
316 OSMO_ASSERT(rc == 3);
317
318 /* re-encode it */
319 rc = tlv_encode(msg, gsm0808_att_tlvdef(), &tp);
320 OSMO_ASSERT(rc == ARRAY_SIZE(enc_ies));
321 OSMO_ASSERT(!memcmp(msgb_data(msg), enc_ies, ARRAY_SIZE(enc_ies)));
322
323 msgb_reset(msg);
324
325 printf("Testing TLV encoder with IE ordering\n");
326
327 /* re-encodei in different order */
328 rc = tlv_encode_ordered(msg, gsm0808_att_tlvdef(), &tp, ie_order, ARRAY_SIZE(ie_order));
329 OSMO_ASSERT(rc == ARRAY_SIZE(enc_ies));
330 OSMO_ASSERT(!memcmp(msgb_data(msg), enc_ies_reordered, ARRAY_SIZE(enc_ies_reordered)));
331
332 msgb_free(msg);
333}
334
Harald Weltee61d4592022-11-03 11:05:58 +0100335static void test_tlv_parser_bounds(void)
Harald Welteefdd6412021-01-12 18:07:18 +0100336{
337 struct tlv_definition tdef;
338 struct tlv_parsed dec;
339 uint8_t buf[32];
340
341 memset(&tdef, 0, sizeof(tdef));
342
343 printf("Testing TLV_TYPE_T decoder for out-of-bounds\n");
344 tdef.def[0x23].type = TLV_TYPE_T;
345 buf[0] = 0x23;
346 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == 1);
347 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 0, 0, 0) == 0);
348
349 printf("Testing TLV_TYPE_TV decoder for out-of-bounds\n");
350 tdef.def[0x23].type = TLV_TYPE_TV;
351 buf[0] = 0x23;
352 buf[1] = 0x42;
353 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == 1);
354 OSMO_ASSERT(*TLVP_VAL(&dec, 0x23) == buf[1]);
355 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
356 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
357
358 printf("Testing TLV_TYPE_FIXED decoder for out-of-bounds\n");
359 tdef.def[0x23].type = TLV_TYPE_FIXED;
360 tdef.def[0x23].fixed_len = 2;
361 buf[0] = 0x23;
362 buf[1] = 0x42;
363 buf[2] = 0x55;
364 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == 1);
365 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
366 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
367
368 printf("Testing TLV_TYPE_TLV decoder for out-of-bounds\n");
369 tdef.def[0x23].type = TLV_TYPE_TLV;
370 buf[0] = 0x23;
371 buf[1] = 0x02;
372 buf[2] = 0x55;
373 buf[3] = 0xAA;
374 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
375 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[2]);
376 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
377 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
378 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
379 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
380 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
381 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
382
383 printf("Testing TLV_TYPE_vTvLV_GAN decoder for out-of-bounds\n");
384 tdef.def[0x23].type = TLV_TYPE_vTvLV_GAN;
385 buf[0] = 0x23;
386 buf[1] = 0x80;
387 buf[2] = 0x01;
388 buf[3] = 0xAA;
389 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
390 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[3]);
391 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
392 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
393 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
394 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
395 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
396 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
397
398 printf("Testing TLV_TYPE_TvLV decoder for out-of-bounds\n");
399 tdef.def[0x23].type = TLV_TYPE_TvLV;
400 buf[0] = 0x23;
401 buf[1] = 0x81;
402 buf[2] = 0xAA;
403 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == 1);
404 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[2]);
405 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
406 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
407 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
408 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
409
410 printf("Testing TLV_TYPE_TL16V decoder for out-of-bounds\n");
411 tdef.def[0x23].type = TLV_TYPE_TL16V;
412 buf[0] = 0x23;
413 buf[1] = 0x00;
414 buf[2] = 0x01;
415 buf[3] = 0xAA;
416 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 4, 0, 0) == 1);
417 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == &buf[3]);
418 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 3, 0, 0) == OSMO_TLVP_ERR_OFS_LEN_BEYOND_BUFFER);
419 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
420 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 2, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
421 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
422 OSMO_ASSERT(tlv_parse(&dec, &tdef, buf, 1, 0, 0) == OSMO_TLVP_ERR_OFS_BEYOND_BUFFER);
423 OSMO_ASSERT(TLVP_VAL(&dec, 0x23) == NULL);
424}
425
Harald Weltee61d4592022-11-03 11:05:58 +0100426static void test_tlv_lens(void)
Daniel Willmann2fa0e9d2021-03-17 16:24:15 +0100427{
428 uint16_t buf_len;
429 uint8_t buf[512];
430 uint8_t val[512] = { 0 };
431 uint16_t x;
432
433
434 for (x = 0; x < 16; x++) {
435 buf_len = lv_put(buf, x, val) - buf;
436 OSMO_ASSERT(buf_len == LV_GROSS_LEN(x));
437 buf_len = tlv_put(buf, 0x23, x, val) - buf;
438 OSMO_ASSERT(buf_len == TLV_GROSS_LEN(x));
439 buf_len = tlv16_put(buf, 0x23, x, (uint16_t *) val) - buf;
440 OSMO_ASSERT(buf_len == TLV16_GROSS_LEN(x));
441 buf_len = tl16v_put(buf, 0x23, x, val) - buf;
442 OSMO_ASSERT(buf_len == TL16V_GROSS_LEN(x));
443 buf_len = t16lv_put(buf, 0x2342, x, val) - buf;
444 OSMO_ASSERT(buf_len == T16LV_GROSS_LEN(x));
445 buf_len = tvlv_put(buf, 0x23, x, val) - buf;
446 OSMO_ASSERT(buf_len == TVLV_GROSS_LEN(x));
447 }
448
449 for (x = 250; x < 300; x++) {
450 buf_len = tl16v_put(buf, 0x23, x, val) - buf;
451 OSMO_ASSERT(buf_len == TL16V_GROSS_LEN(x));
452 buf_len = tvlv_put(buf, 0x23, x, val) - buf;
453 OSMO_ASSERT(buf_len == TVLV_GROSS_LEN(x));
454 }
455}
456
Pau Espin Pedrole2217ee2023-05-02 12:11:22 +0200457static void test_tlv_type_single_tv(void)
458{
459 #define SAMPLE_SINGLE_TV_IE 0x08
460 const struct tlv_definition att_tlvdef = {
461 .def = {
462 [SAMPLE_SINGLE_TV_IE] = { TLV_TYPE_SINGLE_TV, 0 },
463 },
464 };
465 struct tlv_parsed tp;
466 int rc;
467 uint8_t exp_val = 0x03;
468 uint8_t buf[] = { (SAMPLE_SINGLE_TV_IE << 4) | (exp_val & 0x0f) };
469 const uint8_t *val;
470
471 rc = tlv_parse(&tp, &att_tlvdef, buf, sizeof(buf), 0, 0);
472 OSMO_ASSERT(rc == 1);
Pau Espin Pedrolbeb7c172023-04-28 17:33:36 +0200473 OSMO_ASSERT(TLVP_PRESENT(&tp, SAMPLE_SINGLE_TV_IE));
Pau Espin Pedrole2217ee2023-05-02 12:11:22 +0200474 val = TLVP_VAL(&tp, SAMPLE_SINGLE_TV_IE);
Pau Espin Pedrolbeb7c172023-04-28 17:33:36 +0200475 OSMO_ASSERT(val);
Pau Espin Pedrole2217ee2023-05-02 12:11:22 +0200476 OSMO_ASSERT(val == &buf[0]);
477 OSMO_ASSERT(*val == buf[0]);
478 OSMO_ASSERT((*val & 0x0f) == exp_val);
Pau Espin Pedrole2217ee2023-05-02 12:11:22 +0200479}
480
Harald Weltefbd02fa2016-04-25 15:19:35 +0200481int main(int argc, char **argv)
482{
Neels Hofmeyra829b452018-04-05 03:02:35 +0200483 //osmo_init_logging2(ctx, &info);
Harald Weltefbd02fa2016-04-25 15:19:35 +0200484
485 test_tlv_shift_functions();
Stefan Sperlingc9bebbd2018-03-16 15:59:01 +0100486 test_tlv_repeated_ie();
Harald Welte8006f532019-02-13 22:23:13 +0100487 test_tlv_encoder();
Harald Welteefdd6412021-01-12 18:07:18 +0100488 test_tlv_parser_bounds();
Daniel Willmann2fa0e9d2021-03-17 16:24:15 +0100489 test_tlv_lens();
Pau Espin Pedrole2217ee2023-05-02 12:11:22 +0200490 test_tlv_type_single_tv();
Harald Weltefbd02fa2016-04-25 15:19:35 +0200491
492 printf("Done.\n");
493 return EXIT_SUCCESS;
494}