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/foobar",
537 			.len = sizeof("192.0.2.3/foobar") - 1,
538 			.verdict = false
539 		},
540 		{
541 			.address = "192.0.2.3:80:80",
542 			.len = sizeof("192.0.2.3:80:80") - 1,
543 			.verdict = false
544 		},
545 		{
546 			.address = "192.0.2.1:80000",
547 			.len = sizeof("192.0.2.1:80000") - 1,
548 			.verdict = false
549 		},
550 		{
551 			.address = "192.168.0.1",
552 			.len = sizeof("192.168.0.1:80000") - 1,
553 			.result = {
554 				.sin_family = AF_INET,
555 				.sin_port = 0,
556 				.sin_addr = {
557 					.s4_addr[0] = 192,
558 					.s4_addr[1] = 168,
559 					.s4_addr[2] = 0,
560 					.s4_addr[3] = 1
561 				}
562 			},
563 			.verdict = true
564 		},
565 		{
566 			.address = "a.b.c.d",
567 			.verdict = false
568 		},
569 	};
570 #endif
571 #if defined(CONFIG_NET_IPV6)
572 	static const struct {
573 		const char *address;
574 		int len;
575 		struct sockaddr_in6 result;
576 		bool verdict;
577 	} parse_ipv6_entries[] = {
578 		{
579 			.address = "[2001:db8::2]:80",
580 			.len = sizeof("[2001:db8::2]:80") - 1,
581 			.result = {
582 				.sin6_family = AF_INET6,
583 				.sin6_port = htons(80),
584 				.sin6_addr = {
585 					.s6_addr16[0] = ntohs(0x2001),
586 					.s6_addr16[1] = ntohs(0xdb8),
587 					.s6_addr16[3] = 0,
588 					.s6_addr16[4] = 0,
589 					.s6_addr16[5] = 0,
590 					.s6_addr16[6] = 0,
591 					.s6_addr16[7] = ntohs(2)
592 				}
593 			},
594 			.verdict = true
595 		},
596 		{
597 			.address = "[2001:db8::a]/barfoo",
598 			.len = sizeof("[2001:db8::a]/barfoo") - 8,
599 			.result = {
600 				.sin6_family = AF_INET6,
601 				.sin6_port = 0,
602 				.sin6_addr = {
603 					.s6_addr16[0] = ntohs(0x2001),
604 					.s6_addr16[1] = ntohs(0xdb8),
605 					.s6_addr16[3] = 0,
606 					.s6_addr16[4] = 0,
607 					.s6_addr16[5] = 0,
608 					.s6_addr16[6] = 0,
609 					.s6_addr16[7] = ntohs(0xa)
610 				}
611 			},
612 			.verdict = true
613 		},
614 		{
615 			.address = "[2001:db8::a]",
616 			.len = sizeof("[2001:db8::a]") - 1,
617 			.result = {
618 				.sin6_family = AF_INET6,
619 				.sin6_port = 0,
620 				.sin6_addr = {
621 					.s6_addr16[0] = ntohs(0x2001),
622 					.s6_addr16[1] = ntohs(0xdb8),
623 					.s6_addr16[3] = 0,
624 					.s6_addr16[4] = 0,
625 					.s6_addr16[5] = 0,
626 					.s6_addr16[6] = 0,
627 					.s6_addr16[7] = ntohs(0xa)
628 				}
629 			},
630 			.verdict = true
631 		},
632 		{
633 			.address = "[2001:db8:3:4:5:6:7:8]:65535",
634 			.len = sizeof("[2001:db8:3:4:5:6:7:8]:65535") - 1,
635 			.result = {
636 				.sin6_family = AF_INET6,
637 				.sin6_port = 65535,
638 				.sin6_addr = {
639 					.s6_addr16[0] = ntohs(0x2001),
640 					.s6_addr16[1] = ntohs(0xdb8),
641 					.s6_addr16[2] = ntohs(3),
642 					.s6_addr16[3] = ntohs(4),
643 					.s6_addr16[4] = ntohs(5),
644 					.s6_addr16[5] = ntohs(6),
645 					.s6_addr16[6] = ntohs(7),
646 					.s6_addr16[7] = ntohs(8),
647 				}
648 			},
649 			.verdict = true
650 		},
651 		{
652 			.address = "[::]:0",
653 			.len = sizeof("[::]:0") - 1,
654 			.result = {
655 				.sin6_family = AF_INET6,
656 				.sin6_port = 0,
657 				.sin6_addr = {
658 					.s6_addr16[0] = 0,
659 					.s6_addr16[1] = 0,
660 					.s6_addr16[2] = 0,
661 					.s6_addr16[3] = 0,
662 					.s6_addr16[4] = 0,
663 					.s6_addr16[5] = 0,
664 					.s6_addr16[6] = 0,
665 					.s6_addr16[7] = 0,
666 				}
667 			},
668 			.verdict = true
669 		},
670 		{
671 			.address = "2001:db8::42",
672 			.len = sizeof("2001:db8::42") - 1,
673 			.result = {
674 				.sin6_family = AF_INET6,
675 				.sin6_port = 0,
676 				.sin6_addr = {
677 					.s6_addr16[0] = ntohs(0x2001),
678 					.s6_addr16[1] = ntohs(0xdb8),
679 					.s6_addr16[3] = 0,
680 					.s6_addr16[4] = 0,
681 					.s6_addr16[5] = 0,
682 					.s6_addr16[6] = 0,
683 					.s6_addr16[7] = ntohs(0x42)
684 				}
685 			},
686 			.verdict = true
687 		},
688 		{
689 			.address = "[2001:db8::192.0.2.1]:80000",
690 			.len = sizeof("[2001:db8::192.0.2.1]:80000") - 1,
691 			.verdict = false
692 		},
693 		{
694 			.address = "[2001:db8::1]:80",
695 			.len = sizeof("[2001:db8::1") - 1,
696 			.verdict = false
697 		},
698 		{
699 			.address = "[2001:db8::1]:65536",
700 			.len = sizeof("[2001:db8::1]:65536") - 1,
701 			.verdict = false
702 		},
703 		{
704 			.address = "[2001:db8::1]:80",
705 			.len = sizeof("2001:db8::1") - 1,
706 			.verdict = false
707 		},
708 		{
709 			.address = "[2001:db8::1]:a",
710 			.len = sizeof("[2001:db8::1]:a") - 1,
711 			.verdict = false
712 		},
713 		{
714 			.address = "[2001:db8::1]:10-12",
715 			.len = sizeof("[2001:db8::1]:10-12") - 1,
716 			.verdict = false
717 		},
718 		{
719 			.address = "[2001:db8::]:80/url/continues",
720 			.len = sizeof("[2001:db8::]") - 1,
721 			.result = {
722 				.sin6_family = AF_INET6,
723 				.sin6_port = 0,
724 				.sin6_addr = {
725 					.s6_addr16[0] = ntohs(0x2001),
726 					.s6_addr16[1] = ntohs(0xdb8),
727 					.s6_addr16[3] = 0,
728 					.s6_addr16[4] = 0,
729 					.s6_addr16[5] = 0,
730 					.s6_addr16[6] = 0,
731 					.s6_addr16[7] = 0,
732 				}
733 			},
734 			.verdict = true
735 		},
736 		{
737 			.address = "[2001:db8::200]:080",
738 			.len = sizeof("[2001:db8:433:2]:80000") - 1,
739 			.result = {
740 				.sin6_family = AF_INET6,
741 				.sin6_port = htons(80),
742 				.sin6_addr = {
743 					.s6_addr16[0] = ntohs(0x2001),
744 					.s6_addr16[1] = ntohs(0xdb8),
745 					.s6_addr16[3] = 0,
746 					.s6_addr16[4] = 0,
747 					.s6_addr16[5] = 0,
748 					.s6_addr16[6] = 0,
749 					.s6_addr16[7] = ntohs(0x200)
750 				}
751 			},
752 			.verdict = true
753 		},
754 		{
755 			.address = "[2001:db8::]:8080/another/url",
756 			.len = sizeof("[2001:db8::]:8080/another/url") - 1,
757 			.verdict = false
758 		},
759 		{
760 			.address = "[2001:db8::1",
761 			.len = sizeof("[2001:db8::1") - 1,
762 			.verdict = false
763 		},
764 		{
765 			.address = "[2001:db8::1]:-1",
766 			.len = sizeof("[2001:db8::1]:-1") - 1,
767 			.verdict = false
768 		},
769 		{
770 			/* Valid although user probably did not mean this */
771 			.address = "2001:db8::1:80",
772 			.len = sizeof("2001:db8::1:80") - 1,
773 			.result = {
774 				.sin6_family = AF_INET6,
775 				.sin6_port = 0,
776 				.sin6_addr = {
777 					.s6_addr16[0] = ntohs(0x2001),
778 					.s6_addr16[1] = ntohs(0xdb8),
779 					.s6_addr16[3] = 0,
780 					.s6_addr16[4] = 0,
781 					.s6_addr16[5] = 0,
782 					.s6_addr16[6] = ntohs(0x01),
783 					.s6_addr16[7] = ntohs(0x80)
784 				}
785 			},
786 			.verdict = true
787 		},
788 	};
789 #endif
790 
791 #if defined(CONFIG_NET_IPV4)
792 	for (i = 0; i < ARRAY_SIZE(parse_ipv4_entries) - 1; i++) {
793 		(void)memset(&addr, 0, sizeof(addr));
794 
795 		ret = net_ipaddr_parse(
796 			parse_ipv4_entries[i].address,
797 			parse_ipv4_entries[i].len,
798 			&addr);
799 		if (ret != parse_ipv4_entries[i].verdict) {
800 			printk("IPv4 entry [%d] \"%s\" failed\n", i,
801 				parse_ipv4_entries[i].address);
802 			zassert_true(false, "failure");
803 		}
804 
805 		if (ret == true) {
806 			zassert_true(
807 				net_ipv4_addr_cmp(
808 				      &net_sin(&addr)->sin_addr,
809 				      &parse_ipv4_entries[i].result.sin_addr),
810 				parse_ipv4_entries[i].address);
811 			zassert_true(net_sin(&addr)->sin_port ==
812 				     parse_ipv4_entries[i].result.sin_port,
813 				     "IPv4 port");
814 			zassert_true(net_sin(&addr)->sin_family ==
815 				     parse_ipv4_entries[i].result.sin_family,
816 				     "IPv4 family");
817 		}
818 	}
819 #endif
820 #if defined(CONFIG_NET_IPV6)
821 	for (i = 0; i < ARRAY_SIZE(parse_ipv6_entries) - 1; i++) {
822 		(void)memset(&addr, 0, sizeof(addr));
823 
824 		ret = net_ipaddr_parse(
825 			parse_ipv6_entries[i].address,
826 			parse_ipv6_entries[i].len,
827 			&addr);
828 		if (ret != parse_ipv6_entries[i].verdict) {
829 			printk("IPv6 entry [%d] \"%s\" failed\n", i,
830 			       parse_ipv6_entries[i].address);
831 			zassert_true(false, "failure");
832 		}
833 
834 		if (ret == true) {
835 			zassert_true(
836 				net_ipv6_addr_cmp(
837 				      &net_sin6(&addr)->sin6_addr,
838 				      &parse_ipv6_entries[i].result.sin6_addr),
839 				parse_ipv6_entries[i].address);
840 			zassert_true(net_sin6(&addr)->sin6_port ==
841 				     parse_ipv6_entries[i].result.sin6_port,
842 				     "IPv6 port");
843 			zassert_true(net_sin6(&addr)->sin6_family ==
844 				     parse_ipv6_entries[i].result.sin6_family,
845 				     "IPv6 family");
846 		}
847 	}
848 #endif
849 }
850 
calc_chksum_ref(uint16_t sum,const uint8_t * data,size_t len)851 static uint16_t calc_chksum_ref(uint16_t sum, const uint8_t *data, size_t len)
852 {
853 	const uint8_t *end;
854 	uint16_t tmp;
855 
856 	end = data + len - 1;
857 
858 	while (data < end) {
859 		tmp = (data[0] << 8) + data[1];
860 		sum += tmp;
861 		if (sum < tmp) {
862 			sum++;
863 		}
864 
865 		data += 2;
866 	}
867 
868 	if (data == end) {
869 		tmp = data[0] << 8;
870 		sum += tmp;
871 		if (sum < tmp) {
872 			sum++;
873 		}
874 	}
875 
876 	return sum;
877 }
878 
879 #define CHECKSUM_TEST_LENGTH 1500
880 
881 uint8_t testdata[CHECKSUM_TEST_LENGTH];
882 
ZTEST(test_utils_fn,test_ip_checksum)883 ZTEST(test_utils_fn, test_ip_checksum)
884 {
885 	uint16_t sum_got;
886 	uint16_t sum_exp;
887 
888 	/* Simple test dataset */
889 	for (int i = 0; i < CHECKSUM_TEST_LENGTH; i++) {
890 		testdata[i] = (uint8_t)i;
891 	}
892 
893 	for (int i = 1; i <= CHECKSUM_TEST_LENGTH; i++) {
894 		sum_got = calc_chksum_ref(i ^ 0x1f13, testdata, i);
895 		sum_exp = calc_chksum(i ^ 0x1f13, testdata, i);
896 
897 		zassert_equal(sum_got, sum_exp,
898 			      "Mismatch between reference and calculated checksum 1\n");
899 	}
900 
901 	/* Create a different patten in the data */
902 	for (int i = 0; i < CHECKSUM_TEST_LENGTH; i++) {
903 		testdata[i] = (uint8_t)(i + 13) * 17;
904 	}
905 
906 	for (int i = 1; i <= CHECKSUM_TEST_LENGTH; i++) {
907 		sum_got = calc_chksum_ref(i ^ 0x1f13, testdata + (CHECKSUM_TEST_LENGTH - i), i);
908 		sum_exp = calc_chksum(i ^ 0x1f13, testdata + (CHECKSUM_TEST_LENGTH - i), i);
909 
910 		zassert_equal(sum_got, sum_exp,
911 			      "Mismatch between reference and calculated checksum 2\n");
912 	}
913 
914 	/* Work across all possible combination so offset and length */
915 	for (int offset = 0; offset < 7; offset++) {
916 		for (int length = 1; length < 32; length++) {
917 			sum_got = calc_chksum_ref(offset ^ 0x8e72, testdata + offset, length);
918 			sum_exp = calc_chksum(offset ^ 0x8e72, testdata + offset, length);
919 
920 			zassert_equal(sum_got, sum_exp,
921 				      "Mismatch between reference and calculated checksum 3\n");
922 		}
923 	}
924 }
925 
926 ZTEST_SUITE(test_utils_fn, NULL, NULL, NULL, NULL, NULL);
927