blob: 711d6e12c67930f63623104f16cd6ab4c292c97c [file] [log] [blame]
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +01001/* tests for utilities of libmsomcore */
2/*
3 * (C) 2014 Holger Hans Peter Freyther
4 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +020023#include <osmocom/gsm/ipa.h>
Harald Welte7869baf2018-07-31 20:25:48 +020024#include <osmocom/gsm/protocol/ipaccess.h>
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +020025
26#include <osmocom/core/logging.h>
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010027#include <osmocom/core/utils.h>
Neels Hofmeyr59f4caf2018-07-19 22:13:19 +020028#include <osmocom/core/socket.h>
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010029
30#include <stdio.h>
Harald Welte504caac2017-10-27 17:19:59 +020031#include <ctype.h>
Harald Welte15a5f8d2018-06-06 16:58:17 +020032#include <time.h>
Neels Hofmeyr59f4caf2018-07-19 22:13:19 +020033#include <netinet/in.h>
34#include <arpa/inet.h>
Neels Hofmeyr7079e692018-12-05 21:02:36 +010035#include <errno.h>
Neels Hofmeyr2cbe25f2019-02-11 20:32:06 +010036#include <limits.h>
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010037
38static void hexdump_test(void)
39{
40 uint8_t data[4098];
Neels Hofmeyr0423b612019-01-14 23:32:53 +010041 char buf[256];
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010042 int i;
43
44 for (i = 0; i < ARRAY_SIZE(data); ++i)
45 data[i] = i & 0xff;
46
47 printf("Plain dump\n");
48 printf("%s\n", osmo_hexdump(data, 4));
Neels Hofmeyr0423b612019-01-14 23:32:53 +010049 printf("%s\n", osmo_hexdump_nospc(data, 4));
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010050
51 printf("Corner case\n");
52 printf("%s\n", osmo_hexdump(data, ARRAY_SIZE(data)));
53 printf("%s\n", osmo_hexdump_nospc(data, ARRAY_SIZE(data)));
Neels Hofmeyr0423b612019-01-14 23:32:53 +010054
55#define _HEXDUMP_BUF_TEST(SIZE, DELIM, DELIM_AFTER) \
56 buf[0] = '!'; \
57 buf[1] = '\0'; \
58 printf("osmo_hexdump_buf(buf, " #SIZE ", data, 4, %s, " #DELIM_AFTER ")\n = \"%s\"\n", \
59 DELIM ? #DELIM : "NULL", \
60 osmo_hexdump_buf(buf, SIZE, data, 4, DELIM, DELIM_AFTER))
61#define HEXDUMP_BUF_TEST(DELIM) \
62 _HEXDUMP_BUF_TEST(sizeof(buf), DELIM, false); \
63 _HEXDUMP_BUF_TEST(sizeof(buf), DELIM, true); \
64 _HEXDUMP_BUF_TEST(6, DELIM, false); \
65 _HEXDUMP_BUF_TEST(7, DELIM, false); \
66 _HEXDUMP_BUF_TEST(8, DELIM, false); \
67 _HEXDUMP_BUF_TEST(6, DELIM, true); \
68 _HEXDUMP_BUF_TEST(7, DELIM, true); \
69 _HEXDUMP_BUF_TEST(8, DELIM, true)
70
71 HEXDUMP_BUF_TEST("[delim]");
72 HEXDUMP_BUF_TEST(" ");
73 HEXDUMP_BUF_TEST(":");
74 HEXDUMP_BUF_TEST("::");
75 HEXDUMP_BUF_TEST("");
76 HEXDUMP_BUF_TEST(NULL);
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +010077}
78
Neels Hofmeyr7adb5672017-02-14 15:48:19 +010079static void hexparse_test(void)
80{
81 int i;
82 int rc;
83 uint8_t data[256];
84
85 printf("\nHexparse 0..255 in lower case\n");
86 memset(data, 0, sizeof(data));
87 rc = osmo_hexparse(
88 "000102030405060708090a0b0c0d0e0f"
89 "101112131415161718191a1b1c1d1e1f"
90 "202122232425262728292a2b2c2d2e2f"
91 "303132333435363738393a3b3c3d3e3f"
92 "404142434445464748494a4b4c4d4e4f"
93 "505152535455565758595a5b5c5d5e5f"
94 "606162636465666768696a6b6c6d6e6f"
95 "707172737475767778797a7b7c7d7e7f"
96 "808182838485868788898a8b8c8d8e8f"
97 "909192939495969798999a9b9c9d9e9f"
98 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
99 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
100 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
101 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
102 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
103 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
104 , data, sizeof(data));
105 printf("rc = %d\n", rc);
106 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
107 for (i = 0; i < sizeof(data); i++)
108 OSMO_ASSERT(data[i] == i);
109
110 printf("Hexparse 0..255 in upper case\n");
111 memset(data, 0, sizeof(data));
112 rc = osmo_hexparse(
113 "000102030405060708090A0B0C0D0E0F"
114 "101112131415161718191A1B1C1D1E1F"
115 "202122232425262728292A2B2C2D2E2F"
116 "303132333435363738393A3B3C3D3E3F"
117 "404142434445464748494A4B4C4D4E4F"
118 "505152535455565758595A5B5C5D5E5F"
119 "606162636465666768696A6B6C6D6E6F"
120 "707172737475767778797A7B7C7D7E7F"
121 "808182838485868788898A8B8C8D8E8F"
122 "909192939495969798999A9B9C9D9E9F"
123 "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"
124 "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"
125 "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"
126 "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"
127 "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
128 "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"
129 , data, sizeof(data));
130 printf("rc = %d\n", rc);
131 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
132 for (i = 0; i < sizeof(data); i++)
133 OSMO_ASSERT(data[i] == i);
134
135 printf("Hexparse 0..255 in mixed case\n");
136 memset(data, 0, sizeof(data));
137 rc = osmo_hexparse(
138 "000102030405060708090A0B0C0D0E0F"
139 "101112131415161718191A1B1C1D1E1F"
140 "202122232425262728292A2B2C2D2E2F"
141 "303132333435363738393a3b3c3d3e3f"
142 "404142434445464748494A4B4C4D4E4F"
143 "505152535455565758595a5b5c5d5e5f"
144 "606162636465666768696A6B6C6D6E6F"
145 "707172737475767778797A7B7C7D7E7F"
146 "808182838485868788898A8B8C8D8E8F"
147 "909192939495969798999A9B9C9D9E9F"
148 "A0A1A2A3a4a5a6a7a8a9AAABACADAEAF"
149 "B0B1B2B3b4b5b6b7b8b9BABBBCBDBEBF"
150 "C0C1C2C3c4c5c6c7c8c9CACBCCCDCECF"
151 "D0D1D2D3d4d5d6d7d8d9DADBDCDDDEDF"
152 "E0E1E2E3e4e5e6e7e8e9EAEBECEDEEEF"
153 "F0F1F2F3f4f5f6f7f8f9FAFBFCFDFEFF"
154 , data, sizeof(data));
155 printf("rc = %d\n", rc);
156 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
157 for (i = 0; i < sizeof(data); i++)
158 OSMO_ASSERT(data[i] == i);
159
Neels Hofmeyr437ed4a2017-02-14 15:54:31 +0100160 printf("Hexparse 0..255 with whitespace\n");
161 memset(data, 0, sizeof(data));
162 rc = osmo_hexparse(
163 "00 01\t02\r030405060708090A0B0C0D0 E 0 F\n"
164 "10 11\t12\r131415161718191A1B1C1D1 E 1 F\n"
165 "20 21\t22\r232425262728292A2B2C2D2 E 2 F\n"
166 "30 31\t32\r333435363738393a3b3c3d3 e 3 f\n"
167 "40 41\t42\r434445464748494A4B4C4D4 E 4 F\n"
168 "50 51\t52\r535455565758595a5b5c5d5 e 5 f\n"
169 "60 61\t62\r636465666768696A6B6C6D6 E 6 F\n"
170 "70 71\t72\r737475767778797A7B7C7D7 E 7 F\n"
171 "80 81\t82\r838485868788898A8B8C8D8 E 8 F\n"
172 "90 91\t92\r939495969798999A9B9C9D9 E 9 F\n"
173 "A0 A1\tA2\rA3a4a5a6a7a8a9AAABACADA E A F\n"
174 "B0 B1\tB2\rB3b4b5b6b7b8b9BABBBCBDB E B F\n"
175 "C0 C1\tC2\rC3c4c5c6c7c8c9CACBCCCDC E C F \n"
176 "D0 D1\tD2\rD3d4d5d6d7d8d9DADBDCDDD E D F\t\n"
177 "E0 E1\tE2\rE3e4e5e6e7e8e9EAEBECEDE E E F \t\n"
178 "F0 F1\tF2\rF3f4f5f6f7f8f9FAFBFCFDF E F F \t\r\n"
179 , data, sizeof(data));
180 printf("rc = %d\n", rc);
181 printf("--> %s\n\n", osmo_hexdump(data, sizeof(data)));
182 for (i = 0; i < sizeof(data); i++)
183 OSMO_ASSERT(data[i] == i);
184
Neels Hofmeyr7adb5672017-02-14 15:48:19 +0100185 printf("Hexparse with buffer too short\n");
186 memset(data, 0, sizeof(data));
187 rc = osmo_hexparse("000102030405060708090a0b0c0d0e0f", data, 15);
188 printf("rc = %d\n", rc);
189
190 printf("Hexparse with uneven amount of digits\n");
191 memset(data, 0, sizeof(data));
192 rc = osmo_hexparse("000102030405060708090a0b0c0d0e0", data, 16);
193 printf("rc = %d\n", rc);
194
195 printf("Hexparse with invalid char\n");
196 memset(data, 0, sizeof(data));
197 rc = osmo_hexparse("0001020304050X0708090a0b0c0d0e0f", data, 16);
198 printf("rc = %d\n", rc);
199}
200
Harald Welte7869baf2018-07-31 20:25:48 +0200201static void test_ipa_ccm_id_resp_parsing(void)
202{
203 struct tlv_parsed tvp;
204 int rc;
205
206 static const uint8_t id_resp_data[] = {
207 0x00, 0x13, IPAC_IDTAG_MACADDR,
208 '0','0',':','0','2',':','9','5',':','0','0',':','6','2',':','9','e','\0',
209 0x00, 0x11, IPAC_IDTAG_IPADDR,
210 '1','9','2','.','1','6','8','.','1','0','0','.','1','9','0','\0',
211 0x00, 0x0a, IPAC_IDTAG_UNIT,
212 '1','2','3','4','/','0','/','0','\0',
213 0x00, 0x02, IPAC_IDTAG_LOCATION1,
214 '\0',
215 0x00, 0x0d, IPAC_IDTAG_LOCATION2,
216 'B','T','S','_','N','B','T','1','3','1','G','\0',
217 0x00, 0x0c, IPAC_IDTAG_EQUIPVERS,
218 '1','6','5','a','0','2','9','_','5','5','\0',
219 0x00, 0x14, IPAC_IDTAG_SWVERSION,
220 '1','6','8','d','4','7','2','_','v','2','0','0','b','4','1','1','d','0','\0',
221 0x00, 0x18, IPAC_IDTAG_UNITNAME,
222 'n','b','t','s','-','0','0','-','0','2','-','9','5','-','0','0','-','6','2','-','9','E','\0',
223 0x00, 0x0a, IPAC_IDTAG_SERNR,
224 '0','0','1','1','0','7','8','1','\0'
225 };
226
227 printf("\nTesting IPA CCM ID RESP parsing\n");
228
229 rc = ipa_ccm_id_resp_parse(&tvp, (uint8_t *) id_resp_data, sizeof(id_resp_data));
230 OSMO_ASSERT(rc == 0);
231
232 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_MACADDR));
233 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_MACADDR) == 0x12);
234 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_IPADDR));
235 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_IPADDR) == 0x10);
236 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNIT));
237 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNIT) == 0x09);
238 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION1));
239 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION1) == 0x01);
240 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_LOCATION2));
241 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_LOCATION2) == 0x0c);
242 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_EQUIPVERS));
243 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);
244 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SWVERSION));
245 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_EQUIPVERS) == 0x0b);
246 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SWVERSION) == 0x13);
247 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME));
248 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_UNITNAME) == 0x17);
249 OSMO_ASSERT(TLVP_PRESENT(&tvp, IPAC_IDTAG_SERNR));
250 OSMO_ASSERT(TLVP_LEN(&tvp, IPAC_IDTAG_SERNR) == 0x09);
251}
252
253static void test_ipa_ccm_id_get_parsing(void)
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200254{
255 struct tlv_parsed tvp;
256 int rc;
257
Harald Welte48fd0192018-07-31 20:19:49 +0200258 /* IPA CCM IDENTITY REQUEST message: 8bit length followed by respective value */
Harald Welte7869baf2018-07-31 20:25:48 +0200259 static const uint8_t id_get_data[] = {
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200260 0x01, 0x08,
261 0x01, 0x07,
262 0x01, 0x02,
263 0x01, 0x03,
264 0x01, 0x04,
265 0x01, 0x05,
266 0x01, 0x01,
267 0x01, 0x00,
268 0x11, 0x23, 0x4e, 0x6a, 0x28, 0xd2, 0xa2, 0x53, 0x3a, 0x2a, 0x82, 0xa7, 0x7a, 0xef, 0x29, 0xd4, 0x44, 0x30,
269 0x11, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
270 };
271
Harald Welte7869baf2018-07-31 20:25:48 +0200272 printf("\nTesting IPA CCM ID GET parsing\n");
273
274 rc = ipa_ccm_id_get_parse(&tvp, id_get_data, sizeof(id_get_data));
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +0200275 OSMO_ASSERT(rc == 0);
276
277 OSMO_ASSERT(TLVP_PRESENT(&tvp, 8));
278 OSMO_ASSERT(TLVP_LEN(&tvp, 8) == 0);
279
280 OSMO_ASSERT(TLVP_PRESENT(&tvp, 7));
281 OSMO_ASSERT(TLVP_LEN(&tvp, 7) == 0);
282
283 OSMO_ASSERT(TLVP_PRESENT(&tvp, 2));
284 OSMO_ASSERT(TLVP_LEN(&tvp, 2) == 0);
285
286 OSMO_ASSERT(TLVP_PRESENT(&tvp, 3));
287 OSMO_ASSERT(TLVP_LEN(&tvp, 3) == 0);
288
289 OSMO_ASSERT(TLVP_PRESENT(&tvp, 4));
290 OSMO_ASSERT(TLVP_LEN(&tvp, 4) == 0);
291
292 OSMO_ASSERT(TLVP_PRESENT(&tvp, 5));
293 OSMO_ASSERT(TLVP_LEN(&tvp, 5) == 0);
294
295 OSMO_ASSERT(TLVP_PRESENT(&tvp, 1));
296 OSMO_ASSERT(TLVP_LEN(&tvp, 1) == 0);
297
298 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0));
299 OSMO_ASSERT(TLVP_LEN(&tvp, 0) == 0);
300
301 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0x23));
302 OSMO_ASSERT(TLVP_LEN(&tvp, 0x23) == 16);
303
304 OSMO_ASSERT(TLVP_PRESENT(&tvp, 0x24));
305 OSMO_ASSERT(TLVP_LEN(&tvp, 0x24) == 16);
306
307 OSMO_ASSERT(!TLVP_PRESENT(&tvp, 0x25));
308}
309
Neels Hofmeyr4335bad2017-10-07 04:39:14 +0200310static struct {
311 const char *str;
312 int min_digits;
313 int max_digits;
314 bool require_even;
315 bool expect_ok;
316} test_hexstrs[] = {
317 { NULL, 0, 10, false, true },
318 { NULL, 1, 10, false, false },
319 { "", 0, 10, false, true },
320 { "", 1, 10, false, false },
321 { " ", 0, 10, false, false },
322 { "1", 0, 10, false, true },
323 { "1", 1, 10, false, true },
324 { "1", 1, 10, true, false },
325 { "1", 2, 10, false, false },
326 { "123", 1, 10, false, true },
327 { "123", 1, 10, true, false },
328 { "123", 4, 10, false, false },
329 { "1234", 4, 10, true, true },
330 { "12345", 4, 10, true, false },
331 { "123456", 4, 10, true, true },
332 { "1234567", 4, 10, true, false },
333 { "12345678", 4, 10, true, true },
334 { "123456789", 4, 10, true, false },
335 { "123456789a", 4, 10, true, true },
336 { "123456789ab", 4, 10, true, false },
337 { "123456789abc", 4, 10, true, false },
338 { "123456789ab", 4, 10, false, false },
339 { "123456789abc", 4, 10, false, false },
340 { "0123456789abcdefABCDEF", 0, 100, false, true },
341 { "0123456789 abcdef ABCDEF", 0, 100, false, false },
342 { "foobar", 0, 100, false, false },
343 { "BeadedBeeAced1EbbedDefacedFacade", 32, 32, true, true },
344 { "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 32, 32, false, true },
345 { "DeafBeddedBabeAcceededFadedDecaff", 32, 32, false, false },
346};
347
348bool test_is_hexstr()
349{
350 int i;
351 bool pass = true;
352 bool ok = true;
353 printf("\n----- %s\n", __func__);
354
355 for (i = 0; i < ARRAY_SIZE(test_hexstrs); i++) {
356 ok = osmo_is_hexstr(test_hexstrs[i].str,
357 test_hexstrs[i].min_digits,
358 test_hexstrs[i].max_digits,
359 test_hexstrs[i].require_even);
360 pass = pass && (ok == test_hexstrs[i].expect_ok);
361 printf("%2d: %s str='%s' min=%d max=%d even=%d expect=%s\n",
362 i, test_hexstrs[i].expect_ok == ok ? "pass" : "FAIL",
363 test_hexstrs[i].str,
364 test_hexstrs[i].min_digits,
365 test_hexstrs[i].max_digits,
366 test_hexstrs[i].require_even,
367 test_hexstrs[i].expect_ok ? "valid" : "invalid");
368 }
369 return pass;
370}
371
Harald Welte504caac2017-10-27 17:19:59 +0200372struct bcdcheck {
373 uint8_t bcd;
374 char ch;
375};
376
377static const struct bcdcheck bcdchecks[] = {
378 { 0, '0' },
379 { 1, '1' },
380 { 2, '2' },
381 { 3, '3' },
382 { 4, '4' },
383 { 5, '5' },
384 { 6, '6' },
385 { 7, '7' },
386 { 8, '8' },
387 { 9, '9' },
388 { 0xA, 'A' },
389 { 0xB, 'B' },
390 { 0xC, 'C' },
391 { 0xD, 'D' },
392 { 0xE, 'E' },
393 { 0xF, 'F' },
394};
395
396static void bcd_test(void)
397{
398 int i;
399
400 printf("\nTesting BCD conversion\n");
401 for (i = 0; i < ARRAY_SIZE(bcdchecks); i++) {
402 const struct bcdcheck *check = &bcdchecks[i];
403 char ch = osmo_bcd2char(check->bcd);
404 printf("\tval=0x%x, expected=%c, found=%c\n", check->bcd, check->ch, ch);
405 OSMO_ASSERT(osmo_bcd2char(check->bcd) == check->ch);
406 /* test char -> bcd back-coversion */
407 OSMO_ASSERT(osmo_char2bcd(ch) == check->bcd);
408 /* test for lowercase hex char */
409 OSMO_ASSERT(osmo_char2bcd(tolower(ch)) == check->bcd);
410 }
411}
412
Neels Hofmeyr7079e692018-12-05 21:02:36 +0100413struct bcd2str_test {
414 const char *bcd_hex;
415 int start_nibble;
416 int end_nibble;
417 bool allow_hex;
418 size_t str_size;
419 const char *expect_str;
420 int expect_rc;
421};
422
423static const struct bcd2str_test bcd2str_tests[] = {
424 {
425 .bcd_hex = "1a 32 54 76 98 f0",
426 .start_nibble = 1,
427 .end_nibble = 11,
428 .expect_str = "1234567890",
429 .expect_rc = 10,
430 },
431 {
432 .bcd_hex = "1a 32 a4 cb 9d f0",
433 .start_nibble = 1,
434 .end_nibble = 11,
435 .expect_str = "1234ABCD90",
436 .expect_rc = -EINVAL,
437 },
438 {
439 .bcd_hex = "1a 32 a4 cb 9d f0",
440 .start_nibble = 1,
441 .end_nibble = 11,
442 .allow_hex = true,
443 .expect_str = "1234ABCD90",
444 .expect_rc = 10,
445 },
446 {
447 .bcd_hex = "1a 32 54 76 98 f0",
448 .start_nibble = 1,
449 .end_nibble = 12,
450 .expect_str = "1234567890F",
451 .expect_rc = -EINVAL,
452 },
453 {
454 .bcd_hex = "1a 32 54 76 98 f0",
455 .start_nibble = 1,
456 .end_nibble = 12,
457 .allow_hex = true,
458 .expect_str = "1234567890F",
459 .expect_rc = 11,
460 },
461 {
462 .bcd_hex = "1a 32 54 76 98 f0",
463 .start_nibble = 0,
464 .end_nibble = 12,
465 .allow_hex = true,
466 .expect_str = "A1234567890F",
467 .expect_rc = 12,
468 },
469 {
470 .bcd_hex = "1a 32 54 76 98 f0",
471 .start_nibble = 1,
472 .end_nibble = 12,
473 .str_size = 5,
474 .expect_str = "1234",
475 .expect_rc = 11,
476 },
477 {
478 .bcd_hex = "",
479 .start_nibble = 1,
480 .end_nibble = 1,
481 .expect_str = "",
482 .expect_rc = 0,
483 },
484};
485
486static void bcd2str_test(void)
487{
488 int i;
489 uint8_t bcd[64];
490 int rc;
491
492 printf("\nTesting bcd to string conversion\n");
493
494 for (i = 0; i < ARRAY_SIZE(bcd2str_tests); i++) {
495 const struct bcd2str_test *t = &bcd2str_tests[i];
496 char str[64] = {};
497 size_t str_size = t->str_size ? : sizeof(str);
498
499 osmo_hexparse(t->bcd_hex, bcd, sizeof(bcd));
500
501 printf("- BCD-input='%s' nibbles=[%d..%d[ str_size=%zu\n", t->bcd_hex,
502 t->start_nibble, t->end_nibble, str_size);
503 rc = osmo_bcd2str(str, str_size, bcd, t->start_nibble, t->end_nibble, t->allow_hex);
504
505 printf(" rc=%d\n", rc);
506
507 OSMO_ASSERT(str[str_size-1] == '\0');
508 printf(" -> %s\n", osmo_quote_str(str, -1));
509
510 if (rc != t->expect_rc)
511 printf(" ERROR: expected rc=%d\n", t->expect_rc);
512 if (strcmp(str, t->expect_str))
513 printf(" ERROR: expected result %s\n", osmo_quote_str(t->expect_str, -1));
514 }
515
516 printf("- zero output buffer\n");
517 rc = osmo_bcd2str(NULL, 100, bcd, 1, 2, false);
518 printf(" bcd2str(NULL, ...) -> %d\n", rc);
519 OSMO_ASSERT(rc < 0);
520 rc = osmo_bcd2str((char*)23, 0, bcd, 1, 2, false);
521 printf(" bcd2str(dst, 0, ...) -> %d\n", rc);
522 OSMO_ASSERT(rc < 0);
523}
524
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100525static void str_escape_test(void)
526{
527 int i;
528 int j;
529 uint8_t in_buf[32];
530 char out_buf[11];
531 const char *printable = "printable";
532 const char *res;
533
534 printf("\nTesting string escaping\n");
535 printf("- all chars from 0 to 255 in batches of 16:\n");
Pau Espin Pedrol6de34ee2018-02-01 12:49:39 +0100536 in_buf[16] = '\0';
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100537 for (j = 0; j < 16; j++) {
538 for (i = 0; i < 16; i++)
539 in_buf[i] = (j << 4) | i;
540 printf("\"%s\"\n", osmo_escape_str((const char*)in_buf, 16));
541 }
542
543 printf("- nul terminated:\n");
544 printf("\"%s\"\n", osmo_escape_str("termi\nated", -1));
545
546 printf("- passthru:\n");
547 res = osmo_escape_str(printable, -1);
Harald Welte98ed3392019-03-28 13:26:53 +0100548 if (strcmp(res, printable))
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100549 printf("NOT passed through! \"%s\"\n", res);
550 else
551 printf("passed through unchanged \"%s\"\n", res);
552
553 printf("- zero length:\n");
554 printf("\"%s\"\n", osmo_escape_str("omitted", 0));
555
556 printf("- truncation when too long:\n");
557 memset(in_buf, 'x', sizeof(in_buf));
558 in_buf[0] = '\a';
559 in_buf[7] = 'E';
560 memset(out_buf, 0x7f, sizeof(out_buf));
561 printf("\"%s\"\n", osmo_escape_str_buf((const char *)in_buf, sizeof(in_buf), out_buf, 10));
562 OSMO_ASSERT(out_buf[10] == 0x7f);
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +0100563}
564
Neels Hofmeyr04eb56f2018-04-09 00:41:28 +0200565static void str_quote_test(void)
566{
567 int i;
568 int j;
569 uint8_t in_buf[32];
570 char out_buf[11];
571 const char *printable = "printable";
572 const char *res;
573
574 printf("\nTesting string quoting\n");
575 printf("- all chars from 0 to 255 in batches of 16:\n");
576 in_buf[16] = '\0';
577 for (j = 0; j < 16; j++) {
578 for (i = 0; i < 16; i++)
579 in_buf[i] = (j << 4) | i;
580 printf("'%s'\n", osmo_quote_str((const char*)in_buf, 16));
581 }
582
583 printf("- nul terminated:\n");
584 printf("'%s'\n", osmo_quote_str("termi\nated", -1));
585
586 printf("- never passthru:\n");
587 res = osmo_quote_str(printable, -1);
588 if (res != printable)
589 printf("NOT passed through. '%s'\n", res);
590 else
591 printf("passed through unchanged '%s'\n", res);
592
593 printf("- zero length:\n");
594 printf("'%s'\n", osmo_quote_str("omitted", 0));
595
596 printf("- truncation when too long:\n");
597 memset(in_buf, 'x', sizeof(in_buf));
598 in_buf[0] = '\a';
599 in_buf[5] = 'E';
600 memset(out_buf, 0x7f, sizeof(out_buf));
601 printf("'%s'\n", osmo_quote_str_buf((const char *)in_buf, sizeof(in_buf), out_buf, 10));
602 OSMO_ASSERT(out_buf[10] == 0x7f);
603
604 printf("- always truncation, even when no escaping needed:\n");
605 memset(in_buf, 'x', sizeof(in_buf));
606 in_buf[6] = 'E'; /* dst has 10, less 2 quotes and nul, leaves 7, i.e. in[6] is last */
607 in_buf[20] = '\0';
608 memset(out_buf, 0x7f, sizeof(out_buf));
609 printf("'%s'\n", osmo_quote_str_buf((const char *)in_buf, -1, out_buf, 10));
610 OSMO_ASSERT(out_buf[0] == '"');
611
612 printf("- try to feed too little buf for quoting:\n");
613 printf("'%s'\n", osmo_quote_str_buf("", -1, out_buf, 2));
614
615 printf("- NULL string becomes a \"NULL\" literal:\n");
616 printf("'%s'\n", osmo_quote_str_buf(NULL, -1, out_buf, 10));
617}
618
Harald Welte15a5f8d2018-06-06 16:58:17 +0200619static void isqrt_test(void)
620{
621 int i;
622
623 printf("\nTesting integer square-root\n");
624 srand(time(NULL));
625 for (i = 0; i < 1024; i++) {
626 uint16_t x;
627 uint32_t r = rand();
628 if (RAND_MAX < UINT16_MAX)
629 x = r * (UINT16_MAX/RAND_MAX);
630 else
631 x = r;
Neels Hofmeyr6979c542018-07-19 22:05:21 +0200632 uint32_t sq = (uint32_t)x*x;
Harald Welte15a5f8d2018-06-06 16:58:17 +0200633 uint32_t y = osmo_isqrt32(sq);
634 if (y != x)
635 printf("ERROR: x=%u, sq=%u, osmo_isqrt(%u) = %u\n", x, sq, sq, y);
636 }
637}
638
Neels Hofmeyr59f4caf2018-07-19 22:13:19 +0200639
640struct osmo_sockaddr_to_str_and_uint_test_case {
641 uint16_t port;
642 bool omit_port;
643 const char *addr;
644 unsigned int addr_len;
645 bool omit_addr;
646 unsigned int expect_rc;
647 const char *expect_returned_addr;
648};
649
650struct osmo_sockaddr_to_str_and_uint_test_case osmo_sockaddr_to_str_and_uint_test_data[] = {
651 {
652 .port = 0,
653 .addr = "0.0.0.0",
654 .addr_len = 20,
655 .expect_rc = 7,
656 },
657 {
658 .port = 65535,
659 .addr = "255.255.255.255",
660 .addr_len = 20,
661 .expect_rc = 15,
662 },
663 {
664 .port = 1234,
665 .addr = "234.23.42.123",
666 .addr_len = 20,
667 .expect_rc = 13,
668 },
669 {
670 .port = 1234,
671 .addr = "234.23.42.123",
672 .addr_len = 10,
673 .expect_rc = 13,
674 .expect_returned_addr = "234.23.42",
675 },
676 {
677 .port = 1234,
678 .omit_port = true,
679 .addr = "234.23.42.123",
680 .addr_len = 20,
681 .expect_rc = 13,
682 },
683 {
684 .port = 1234,
685 .addr = "234.23.42.123",
686 .omit_addr = true,
687 .expect_rc = 0,
688 .expect_returned_addr = "",
689 },
690 {
691 .port = 1234,
692 .addr = "234.23.42.123",
693 .addr_len = 0,
694 .expect_rc = 13,
695 .expect_returned_addr = "",
696 },
697 {
698 .port = 1234,
699 .addr = "234.23.42.123",
700 .omit_port = true,
701 .omit_addr = true,
702 .expect_rc = 0,
703 .expect_returned_addr = "",
704 },
705};
706
707static void osmo_sockaddr_to_str_and_uint_test(void)
708{
709 int i;
710 printf("\n%s\n", __func__);
711
712 for (i = 0; i < ARRAY_SIZE(osmo_sockaddr_to_str_and_uint_test_data); i++) {
713 struct osmo_sockaddr_to_str_and_uint_test_case *t =
714 &osmo_sockaddr_to_str_and_uint_test_data[i];
715
716 struct sockaddr_in sin = {
717 .sin_family = AF_INET,
718 .sin_port = htons(t->port),
719 };
720 inet_aton(t->addr, &sin.sin_addr);
721
722 char addr[20] = {};
723 uint16_t port = 0;
724 unsigned int rc;
725
726 rc = osmo_sockaddr_to_str_and_uint(
727 t->omit_addr? NULL : addr, t->addr_len,
728 t->omit_port? NULL : &port,
729 (const struct sockaddr*)&sin);
730
731 printf("[%d] %s:%u%s%s addr_len=%u --> %s:%u rc=%u\n",
732 i,
733 t->addr ? : "-",
734 t->port,
735 t->omit_addr ? " (omit addr)" : "",
736 t->omit_port ? " (omit port)" : "",
737 t->addr_len,
738 addr, port, rc);
739 if (rc != t->expect_rc)
740 printf("ERROR: Expected rc = %u\n", t->expect_rc);
741 if (!t->expect_returned_addr)
742 t->expect_returned_addr = t->addr;
743 if (strcmp(t->expect_returned_addr, addr))
744 printf("ERROR: Expected addr = '%s'\n", t->expect_returned_addr);
745 if (!t->omit_port && port != t->port)
746 printf("ERROR: Expected port = %u\n", t->port);
747 }
748}
749
Neels Hofmeyr7c749892018-09-07 03:01:38 +0200750struct osmo_str_tolowupper_test_data {
751 const char *in;
752 bool use_static_buf;
753 size_t buflen;
754 const char *expect_lower;
755 const char *expect_upper;
756 size_t expect_rc;
757 size_t expect_rc_inplace;
758};
759
760struct osmo_str_tolowupper_test_data osmo_str_tolowupper_tests[] = {
761 {
762 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
763 .use_static_buf = true,
764 .expect_lower = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz!@#$%^&*()",
765 .expect_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
766 },
767 {
768 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
769 .buflen = 99,
770 .expect_lower = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz!@#$%^&*()",
771 .expect_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
772 .expect_rc = 62,
773 .expect_rc_inplace = 62,
774 },
775 {
776 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
777 .buflen = 0,
778 .expect_lower = "Unset",
779 .expect_upper = "Unset",
780 .expect_rc = 62,
781 .expect_rc_inplace = 0,
782 },
783 {
784 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
785 .buflen = 1,
786 .expect_lower = "",
787 .expect_upper = "",
788 .expect_rc = 62,
789 .expect_rc_inplace = 0,
790 },
791 {
792 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
793 .buflen = 2,
794 .expect_lower = "a",
795 .expect_upper = "A",
796 .expect_rc = 62,
797 .expect_rc_inplace = 1,
798 },
799 {
800 .in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()",
801 .buflen = 28,
802 .expect_lower = "abcdefghijklmnopqrstuvwxyza",
803 .expect_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZA",
804 .expect_rc = 62,
805 .expect_rc_inplace = 27,
806 },
807};
808
809
810static void osmo_str_tolowupper_test()
811{
812 int i;
813 char buf[128];
814 bool ok = true;
815 printf("\n%s\n", __func__);
816
817 for (i = 0; i < ARRAY_SIZE(osmo_str_tolowupper_tests); i++) {
818 struct osmo_str_tolowupper_test_data *d = &osmo_str_tolowupper_tests[i];
819 size_t rc = 0;
820 const char *res;
821
822 /* tolower */
823 if (d->use_static_buf) {
824 res = osmo_str_tolower(d->in);
825 printf("osmo_str_tolower(%s)\n", osmo_quote_str(d->in, -1));
826 printf(" = %s\n", osmo_quote_str(res, -1));
827 } else {
828 OSMO_ASSERT(sizeof(buf) >= d->buflen);
829 osmo_strlcpy(buf, "Unset", sizeof(buf));
830 rc = osmo_str_tolower_buf(buf, d->buflen, d->in);
831 res = buf;
832 printf("osmo_str_tolower_buf(%zu, %s)\n", d->buflen, osmo_quote_str(d->in, -1));
833 printf(" = %zu, %s\n", rc, osmo_quote_str(res, -1));
834 }
835
836 if (strcmp(res, d->expect_lower)) {
837 printf("ERROR: osmo_str_tolowupper_test[%d] tolower\n"
838 " got %s\n", i, osmo_quote_str(res, -1));
839 printf(" expected %s\n", osmo_quote_str(d->expect_lower, -1));
840 ok = false;
841 }
842
843 if (!d->use_static_buf && d->expect_rc != rc) {
844 printf("ERROR: osmo_str_tolowupper_test[%d] tolower\n"
845 " got rc=%zu, expected rc=%zu\n", i, rc, d->expect_rc);
846 ok = false;
847 }
848
849 /* tolower, in-place */
850 if (!d->use_static_buf) {
851 osmo_strlcpy(buf,
852 d->buflen ? d->in : "Unset",
853 sizeof(buf));
854 rc = osmo_str_tolower_buf(buf, d->buflen, buf);
855 res = buf;
856 printf("osmo_str_tolower_buf(%zu, %s, in-place)\n",
857 d->buflen, osmo_quote_str(d->in, -1));
858 printf(" = %zu, %s\n", rc, osmo_quote_str(res, -1));
859
860 if (strcmp(res, d->expect_lower)) {
861 printf("ERROR: osmo_str_tolowupper_test[%d] tolower in-place\n"
862 " got %s\n", i, osmo_quote_str(res, -1));
863 printf(" expected %s\n", osmo_quote_str(d->expect_lower, -1));
864 ok = false;
865 }
866
867 if (d->expect_rc_inplace != rc) {
868 printf("ERROR: osmo_str_tolowupper_test[%d] tolower in-place\n"
869 " got rc=%zu, expected rc=%zu\n",
870 i, rc, d->expect_rc_inplace);
871 ok = false;
872 }
873 }
874
875 /* toupper */
876 if (d->use_static_buf) {
877 res = osmo_str_toupper(d->in);
878 printf("osmo_str_toupper(%s)\n", osmo_quote_str(d->in, -1));
879 printf(" = %s\n", osmo_quote_str(res, -1));
880 } else {
881 OSMO_ASSERT(sizeof(buf) >= d->buflen);
882 osmo_strlcpy(buf, "Unset", sizeof(buf));
883 rc = osmo_str_toupper_buf(buf, d->buflen, d->in);
884 res = buf;
885 printf("osmo_str_toupper_buf(%zu, %s)\n", d->buflen, osmo_quote_str(d->in, -1));
886 printf(" = %zu, %s\n", rc, osmo_quote_str(res, -1));
887 }
888
889 if (strcmp(res, d->expect_upper)) {
890 printf("ERROR: osmo_str_tolowupper_test[%d] toupper\n"
891 " got %s\n", i, osmo_quote_str(res, -1));
892 printf(" expected %s\n", osmo_quote_str(d->expect_upper, -1));
893 ok = false;
894 }
895
896 if (!d->use_static_buf && d->expect_rc != rc) {
897 printf("ERROR: osmo_str_tolowupper_test[%d] toupper\n"
898 " got rc=%zu, expected rc=%zu\n", i, rc, d->expect_rc);
899 ok = false;
900 }
901
902 /* toupper, in-place */
903 if (!d->use_static_buf) {
904 osmo_strlcpy(buf,
905 d->buflen ? d->in : "Unset",
906 sizeof(buf));
907 rc = osmo_str_toupper_buf(buf, d->buflen, buf);
908 res = buf;
909 printf("osmo_str_toupper_buf(%zu, %s, in-place)\n",
910 d->buflen, osmo_quote_str(d->in, -1));
911 printf(" = %zu, %s\n", rc, osmo_quote_str(res, -1));
912
913 if (strcmp(res, d->expect_upper)) {
914 printf("ERROR: osmo_str_tolowupper_test[%d] toupper in-place\n"
915 " got %s\n", i, osmo_quote_str(res, -1));
916 printf(" expected %s\n", osmo_quote_str(d->expect_upper, -1));
917 ok = false;
918 }
919
920 if (d->expect_rc_inplace != rc) {
921 printf("ERROR: osmo_str_tolowupper_test[%d] toupper in-place\n"
922 " got rc=%zu, expected rc=%zu\n",
923 i, rc, d->expect_rc_inplace);
924 ok = false;
925 }
926 }
927 }
928
929 OSMO_ASSERT(ok);
930}
931
Neels Hofmeyr2cbe25f2019-02-11 20:32:06 +0100932/* Copy of the examples from OSMO_STRBUF_APPEND() */
933int print_spaces(char *dst, size_t dst_len, int argument)
934{
935 int i;
936 if (argument < 0)
937 return -EINVAL;
938 for (i = 0; i < argument && i < dst_len; i++)
939 dst[i] = ' ';
940 if (dst_len)
941 dst[OSMO_MIN(dst_len - 1, argument)] = '\0';
942 return argument;
943}
944
945void strbuf_example(char *buf, size_t buflen)
946{
947 struct osmo_strbuf sb = { .buf = buf, .len = buflen };
948
949 OSMO_STRBUF_APPEND(sb, print_spaces, 5);
950 OSMO_STRBUF_APPEND(sb, snprintf, "The answer is %d but what is the question?", 42);
951 OSMO_STRBUF_APPEND(sb, print_spaces, 423423);
952
953 printf("%s\n", buf);
954 printf("would have needed %zu bytes\n", sb.chars_needed);
955}
956
957/* Copy of the examples from OSMO_STRBUF_PRINTF() */
958int strbuf_example2(char *buf, size_t buflen)
959{
960 int i;
961 struct osmo_strbuf sb = { .buf = buf, .len = buflen };
962
963 OSMO_STRBUF_PRINTF(sb, "T minus");
964 for (i = 10; i; i--)
965 OSMO_STRBUF_PRINTF(sb, " %d", i);
966 OSMO_STRBUF_PRINTF(sb, " ... Lift off!");
967
968 return sb.chars_needed;
969}
970
971int strbuf_cascade(char *buf, size_t buflen)
972{
973 struct osmo_strbuf sb = { .buf = buf, .len = buflen };
974
975 OSMO_STRBUF_APPEND(sb, strbuf_example2);
976 OSMO_STRBUF_PRINTF(sb, " -- ");
977 OSMO_STRBUF_APPEND(sb, strbuf_example2);
978 OSMO_STRBUF_PRINTF(sb, " -- ");
979 OSMO_STRBUF_APPEND(sb, strbuf_example2);
980
981 return sb.chars_needed;
982}
983
984void strbuf_test()
985{
986 char buf[256];
987 int rc;
988 printf("\n%s\n", __func__);
989
990 printf("OSMO_STRBUF_APPEND():\n");
991 strbuf_example(buf, 23);
992
993 printf("\nOSMO_STRBUF_PRINTF():\n");
994 rc = strbuf_example2(buf, 23);
995 printf("1: (need %d chars, had size=23) %s\n", rc, buf);
996
997 rc = strbuf_example2(buf, rc);
998 printf("2: (need %d chars, had size=%d) %s\n", rc, rc, buf);
999
1000 rc = strbuf_example2(buf, rc + 1);
1001 printf("3: (need %d chars, had size=%d+1) %s\n", rc, rc, buf);
1002
1003 rc = strbuf_example2(buf, 0);
1004 snprintf(buf, sizeof(buf), "0x2b 0x2b 0x2b...");
1005 printf("4: (need %d chars, had size=0) %s\n", rc, buf);
1006
1007 rc = strbuf_example2(NULL, 99);
1008 printf("5: (need %d chars, had NULL buffer)\n", rc);
1009
1010 printf("\ncascade:\n");
1011 rc = strbuf_cascade(buf, sizeof(buf));
1012 printf("(need %d chars)\n%s\n", rc, buf);
1013 rc = strbuf_cascade(buf, 63);
1014 printf("(need %d chars, had size=63) %s\n", rc, buf);
1015}
Neels Hofmeyr7c749892018-09-07 03:01:38 +02001016
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +01001017int main(int argc, char **argv)
1018{
Holger Hans Peter Freytherf558ed42015-06-02 15:52:06 +02001019 static const struct log_info log_info = {};
1020 log_init(&log_info, NULL);
1021
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +01001022 hexdump_test();
Neels Hofmeyr7adb5672017-02-14 15:48:19 +01001023 hexparse_test();
Harald Welte7869baf2018-07-31 20:25:48 +02001024 test_ipa_ccm_id_get_parsing();
1025 test_ipa_ccm_id_resp_parsing();
Neels Hofmeyr4335bad2017-10-07 04:39:14 +02001026 test_is_hexstr();
Harald Welte504caac2017-10-27 17:19:59 +02001027 bcd_test();
Neels Hofmeyr7079e692018-12-05 21:02:36 +01001028 bcd2str_test();
Neels Hofmeyr9910bbc2017-12-16 00:54:52 +01001029 str_escape_test();
Neels Hofmeyr04eb56f2018-04-09 00:41:28 +02001030 str_quote_test();
Harald Welte15a5f8d2018-06-06 16:58:17 +02001031 isqrt_test();
Neels Hofmeyr59f4caf2018-07-19 22:13:19 +02001032 osmo_sockaddr_to_str_and_uint_test();
Neels Hofmeyr7c749892018-09-07 03:01:38 +02001033 osmo_str_tolowupper_test();
Neels Hofmeyr2cbe25f2019-02-11 20:32:06 +01001034 strbuf_test();
Holger Hans Peter Freytherb79a1482014-01-02 13:55:00 +01001035 return 0;
1036}