1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2016 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_UTILS_LOG_LEVEL);
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/ztest_assert.h>
14 #include <zephyr/types.h>
15 #include <stddef.h>
16 #include <string.h>
17 #include <stdio.h>
18 #include <errno.h>
19 #include <zephyr/device.h>
20 #include <zephyr/init.h>
21 #include <zephyr/sys/printk.h>
22 #include <zephyr/net/net_core.h>
23 #include <zephyr/net/net_ip.h>
24 #include <zephyr/net/ethernet.h>
25 #include <zephyr/linker/sections.h>
26 
27 #include <zephyr/tc_util.h>
28 #include <zephyr/ztest.h>
29 
30 #define NET_LOG_ENABLED 1
31 #include "net_private.h"
32 
33 struct net_addr_test_data {
34 	sa_family_t family;
35 	bool pton;
36 
37 	struct {
38 		char c_addr[16];
39 		char c_verify[16];
40 		struct in_addr addr;
41 		struct in_addr verify;
42 	} ipv4;
43 
44 	struct {
45 		char c_addr[46];
46 		char c_verify[46];
47 		struct in6_addr addr;
48 		struct in6_addr verify;
49 	} ipv6;
50 };
51 
52 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_1 = {
53 	.family = AF_INET,
54 	.pton = true,
55 	.ipv4.c_addr = "192.0.0.1",
56 	.ipv4.verify.s4_addr = { 192, 0, 0, 1 },
57 };
58 
59 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_2 = {
60 	.family = AF_INET,
61 	.pton = true,
62 	.ipv4.c_addr = "192.1.0.0",
63 	.ipv4.verify.s4_addr = { 192, 1, 0, 0 },
64 };
65 
66 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_3 = {
67 	.family = AF_INET,
68 	.pton = true,
69 	.ipv4.c_addr = "192.0.0.0",
70 	.ipv4.verify.s4_addr = { 192, 0, 0, 0 },
71 };
72 
73 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_4 = {
74 	.family = AF_INET,
75 	.pton = true,
76 	.ipv4.c_addr = "255.255.255.255",
77 	.ipv4.verify.s4_addr = { 255, 255, 255, 255 },
78 };
79 
80 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_5 = {
81 	.family = AF_INET,
82 	.pton = true,
83 	.ipv4.c_addr = "0.0.0.0",
84 	.ipv4.verify.s4_addr = { 0, 0, 0, 0 },
85 };
86 
87 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_6 = {
88 	.family = AF_INET,
89 	.pton = true,
90 	.ipv4.c_addr = "0.0.0.1",
91 	.ipv4.verify.s4_addr = { 0, 0, 0, 1 },
92 };
93 
94 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_7 = {
95 	.family = AF_INET,
96 	.pton = true,
97 	.ipv4.c_addr = "0.0.1.0",
98 	.ipv4.verify.s4_addr = { 0, 0, 1, 0 },
99 };
100 
101 static ZTEST_DMEM struct net_addr_test_data ipv4_pton_8 = {
102 	.family = AF_INET,
103 	.pton = true,
104 	.ipv4.c_addr = "0.1.0.0",
105 	.ipv4.verify.s4_addr = { 0, 1, 0, 0 },
106 };
107 
108 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_1 = {
109 	.family = AF_INET6,
110 	.pton = true,
111 	.ipv6.c_addr = "ff08::",
112 	.ipv6.verify.s6_addr16 = { htons(0xff08), 0, 0, 0, 0, 0, 0, 0 },
113 };
114 
115 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_2 = {
116 	.family = AF_INET6,
117 	.pton = true,
118 	.ipv6.c_addr = "::",
119 	.ipv6.verify.s6_addr16 = { 0 },
120 };
121 
122 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_3 = {
123 	.family = AF_INET6,
124 	.pton = true,
125 	.ipv6.c_addr = "ff08::1",
126 	.ipv6.verify.s6_addr16 = { htons(0xff08), 0, 0, 0, 0, 0, 0, htons(1) },
127 };
128 
129 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_4 = {
130 	.family = AF_INET6,
131 	.pton = true,
132 	.ipv6.c_addr = "2001:db8::1",
133 	.ipv6.verify.s6_addr16 = { htons(0x2001), htons(0xdb8),
134 				   0, 0, 0, 0, 0, htons(1) },
135 };
136 
137 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_5 = {
138 	.family = AF_INET6,
139 	.pton = true,
140 	.ipv6.c_addr = "2001:db8::2:1",
141 	.ipv6.verify.s6_addr16 = { htons(0x2001), htons(0xdb8),
142 				   0, 0, 0, 0, htons(2), htons(1) },
143 };
144 
145 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_6 = {
146 	.family = AF_INET6,
147 	.pton = true,
148 	.ipv6.c_addr = "ff08:1122:3344:5566:7788:9900:aabb:ccdd",
149 	.ipv6.verify.s6_addr16 = { htons(0xff08), htons(0x1122),
150 				   htons(0x3344), htons(0x5566),
151 				   htons(0x7788), htons(0x9900),
152 				   htons(0xaabb), htons(0xccdd) },
153 };
154 
155 static ZTEST_DMEM struct net_addr_test_data ipv6_pton_7 = {
156 	.family = AF_INET6,
157 	.pton = true,
158 	.ipv6.c_addr = "0:ff08::",
159 	.ipv6.verify.s6_addr16 = { 0, htons(0xff08), 0, 0, 0, 0, 0, 0 },
160 };
161 
162 /* net_addr_ntop test cases */
163 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_1 = {
164 	.family = AF_INET,
165 	.pton = false,
166 	.ipv4.c_verify = "192.0.0.1",
167 	.ipv4.addr.s4_addr = { 192, 0, 0, 1 },
168 };
169 
170 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_2 = {
171 	.family = AF_INET,
172 	.pton = false,
173 	.ipv4.c_verify = "192.1.0.0",
174 	.ipv4.addr.s4_addr = { 192, 1, 0, 0 },
175 };
176 
177 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_3 = {
178 	.family = AF_INET,
179 	.pton = false,
180 	.ipv4.c_verify = "192.0.0.0",
181 	.ipv4.addr.s4_addr = { 192, 0, 0, 0 },
182 };
183 
184 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_4 = {
185 	.family = AF_INET,
186 	.pton = false,
187 	.ipv4.c_verify = "255.255.255.255",
188 	.ipv4.addr.s4_addr = { 255, 255, 255, 255 },
189 };
190 
191 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_5 = {
192 	.family = AF_INET,
193 	.pton = false,
194 	.ipv4.c_verify = "0.0.0.0",
195 	.ipv4.addr.s4_addr = { 0, 0, 0, 0 },
196 };
197 
198 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_6 = {
199 	.family = AF_INET,
200 	.pton = false,
201 	.ipv4.c_verify = "0.0.0.1",
202 	.ipv4.addr.s4_addr = { 0, 0, 0, 1 },
203 };
204 
205 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_7 = {
206 	.family = AF_INET,
207 	.pton = false,
208 	.ipv4.c_verify = "0.0.1.0",
209 	.ipv4.addr.s4_addr = { 0, 0, 1, 0 },
210 };
211 
212 static ZTEST_DMEM struct net_addr_test_data ipv4_ntop_8 = {
213 	.family = AF_INET,
214 	.pton = false,
215 	.ipv4.c_verify = "0.1.0.0",
216 	.ipv4.addr.s4_addr = { 0, 1, 0, 0 },
217 };
218 
219 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_1 = {
220 	.family = AF_INET6,
221 	.pton = false,
222 	.ipv6.c_verify = "ff08::",
223 	.ipv6.addr.s6_addr16 = { htons(0xff08), 0, 0, 0, 0, 0, 0, 0 },
224 };
225 
226 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_2 = {
227 	.family = AF_INET6,
228 	.pton = false,
229 	.ipv6.c_verify = "::",
230 	.ipv6.addr.s6_addr16 = { 0 },
231 };
232 
233 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_3 = {
234 	.family = AF_INET6,
235 	.pton = false,
236 	.ipv6.c_verify = "ff08::1",
237 	.ipv6.addr.s6_addr16 = { htons(0xff08), 0, 0, 0, 0, 0, 0, htons(1) },
238 };
239 
240 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_4 = {
241 	.family = AF_INET6,
242 	.pton = false,
243 	.ipv6.c_verify = "2001:db8::1",
244 	.ipv6.addr.s6_addr16 = { htons(0x2001), htons(0xdb8),
245 				 0, 0, 0, 0, 0, htons(1) },
246 };
247 
248 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_5 = {
249 	.family = AF_INET6,
250 	.pton = false,
251 	.ipv6.c_verify = "2001:db8::2:1",
252 	.ipv6.addr.s6_addr16 = { htons(0x2001), htons(0xdb8),
253 				 0, 0, 0, 0, htons(2), htons(1) },
254 };
255 
256 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_6 = {
257 	.family = AF_INET6,
258 	.pton = false,
259 	.ipv6.c_verify = "ff08:1122:3344:5566:7788:9900:aabb:ccdd",
260 	.ipv6.addr.s6_addr16 = { htons(0xff08), htons(0x1122),
261 				 htons(0x3344), htons(0x5566),
262 				 htons(0x7788), htons(0x9900),
263 				 htons(0xaabb), htons(0xccdd) },
264 };
265 
266 static ZTEST_DMEM struct net_addr_test_data ipv6_ntop_7 = {
267 	.family = AF_INET6,
268 	.pton = false,
269 	.ipv6.c_verify = "0:ff08::",
270 	.ipv6.addr.s6_addr16 = { 0, htons(0xff08), 0, 0, 0, 0, 0, 0 },
271 };
272 
273 static const struct {
274 	const char *name;
275 	struct net_addr_test_data *data;
276 } tests[] = {
277 	/* IPv4 net_addr_pton */
278 	{ "test_ipv4_pton_1", &ipv4_pton_1},
279 	{ "test_ipv4_pton_2", &ipv4_pton_2},
280 	{ "test_ipv4_pton_3", &ipv4_pton_3},
281 	{ "test_ipv4_pton_4", &ipv4_pton_4},
282 	{ "test_ipv4_pton_5", &ipv4_pton_5},
283 	{ "test_ipv4_pton_6", &ipv4_pton_6},
284 	{ "test_ipv4_pton_7", &ipv4_pton_7},
285 	{ "test_ipv4_pton_8", &ipv4_pton_8},
286 
287 	/* IPv6 net_addr_pton */
288 	{ "test_ipv6_pton_1", &ipv6_pton_1},
289 	{ "test_ipv6_pton_2", &ipv6_pton_2},
290 	{ "test_ipv6_pton_3", &ipv6_pton_3},
291 	{ "test_ipv6_pton_4", &ipv6_pton_4},
292 	{ "test_ipv6_pton_5", &ipv6_pton_5},
293 	{ "test_ipv6_pton_6", &ipv6_pton_6},
294 	{ "test_ipv6_pton_7", &ipv6_pton_7},
295 
296 	/* IPv4 net_addr_ntop */
297 	{ "test_ipv4_ntop_1", &ipv4_ntop_1},
298 	{ "test_ipv4_ntop_2", &ipv4_ntop_2},
299 	{ "test_ipv4_ntop_3", &ipv4_ntop_3},
300 	{ "test_ipv4_ntop_4", &ipv4_ntop_4},
301 	{ "test_ipv4_ntop_5", &ipv4_ntop_5},
302 	{ "test_ipv4_ntop_6", &ipv4_ntop_6},
303 	{ "test_ipv4_ntop_7", &ipv4_ntop_7},
304 	{ "test_ipv4_ntop_8", &ipv4_ntop_8},
305 
306 	/* IPv6 net_addr_ntop */
307 	{ "test_ipv6_ntop_1", &ipv6_ntop_1},
308 	{ "test_ipv6_ntop_2", &ipv6_ntop_2},
309 	{ "test_ipv6_ntop_3", &ipv6_ntop_3},
310 	{ "test_ipv6_ntop_4", &ipv6_ntop_4},
311 	{ "test_ipv6_ntop_5", &ipv6_ntop_5},
312 	{ "test_ipv6_ntop_6", &ipv6_ntop_6},
313 	{ "test_ipv6_ntop_7", &ipv6_ntop_7},
314 };
315 
check_net_addr(struct net_addr_test_data * data)316 static bool check_net_addr(struct net_addr_test_data *data)
317 {
318 	switch (data->family) {
319 	case AF_INET:
320 		if (data->pton) {
321 			if (net_addr_pton(AF_INET, (char *)data->ipv4.c_addr,
322 					  &data->ipv4.addr) < 0) {
323 				printk("Failed to convert %s\n",
324 				       data->ipv4.c_addr);
325 
326 				return false;
327 			}
328 
329 			if (!net_ipv4_addr_cmp(&data->ipv4.addr,
330 					       &data->ipv4.verify)) {
331 				printk("Failed to verify %s\n",
332 				       data->ipv4.c_addr);
333 
334 				return false;
335 			}
336 		} else {
337 			if (!net_addr_ntop(AF_INET, &data->ipv4.addr,
338 					   data->ipv4.c_addr,
339 					   sizeof(data->ipv4.c_addr))) {
340 				printk("Failed to convert %s\n",
341 				       net_sprint_ipv4_addr(&data->ipv4.addr));
342 
343 				return false;
344 			}
345 
346 			if (strcmp(data->ipv4.c_addr, data->ipv4.c_verify)) {
347 				printk("Failed to verify %s\n",
348 				       data->ipv4.c_addr);
349 				printk("against %s\n",
350 				       data->ipv4.c_verify);
351 
352 				return false;
353 			}
354 		}
355 
356 		break;
357 
358 	case AF_INET6:
359 		if (data->pton) {
360 			if (net_addr_pton(AF_INET6, (char *)data->ipv6.c_addr,
361 					  &data->ipv6.addr) < 0) {
362 				printk("Failed to convert %s\n",
363 				       data->ipv6.c_addr);
364 
365 				return false;
366 			}
367 
368 			if (!net_ipv6_addr_cmp(&data->ipv6.addr,
369 					       &data->ipv6.verify)) {
370 				printk("Failed to verify %s\n",
371 				       net_sprint_ipv6_addr(&data->ipv6.addr));
372 				printk("against %s\n",
373 				       net_sprint_ipv6_addr(
374 							&data->ipv6.verify));
375 
376 				return false;
377 			}
378 		} else {
379 			if (!net_addr_ntop(AF_INET6, &data->ipv6.addr,
380 					   data->ipv6.c_addr,
381 					   sizeof(data->ipv6.c_addr))) {
382 				printk("Failed to convert %s\n",
383 				       net_sprint_ipv6_addr(&data->ipv6.addr));
384 
385 				return false;
386 			}
387 
388 			if (strcmp(data->ipv6.c_addr, data->ipv6.c_verify)) {
389 				printk("Failed to verify %s\n",
390 				       data->ipv6.c_addr);
391 				printk("against %s\n",
392 				       data->ipv6.c_verify);
393 
394 				return false;
395 			}
396 
397 		}
398 
399 		break;
400 	}
401 
402 	return true;
403 }
404 
ZTEST(test_utils_fn,test_net_addr)405 ZTEST(test_utils_fn, test_net_addr)
406 {
407 	int count, pass;
408 
409 	for (count = 0, pass = 0; count < ARRAY_SIZE(tests); count++) {
410 		TC_PRINT("Running test: %s: ", tests[count].name);
411 
412 		if (check_net_addr(tests[count].data)) {
413 			TC_PRINT("passed\n");
414 			pass++;
415 		} else {
416 			TC_PRINT("failed\n");
417 		}
418 	}
419 
420 	zassert_equal(pass, ARRAY_SIZE(tests), "check_net_addr error");
421 }
422 
ZTEST(test_utils_fn,test_addr_parse)423 ZTEST(test_utils_fn, test_addr_parse)
424 {
425 	struct sockaddr addr;
426 	bool ret;
427 	int i;
428 #if defined(CONFIG_NET_IPV4)
429 	static const struct {
430 		const char *address;
431 		int len;
432 		struct sockaddr_in result;
433 		bool verdict;
434 	} parse_ipv4_entries[] = {
435 		{
436 			.address = "192.0.2.1:80",
437 			.len = sizeof("192.0.2.1:80") - 1,
438 			.result = {
439 				.sin_family = AF_INET,
440 				.sin_port = htons(80),
441 				.sin_addr = {
442 					.s4_addr[0] = 192,
443 					.s4_addr[1] = 0,
444 					.s4_addr[2] = 2,
445 					.s4_addr[3] = 1
446 				}
447 			},
448 			.verdict = true
449 		},
450 		{
451 			.address = "192.0.2.2",
452 			.len = sizeof("192.0.2.2") - 1,
453 			.result = {
454 				.sin_family = AF_INET,
455 				.sin_port = 0,
456 				.sin_addr = {
457 					.s4_addr[0] = 192,
458 					.s4_addr[1] = 0,
459 					.s4_addr[2] = 2,
460 					.s4_addr[3] = 2
461 				}
462 			},
463 			.verdict = true
464 		},
465 		{
466 			.address = "192.0.2.3/foobar",
467 			.len = sizeof("192.0.2.3/foobar") - 8,
468 			.result = {
469 				.sin_family = AF_INET,
470 				.sin_port = 0,
471 				.sin_addr = {
472 					.s4_addr[0] = 192,
473 					.s4_addr[1] = 0,
474 					.s4_addr[2] = 2,
475 					.s4_addr[3] = 3
476 				}
477 			},
478 			.verdict = true
479 		},
480 		{
481 			.address = "255.255.255.255:0",
482 			.len = sizeof("255.255.255.255:0") - 1,
483 			.result = {
484 				.sin_family = AF_INET,
485 				.sin_port = 0,
486 				.sin_addr = {
487 					.s4_addr[0] = 255,
488 					.s4_addr[1] = 255,
489 					.s4_addr[2] = 255,
490 					.s4_addr[3] = 255
491 				}
492 			},
493 			.verdict = true
494 		},
495 		{
496 			.address = "127.0.0.42:65535",
497 			.len = sizeof("127.0.0.42:65535") - 1,
498 			.result = {
499 				.sin_family = AF_INET,
500 				.sin_port = htons(65535),
501 				.sin_addr = {
502 					.s4_addr[0] = 127,
503 					.s4_addr[1] = 0,
504 					.s4_addr[2] = 0,
505 					.s4_addr[3] = 42
506 				}
507 			},
508 			.verdict = true
509 		},
510 		{
511 			.address = "192.0.2.3:80/foobar",
512 			.len = sizeof("192.0.2.3:80/foobar") - 1,
513 			.verdict = false
514 		},
515 		{
516 			.address = "192.168.1.1:65536/foobar",
517 			.len = sizeof("192.168.1.1:65536") - 1,
518 			.verdict = false
519 		},
520 		{
521 			.address = "192.0.2.3:80/foobar",
522 			.len = sizeof("192.0.2.3") - 1,
523 			.result = {
524 				.sin_family = AF_INET,
525 				.sin_port = 0,
526 				.sin_addr = {
527 					.s4_addr[0] = 192,
528 					.s4_addr[1] = 0,
529 					.s4_addr[2] = 2,
530 					.s4_addr[3] = 3
531 				}
532 			},
533 			.verdict = true
534 		},
535 		{
536 			.address = "192.0.2.3:80/foobar",
537 			.len = sizeof("192.0.2.3:80") - 1,
538 			.result = {
539 				.sin_family = AF_INET,
540 				.sin_port = htons(80),
541 				.sin_addr = {
542 					.s4_addr[0] = 192,
543 					.s4_addr[1] = 0,
544 					.s4_addr[2] = 2,
545 					.s4_addr[3] = 3
546 				}
547 			},
548 			.verdict = true
549 		},
550 		{
551 			.address = "192.0.2.3/foobar",
552 			.len = sizeof("192.0.2.3/foobar") - 1,
553 			.verdict = false
554 		},
555 		{
556 			.address = "192.0.2.3:80:80",
557 			.len = sizeof("192.0.2.3:80:80") - 1,
558 			.verdict = false
559 		},
560 		{
561 			.address = "192.0.2.1:80000",
562 			.len = sizeof("192.0.2.1:80000") - 1,
563 			.verdict = false
564 		},
565 		{
566 			.address = "192.168.0.1",
567 			.len = sizeof("192.168.0.1:80000") - 1,
568 			.result = {
569 				.sin_family = AF_INET,
570 				.sin_port = 0,
571 				.sin_addr = {
572 					.s4_addr[0] = 192,
573 					.s4_addr[1] = 168,
574 					.s4_addr[2] = 0,
575 					.s4_addr[3] = 1
576 				}
577 			},
578 			.verdict = true
579 		},
580 		{
581 			.address = "a.b.c.d",
582 			.verdict = false
583 		},
584 	};
585 #endif
586 #if defined(CONFIG_NET_IPV6)
587 	static const struct {
588 		const char *address;
589 		int len;
590 		struct sockaddr_in6 result;
591 		bool verdict;
592 	} parse_ipv6_entries[] = {
593 		{
594 			.address = "[2001:db8::2]:80",
595 			.len = sizeof("[2001:db8::2]:80") - 1,
596 			.result = {
597 				.sin6_family = AF_INET6,
598 				.sin6_port = htons(80),
599 				.sin6_addr = {
600 					.s6_addr16[0] = ntohs(0x2001),
601 					.s6_addr16[1] = ntohs(0xdb8),
602 					.s6_addr16[3] = 0,
603 					.s6_addr16[4] = 0,
604 					.s6_addr16[5] = 0,
605 					.s6_addr16[6] = 0,
606 					.s6_addr16[7] = ntohs(2)
607 				}
608 			},
609 			.verdict = true
610 		},
611 		{
612 			.address = "[2001:db8::a]/barfoo",
613 			.len = sizeof("[2001:db8::a]/barfoo") - 8,
614 			.result = {
615 				.sin6_family = AF_INET6,
616 				.sin6_port = 0,
617 				.sin6_addr = {
618 					.s6_addr16[0] = ntohs(0x2001),
619 					.s6_addr16[1] = ntohs(0xdb8),
620 					.s6_addr16[3] = 0,
621 					.s6_addr16[4] = 0,
622 					.s6_addr16[5] = 0,
623 					.s6_addr16[6] = 0,
624 					.s6_addr16[7] = ntohs(0xa)
625 				}
626 			},
627 			.verdict = true
628 		},
629 		{
630 			.address = "[2001:db8::a]",
631 			.len = sizeof("[2001:db8::a]") - 1,
632 			.result = {
633 				.sin6_family = AF_INET6,
634 				.sin6_port = 0,
635 				.sin6_addr = {
636 					.s6_addr16[0] = ntohs(0x2001),
637 					.s6_addr16[1] = ntohs(0xdb8),
638 					.s6_addr16[3] = 0,
639 					.s6_addr16[4] = 0,
640 					.s6_addr16[5] = 0,
641 					.s6_addr16[6] = 0,
642 					.s6_addr16[7] = ntohs(0xa)
643 				}
644 			},
645 			.verdict = true
646 		},
647 		{
648 			.address = "[2001:db8:3:4:5:6:7:8]:65535",
649 			.len = sizeof("[2001:db8:3:4:5:6:7:8]:65535") - 1,
650 			.result = {
651 				.sin6_family = AF_INET6,
652 				.sin6_port = 65535,
653 				.sin6_addr = {
654 					.s6_addr16[0] = ntohs(0x2001),
655 					.s6_addr16[1] = ntohs(0xdb8),
656 					.s6_addr16[2] = ntohs(3),
657 					.s6_addr16[3] = ntohs(4),
658 					.s6_addr16[4] = ntohs(5),
659 					.s6_addr16[5] = ntohs(6),
660 					.s6_addr16[6] = ntohs(7),
661 					.s6_addr16[7] = ntohs(8),
662 				}
663 			},
664 			.verdict = true
665 		},
666 		{
667 			.address = "[::]:0",
668 			.len = sizeof("[::]:0") - 1,
669 			.result = {
670 				.sin6_family = AF_INET6,
671 				.sin6_port = 0,
672 				.sin6_addr = {
673 					.s6_addr16[0] = 0,
674 					.s6_addr16[1] = 0,
675 					.s6_addr16[2] = 0,
676 					.s6_addr16[3] = 0,
677 					.s6_addr16[4] = 0,
678 					.s6_addr16[5] = 0,
679 					.s6_addr16[6] = 0,
680 					.s6_addr16[7] = 0,
681 				}
682 			},
683 			.verdict = true
684 		},
685 		{
686 			.address = "2001:db8::42",
687 			.len = sizeof("2001:db8::42") - 1,
688 			.result = {
689 				.sin6_family = AF_INET6,
690 				.sin6_port = 0,
691 				.sin6_addr = {
692 					.s6_addr16[0] = ntohs(0x2001),
693 					.s6_addr16[1] = ntohs(0xdb8),
694 					.s6_addr16[3] = 0,
695 					.s6_addr16[4] = 0,
696 					.s6_addr16[5] = 0,
697 					.s6_addr16[6] = 0,
698 					.s6_addr16[7] = ntohs(0x42)
699 				}
700 			},
701 			.verdict = true
702 		},
703 		{
704 			.address = "[2001:db8::192.0.2.1]:80000",
705 			.len = sizeof("[2001:db8::192.0.2.1]:80000") - 1,
706 			.verdict = false
707 		},
708 		{
709 			.address = "[2001:db8::1]:80",
710 			.len = sizeof("[2001:db8::1") - 1,
711 			.verdict = false
712 		},
713 		{
714 			.address = "[2001:db8::1]:65536",
715 			.len = sizeof("[2001:db8::1]:65536") - 1,
716 			.verdict = false
717 		},
718 		{
719 			.address = "[2001:db8::1]:80",
720 			.len = sizeof("2001:db8::1") - 1,
721 			.verdict = false
722 		},
723 		{
724 			.address = "[2001:db8::1]:a",
725 			.len = sizeof("[2001:db8::1]:a") - 1,
726 			.verdict = false
727 		},
728 		{
729 			.address = "[2001:db8::1]:10-12",
730 			.len = sizeof("[2001:db8::1]:10-12") - 1,
731 			.verdict = false
732 		},
733 		{
734 			.address = "[2001:db8::]:80/url/continues",
735 			.len = sizeof("[2001:db8::]") - 1,
736 			.result = {
737 				.sin6_family = AF_INET6,
738 				.sin6_port = 0,
739 				.sin6_addr = {
740 					.s6_addr16[0] = ntohs(0x2001),
741 					.s6_addr16[1] = ntohs(0xdb8),
742 					.s6_addr16[3] = 0,
743 					.s6_addr16[4] = 0,
744 					.s6_addr16[5] = 0,
745 					.s6_addr16[6] = 0,
746 					.s6_addr16[7] = 0,
747 				}
748 			},
749 			.verdict = true
750 		},
751 		{
752 			.address = "[2001:db8::200]:080",
753 			.len = sizeof("[2001:db8:433:2]:80000") - 1,
754 			.result = {
755 				.sin6_family = AF_INET6,
756 				.sin6_port = htons(80),
757 				.sin6_addr = {
758 					.s6_addr16[0] = ntohs(0x2001),
759 					.s6_addr16[1] = ntohs(0xdb8),
760 					.s6_addr16[3] = 0,
761 					.s6_addr16[4] = 0,
762 					.s6_addr16[5] = 0,
763 					.s6_addr16[6] = 0,
764 					.s6_addr16[7] = ntohs(0x200)
765 				}
766 			},
767 			.verdict = true
768 		},
769 		{
770 			.address = "[2001:db8::]:8080/another/url",
771 			.len = sizeof("[2001:db8::]:8080/another/url") - 1,
772 			.verdict = false
773 		},
774 		{
775 			.address = "[2001:db8::1",
776 			.len = sizeof("[2001:db8::1") - 1,
777 			.verdict = false
778 		},
779 		{
780 			.address = "[2001:db8::1]:-1",
781 			.len = sizeof("[2001:db8::1]:-1") - 1,
782 			.verdict = false
783 		},
784 		{
785 			/* Valid although user probably did not mean this */
786 			.address = "2001:db8::1:80",
787 			.len = sizeof("2001:db8::1:80") - 1,
788 			.result = {
789 				.sin6_family = AF_INET6,
790 				.sin6_port = 0,
791 				.sin6_addr = {
792 					.s6_addr16[0] = ntohs(0x2001),
793 					.s6_addr16[1] = ntohs(0xdb8),
794 					.s6_addr16[3] = 0,
795 					.s6_addr16[4] = 0,
796 					.s6_addr16[5] = 0,
797 					.s6_addr16[6] = ntohs(0x01),
798 					.s6_addr16[7] = ntohs(0x80)
799 				}
800 			},
801 			.verdict = true
802 		},
803 	};
804 #endif
805 
806 #if defined(CONFIG_NET_IPV4)
807 	for (i = 0; i < ARRAY_SIZE(parse_ipv4_entries) - 1; i++) {
808 		(void)memset(&addr, 0, sizeof(addr));
809 
810 		ret = net_ipaddr_parse(
811 			parse_ipv4_entries[i].address,
812 			parse_ipv4_entries[i].len,
813 			&addr);
814 		if (ret != parse_ipv4_entries[i].verdict) {
815 			printk("IPv4 entry [%d] \"%s\" failed\n", i,
816 				parse_ipv4_entries[i].address);
817 			zassert_true(false, "failure");
818 		}
819 
820 		if (ret == true) {
821 			zassert_true(
822 				net_ipv4_addr_cmp(
823 				      &net_sin(&addr)->sin_addr,
824 				      &parse_ipv4_entries[i].result.sin_addr),
825 				parse_ipv4_entries[i].address);
826 			zassert_true(net_sin(&addr)->sin_port ==
827 				     parse_ipv4_entries[i].result.sin_port,
828 				     "IPv4 port");
829 			zassert_true(net_sin(&addr)->sin_family ==
830 				     parse_ipv4_entries[i].result.sin_family,
831 				     "IPv4 family");
832 		}
833 	}
834 #endif
835 #if defined(CONFIG_NET_IPV6)
836 	for (i = 0; i < ARRAY_SIZE(parse_ipv6_entries) - 1; i++) {
837 		(void)memset(&addr, 0, sizeof(addr));
838 
839 		ret = net_ipaddr_parse(
840 			parse_ipv6_entries[i].address,
841 			parse_ipv6_entries[i].len,
842 			&addr);
843 		if (ret != parse_ipv6_entries[i].verdict) {
844 			printk("IPv6 entry [%d] \"%s\" failed\n", i,
845 			       parse_ipv6_entries[i].address);
846 			zassert_true(false, "failure");
847 		}
848 
849 		if (ret == true) {
850 			zassert_true(
851 				net_ipv6_addr_cmp(
852 				      &net_sin6(&addr)->sin6_addr,
853 				      &parse_ipv6_entries[i].result.sin6_addr),
854 				parse_ipv6_entries[i].address);
855 			zassert_true(net_sin6(&addr)->sin6_port ==
856 				     parse_ipv6_entries[i].result.sin6_port,
857 				     "IPv6 port");
858 			zassert_true(net_sin6(&addr)->sin6_family ==
859 				     parse_ipv6_entries[i].result.sin6_family,
860 				     "IPv6 family");
861 		}
862 	}
863 #endif
864 }
865 
calc_chksum_ref(uint16_t sum,const uint8_t * data,size_t len)866 static uint16_t calc_chksum_ref(uint16_t sum, const uint8_t *data, size_t len)
867 {
868 	const uint8_t *end;
869 	uint16_t tmp;
870 
871 	end = data + len - 1;
872 
873 	while (data < end) {
874 		tmp = (data[0] << 8) + data[1];
875 		sum += tmp;
876 		if (sum < tmp) {
877 			sum++;
878 		}
879 
880 		data += 2;
881 	}
882 
883 	if (data == end) {
884 		tmp = data[0] << 8;
885 		sum += tmp;
886 		if (sum < tmp) {
887 			sum++;
888 		}
889 	}
890 
891 	return sum;
892 }
893 
894 #define CHECKSUM_TEST_LENGTH 1500
895 
896 uint8_t testdata[CHECKSUM_TEST_LENGTH];
897 
ZTEST(test_utils_fn,test_ip_checksum)898 ZTEST(test_utils_fn, test_ip_checksum)
899 {
900 	uint16_t sum_got;
901 	uint16_t sum_exp;
902 
903 	/* Simple test dataset */
904 	for (int i = 0; i < CHECKSUM_TEST_LENGTH; i++) {
905 		testdata[i] = (uint8_t)i;
906 	}
907 
908 	for (int i = 1; i <= CHECKSUM_TEST_LENGTH; i++) {
909 		sum_got = calc_chksum_ref(i ^ 0x1f13, testdata, i);
910 		sum_exp = calc_chksum(i ^ 0x1f13, testdata, i);
911 
912 		zassert_equal(sum_got, sum_exp,
913 			      "Mismatch between reference and calculated checksum 1\n");
914 	}
915 
916 	/* Create a different patten in the data */
917 	for (int i = 0; i < CHECKSUM_TEST_LENGTH; i++) {
918 		testdata[i] = (uint8_t)(i + 13) * 17;
919 	}
920 
921 	for (int i = 1; i <= CHECKSUM_TEST_LENGTH; i++) {
922 		sum_got = calc_chksum_ref(i ^ 0x1f13, testdata + (CHECKSUM_TEST_LENGTH - i), i);
923 		sum_exp = calc_chksum(i ^ 0x1f13, testdata + (CHECKSUM_TEST_LENGTH - i), i);
924 
925 		zassert_equal(sum_got, sum_exp,
926 			      "Mismatch between reference and calculated checksum 2\n");
927 	}
928 
929 	/* Work across all possible combination so offset and length */
930 	for (int offset = 0; offset < 7; offset++) {
931 		for (int length = 1; length < 32; length++) {
932 			sum_got = calc_chksum_ref(offset ^ 0x8e72, testdata + offset, length);
933 			sum_exp = calc_chksum(offset ^ 0x8e72, testdata + offset, length);
934 
935 			zassert_equal(sum_got, sum_exp,
936 				      "Mismatch between reference and calculated checksum 3\n");
937 		}
938 	}
939 }
940 
941 ZTEST_SUITE(test_utils_fn, NULL, NULL, NULL, NULL, NULL);
942