xref: /dpdk/app/test/test_cmdline_ipaddr.c (revision 7917b0d38e92e8b9ec5a870415b791420e10f11a)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 #include <stdio.h>
5 #include <string.h>
6 #include <inttypes.h>
7 
8 #include <rte_string_fns.h>
9 
10 #include <cmdline_parse.h>
11 #include <cmdline_parse_ipaddr.h>
12 
13 #include "test_cmdline.h"
14 
15 #define IP4(a,b,c,d) {.s_addr = (uint32_t)(((a) & 0xff) | \
16 					   (((b) & 0xff) << 8) | \
17 					   (((c) & 0xff) << 16)  | \
18 					   ((d) & 0xff)  << 24)}
19 
20 #define U16_SWAP(x) \
21 		(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
22 
23 /* create IPv6 address, swapping bytes where needed */
24 #ifndef s6_addr16
25 #ifdef RTE_EXEC_ENV_WINDOWS
26 #define s6_addr16 u.Word
27 #else
28 #define s6_addr16 __u6_addr.__u6_addr16
29 #endif
30 #endif
31 #define IP6(a,b,c,d,e,f,g,h) .ipv6 = \
32 		{.s6_addr16 = \
33 		{U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\
34 		 U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}}
35 
36 /** these are defined in netinet/in.h but not present in linux headers */
37 #ifndef NIPQUAD
38 
39 #define NIPQUAD_FMT "%u.%u.%u.%u"
40 #define NIPQUAD(addr)				\
41 	(unsigned)((unsigned char *)&addr)[0],	\
42 	(unsigned)((unsigned char *)&addr)[1],	\
43 	(unsigned)((unsigned char *)&addr)[2],	\
44 	(unsigned)((unsigned char *)&addr)[3]
45 
46 #define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
47 #define NIP6(addr)					\
48 	(unsigned)((addr).s6_addr[0]),			\
49 	(unsigned)((addr).s6_addr[1]),			\
50 	(unsigned)((addr).s6_addr[2]),			\
51 	(unsigned)((addr).s6_addr[3]),			\
52 	(unsigned)((addr).s6_addr[4]),			\
53 	(unsigned)((addr).s6_addr[5]),			\
54 	(unsigned)((addr).s6_addr[6]),			\
55 	(unsigned)((addr).s6_addr[7]),			\
56 	(unsigned)((addr).s6_addr[8]),			\
57 	(unsigned)((addr).s6_addr[9]),			\
58 	(unsigned)((addr).s6_addr[10]),			\
59 	(unsigned)((addr).s6_addr[11]),			\
60 	(unsigned)((addr).s6_addr[12]),			\
61 	(unsigned)((addr).s6_addr[13]),			\
62 	(unsigned)((addr).s6_addr[14]),			\
63 	(unsigned)((addr).s6_addr[15])
64 
65 #endif
66 
67 
68 
69 struct ipaddr_str {
70 	const char * str;
71 	cmdline_ipaddr_t addr;
72 	unsigned flags;
73 };
74 
75 const struct ipaddr_str ipaddr_valid_strs[] = {
76 		{"0.0.0.0", {AF_INET, {IP4(0,0,0,0)}, 0},
77 				CMDLINE_IPADDR_V4},
78 		{"0.0.0.0/0", {AF_INET, {IP4(0,0,0,0)}, 0},
79 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
80 		{"0.0.0.0/24", {AF_INET, {IP4(0,0,0,0)}, 24},
81 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
82 		{"192.168.1.0/24", {AF_INET, {IP4(192,168,1,0)}, 24},
83 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
84 		{"34.56.78.90/1", {AF_INET, {IP4(34,56,78,90)}, 1},
85 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
86 		{"::", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 0},
87 					CMDLINE_IPADDR_V6},
88 		{"::1", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 0},
89 				CMDLINE_IPADDR_V6},
90 		{"::1/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 32},
91 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
92 		{"::/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 32},
93 					CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
94 		/* RFC5952 requests that only lowercase should be used */
95 		{"1234:5678:90ab:cdef:4321:8765:BA09:FEDC", {AF_INET6,
96 				{IP6(0x1234,0x5678,0x90AB,0xCDEF,0x4321,0x8765,0xBA09,0xFEDC)},
97 				0},
98 				CMDLINE_IPADDR_V6},
99 		{"1234::1234/64", {AF_INET6,
100 				{IP6(0x1234,0,0,0,0,0,0,0x1234)},
101 				64},
102 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
103 		{"1234::/64", {AF_INET6,
104 				{IP6(0x1234,0,0,0,0,0,0,0)},
105 				64},
106 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
107 		{"1:1::1/32", {AF_INET6,
108 				{IP6(1,1,0,0,0,0,0,1)},
109 				32},
110 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
111 		{"1:2:3:4::/64", {AF_INET6,
112 				{IP6(1,2,3,4,0,0,0,0)},
113 				64},
114 			CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
115 		{"::ffff:192.168.1.0/64", {AF_INET6,
116 				{IP6(0,0,0,0,0,0xFFFF,0xC0A8,0x100)},
117 				64},
118 			CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
119 		/* RFC5952 requests not using :: to skip one block of zeros*/
120 		{"1::2:3:4:5:6:7", {AF_INET6,
121 				{IP6(1,0,2,3,4,5,6,7)},
122 				0},
123 			CMDLINE_IPADDR_V6},
124 };
125 
126 const char * ipaddr_garbage_addr4_strs[] = {
127 		/* IPv4 */
128 		"192.168.1.0 garbage",
129 		"192.168.1.0\0garbage",
130 		"192.168.1.0#garbage",
131 		"192.168.1.0\tgarbage",
132 		"192.168.1.0\rgarbage",
133 		"192.168.1.0\ngarbage",
134 };
135 #define IPv4_GARBAGE_ADDR IP4(192,168,1,0)
136 
137 const char * ipaddr_garbage_addr6_strs[] = {
138 		/* IPv6 */
139 		"1:2:3:4::8 garbage",
140 		"1:2:3:4::8#garbage",
141 		"1:2:3:4::8\0garbage",
142 		"1:2:3:4::8\rgarbage",
143 		"1:2:3:4::8\ngarbage",
144 		"1:2:3:4::8\tgarbage",
145 };
146 #define IPv6_GARBAGE_ADDR {IP6(1,2,3,4,0,0,0,8)}
147 
148 const char * ipaddr_garbage_network4_strs[] = {
149 		/* IPv4 */
150 		"192.168.1.0/24 garbage",
151 		"192.168.1.0/24\0garbage",
152 		"192.168.1.0/24#garbage",
153 		"192.168.1.0/24\tgarbage",
154 		"192.168.1.0/24\rgarbage",
155 		"192.168.1.0/24\ngarbage",
156 };
157 #define IPv4_GARBAGE_PREFIX 24
158 
159 const char * ipaddr_garbage_network6_strs[] = {
160 		/* IPv6 */
161 		"1:2:3:4::8/64 garbage",
162 		"1:2:3:4::8/64#garbage",
163 		"1:2:3:4::8/64\0garbage",
164 		"1:2:3:4::8/64\rgarbage",
165 		"1:2:3:4::8/64\ngarbage",
166 		"1:2:3:4::8/64\tgarbage",
167 };
168 #define IPv6_GARBAGE_PREFIX 64
169 
170 const char * ipaddr_invalid_strs[] = {
171 		/** IPv4 **/
172 
173 		/* invalid numbers */
174 		"0.0.0.-1",
175 		"0.0.-1.0",
176 		"0.-1.0.0",
177 		"-1.0.0.0",
178 		"0.0.0.-1/24",
179 		"256.123.123.123",
180 		"255.256.123.123",
181 		"255.255.256.123",
182 		"255.255.255.256",
183 		"256.123.123.123/24",
184 		"255.256.123.123/24",
185 		"255.255.256.123/24",
186 		"255.255.255.256/24",
187 		/* invalid network mask */
188 		"1.2.3.4/33",
189 		"1.2.3.4/33231313",
190 		"1.2.3.4/-1",
191 		"1.2.3.4/24/33",
192 		"1.2.3.4/24/-1",
193 		"1.2.3.4/24/",
194 		/* wrong format */
195 		"1/24"
196 		"/24"
197 		"123.123.123",
198 		"123.123.123.",
199 		"123.123.123.123.",
200 		"123.123.123..123",
201 		"123.123.123.123.123",
202 		".123.123.123",
203 		".123.123.123.123",
204 		"123.123.123/24",
205 		"123.123.123./24",
206 		"123.123.123.123./24",
207 		"123.123.123..123/24",
208 		"123.123.123.123.123/24",
209 		".123.123.123/24",
210 		".123.123.123.123/24",
211 		/* invalid characters */
212 		"123.123.123.12F",
213 		"123.123.12F.123",
214 		"123.12F.123.123",
215 		"12F.123.123.123",
216 		"12J.123.123.123",
217 		"123,123,123,123",
218 		"123!123!123!12F",
219 		"123.123.123.123/4F",
220 
221 		/** IPv6 **/
222 
223 		/* wrong format */
224 		"::fffff",
225 		"ffff:",
226 		"1:2:3:4:5:6:7:192.168.1.1",
227 		"1234:192.168.1.1:ffff::",
228 		"1:2:3:4:5:6:7:890ab",
229 		"1:2:3:4:5:6:7890a:b",
230 		"1:2:3:4:5:67890:a:b",
231 		"1:2:3:4:56789:0:a:b",
232 		"1:2:3:45678:9:0:a:b",
233 		"1:2:34567:8:9:0:a:b",
234 		"1:23456:7:8:9:0:a:b",
235 		"12345:6:7:8:9:0:a:b",
236 		"1:::2",
237 		"1::::2",
238 		"::fffff/64",
239 		"1::2::3",
240 		"1::2::3/64",
241 		":1:2",
242 		":1:2/64",
243 		":1::2",
244 		":1::2/64",
245 		"1::2:3:4:5:6:7:8/64",
246 
247 		/* invalid network mask */
248 		"1:2:3:4:5:6:7:8/129",
249 		"1:2:3:4:5:6:7:8/-1",
250 
251 		/* invalid characters */
252 		"a:b:c:d:e:f:g::",
253 
254 		/** misc **/
255 
256 		/* too long */
257 		"1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234",
258 		"random invalid text",
259 		"",
260 		"\0",
261 		" ",
262 };
263 
264 static void
265 dump_addr(cmdline_ipaddr_t addr)
266 {
267 	switch (addr.family) {
268 	case AF_INET:
269 	{
270 		printf(NIPQUAD_FMT " prefixlen=%u\n",
271 				NIPQUAD(addr.addr.ipv4.s_addr), addr.prefixlen);
272 		break;
273 	}
274 	case AF_INET6:
275 	{
276 		printf(NIP6_FMT " prefixlen=%u\n",
277 				NIP6(addr.addr.ipv6), addr.prefixlen);
278 		break;
279 	}
280 	default:
281 		printf("Can't dump: unknown address family.\n");
282 		return;
283 	}
284 }
285 
286 
287 static int
288 is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2)
289 {
290 	if (addr1.family != addr2.family)
291 		return 1;
292 
293 	if (addr1.prefixlen != addr2.prefixlen)
294 		return 1;
295 
296 	switch (addr1.family) {
297 	/* IPv4 */
298 	case AF_INET:
299 		if (memcmp(&addr1.addr.ipv4, &addr2.addr.ipv4,
300 				sizeof(struct in_addr)) != 0)
301 			return 1;
302 		break;
303 	/* IPv6 */
304 	case AF_INET6:
305 	{
306 		if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6,
307 				sizeof(struct in6_addr)) != 0)
308 			return 1;
309 		break;
310 	}
311 	/* thing that should not be */
312 	default:
313 		return -1;
314 	}
315 	return 0;
316 }
317 
318 static int
319 can_parse_addr(unsigned addr_flags, unsigned test_flags)
320 {
321 	if ((test_flags & addr_flags) == addr_flags) {
322 		/* if we are not trying to parse network addresses */
323 		if (test_flags < CMDLINE_IPADDR_NETWORK)
324 			return 1;
325 		/* if this is a network address */
326 		else if (addr_flags & CMDLINE_IPADDR_NETWORK)
327 			return 1;
328 	}
329 	return 0;
330 }
331 
332 int
333 test_parse_ipaddr_valid(void)
334 {
335 	cmdline_parse_token_ipaddr_t token;
336 	char buf[CMDLINE_TEST_BUFSIZE];
337 	cmdline_ipaddr_t result;
338 	unsigned i;
339 	uint8_t flags;
340 	int ret;
341 
342 	/* cover all cases in help */
343 	for (flags = 0x1; flags < 0x8; flags++) {
344 		token.ipaddr_data.flags = flags;
345 
346 		memset(buf, 0, sizeof(buf));
347 
348 		if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
349 				buf, sizeof(buf)) == -1) {
350 			printf("Error: help rejected valid parameters!\n");
351 			return -1;
352 		}
353 	}
354 
355 	/* test valid strings */
356 	for (i = 0; i < RTE_DIM(ipaddr_valid_strs); i++) {
357 
358 		/* test each valid string against different flags */
359 		for (flags = 1; flags < 0x8; flags++) {
360 
361 			/* skip bad flag */
362 			if (flags == CMDLINE_IPADDR_NETWORK)
363 				continue;
364 
365 			/* clear out everything */
366 			memset(buf, 0, sizeof(buf));
367 			memset(&result, 0, sizeof(result));
368 			memset(&token, 0, sizeof(token));
369 
370 			token.ipaddr_data.flags = flags;
371 
372 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
373 							buf, sizeof(buf));
374 
375 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
376 				ipaddr_valid_strs[i].str, (void*)&result,
377 				sizeof(result));
378 
379 			/* if should have passed, or should have failed */
380 			if ((ret < 0) ==
381 					(can_parse_addr(ipaddr_valid_strs[i].flags, flags))) {
382 				printf("Error: unexpected behavior when parsing %s as %s!\n",
383 						ipaddr_valid_strs[i].str, buf);
384 				printf("Parsed result: ");
385 				dump_addr(result);
386 				printf("Expected result: ");
387 				dump_addr(ipaddr_valid_strs[i].addr);
388 				return -1;
389 			}
390 			if (ret != -1 &&
391 					is_addr_different(result, ipaddr_valid_strs[i].addr)) {
392 				printf("Error: result mismatch when parsing %s as %s!\n",
393 						ipaddr_valid_strs[i].str, buf);
394 				printf("Parsed result: ");
395 				dump_addr(result);
396 				printf("Expected result: ");
397 				dump_addr(ipaddr_valid_strs[i].addr);
398 				return -1;
399 			}
400 		}
401 	}
402 
403 	/* test garbage ipv4 address strings */
404 	for (i = 0; i < RTE_DIM(ipaddr_garbage_addr4_strs); i++) {
405 
406 		struct in_addr tmp = IPv4_GARBAGE_ADDR;
407 
408 		/* test each valid string against different flags */
409 		for (flags = 1; flags < 0x8; flags++) {
410 
411 			/* skip bad flag */
412 			if (flags == CMDLINE_IPADDR_NETWORK)
413 				continue;
414 
415 			/* clear out everything */
416 			memset(buf, 0, sizeof(buf));
417 			memset(&result, 0, sizeof(result));
418 			memset(&token, 0, sizeof(token));
419 
420 			token.ipaddr_data.flags = flags;
421 
422 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
423 							buf, sizeof(buf));
424 
425 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
426 				ipaddr_garbage_addr4_strs[i], (void*)&result,
427 				sizeof(result));
428 
429 			/* if should have passed, or should have failed */
430 			if ((ret < 0) ==
431 					(can_parse_addr(CMDLINE_IPADDR_V4, flags))) {
432 				printf("Error: unexpected behavior when parsing %s as %s!\n",
433 						ipaddr_garbage_addr4_strs[i], buf);
434 				return -1;
435 			}
436 			if (ret != -1 &&
437 					memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
438 				printf("Error: result mismatch when parsing %s as %s!\n",
439 						ipaddr_garbage_addr4_strs[i], buf);
440 				return -1;
441 			}
442 		}
443 	}
444 
445 	/* test garbage ipv6 address strings */
446 	for (i = 0; i < RTE_DIM(ipaddr_garbage_addr6_strs); i++) {
447 
448 		cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
449 
450 		/* test each valid string against different flags */
451 		for (flags = 1; flags < 0x8; flags++) {
452 
453 			/* skip bad flag */
454 			if (flags == CMDLINE_IPADDR_NETWORK)
455 				continue;
456 
457 			/* clear out everything */
458 			memset(buf, 0, sizeof(buf));
459 			memset(&result, 0, sizeof(result));
460 			memset(&token, 0, sizeof(token));
461 
462 			token.ipaddr_data.flags = flags;
463 
464 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
465 							buf, sizeof(buf));
466 
467 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
468 				ipaddr_garbage_addr6_strs[i], (void*)&result,
469 				sizeof(result));
470 
471 			/* if should have passed, or should have failed */
472 			if ((ret < 0) ==
473 					(can_parse_addr(CMDLINE_IPADDR_V6, flags))) {
474 				printf("Error: unexpected behavior when parsing %s as %s!\n",
475 						ipaddr_garbage_addr6_strs[i], buf);
476 				return -1;
477 			}
478 			if (ret != -1 &&
479 					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
480 				printf("Error: result mismatch when parsing %s as %s!\n",
481 						ipaddr_garbage_addr6_strs[i], buf);
482 				return -1;
483 			}
484 		}
485 	}
486 
487 
488 	/* test garbage ipv4 network strings */
489 	for (i = 0; i < RTE_DIM(ipaddr_garbage_network4_strs); i++) {
490 
491 		struct in_addr tmp = IPv4_GARBAGE_ADDR;
492 
493 		/* test each valid string against different flags */
494 		for (flags = 1; flags < 0x8; flags++) {
495 
496 			/* skip bad flag */
497 			if (flags == CMDLINE_IPADDR_NETWORK)
498 				continue;
499 
500 			/* clear out everything */
501 			memset(buf, 0, sizeof(buf));
502 			memset(&result, 0, sizeof(result));
503 			memset(&token, 0, sizeof(token));
504 
505 			token.ipaddr_data.flags = flags;
506 
507 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
508 							buf, sizeof(buf));
509 
510 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
511 				ipaddr_garbage_network4_strs[i], (void*)&result,
512 				sizeof(result));
513 
514 			/* if should have passed, or should have failed */
515 			if ((ret < 0) ==
516 					(can_parse_addr(CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK, flags))) {
517 				printf("Error: unexpected behavior when parsing %s as %s!\n",
518 						ipaddr_garbage_network4_strs[i], buf);
519 				return -1;
520 			}
521 			if (ret != -1 &&
522 					memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
523 				printf("Error: result mismatch when parsing %s as %s!\n",
524 						ipaddr_garbage_network4_strs[i], buf);
525 				return -1;
526 			}
527 		}
528 	}
529 
530 	/* test garbage ipv6 address strings */
531 	for (i = 0; i < RTE_DIM(ipaddr_garbage_network6_strs); i++) {
532 
533 		cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
534 
535 		/* test each valid string against different flags */
536 		for (flags = 1; flags < 0x8; flags++) {
537 
538 			/* skip bad flag */
539 			if (flags == CMDLINE_IPADDR_NETWORK)
540 				continue;
541 
542 			/* clear out everything */
543 			memset(buf, 0, sizeof(buf));
544 			memset(&result, 0, sizeof(result));
545 			memset(&token, 0, sizeof(token));
546 
547 			token.ipaddr_data.flags = flags;
548 
549 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
550 							buf, sizeof(buf));
551 
552 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
553 				ipaddr_garbage_network6_strs[i], (void*)&result,
554 				sizeof(result));
555 
556 			/* if should have passed, or should have failed */
557 			if ((ret < 0) ==
558 					(can_parse_addr(CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK, flags))) {
559 				printf("Error: unexpected behavior when parsing %s as %s!\n",
560 						ipaddr_garbage_network6_strs[i], buf);
561 				return -1;
562 			}
563 			if (ret != -1 &&
564 					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
565 				printf("Error: result mismatch when parsing %s as %s!\n",
566 						ipaddr_garbage_network6_strs[i], buf);
567 				return -1;
568 			}
569 		}
570 	}
571 
572 	return 0;
573 }
574 
575 int
576 test_parse_ipaddr_invalid_data(void)
577 {
578 	cmdline_parse_token_ipaddr_t token;
579 	char buf[CMDLINE_TEST_BUFSIZE];
580 	cmdline_ipaddr_t result;
581 	unsigned i;
582 	uint8_t flags;
583 	int ret;
584 
585 	memset(&result, 0, sizeof(result));
586 
587 	/* test invalid strings */
588 	for (i = 0; i < RTE_DIM(ipaddr_invalid_strs); i++) {
589 
590 		/* test each valid string against different flags */
591 		for (flags = 1; flags < 0x8; flags++) {
592 
593 			/* skip bad flag */
594 			if (flags == CMDLINE_IPADDR_NETWORK)
595 				continue;
596 
597 			/* clear out everything */
598 			memset(buf, 0, sizeof(buf));
599 			memset(&token, 0, sizeof(token));
600 
601 			token.ipaddr_data.flags = flags;
602 
603 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
604 					buf, sizeof(buf));
605 
606 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
607 				ipaddr_invalid_strs[i], (void*)&result,
608 				sizeof(result));
609 
610 			if (ret != -1) {
611 				printf("Error: parsing %s as %s succeeded!\n",
612 						ipaddr_invalid_strs[i], buf);
613 				printf("Parsed result: ");
614 				dump_addr(result);
615 				return -1;
616 			}
617 		}
618 	}
619 
620 	return 0;
621 }
622 
623 int
624 test_parse_ipaddr_invalid_param(void)
625 {
626 	cmdline_parse_token_ipaddr_t token;
627 	char buf[CMDLINE_TEST_BUFSIZE];
628 	cmdline_ipaddr_t result;
629 
630 	snprintf(buf, sizeof(buf), "1.2.3.4");
631 	token.ipaddr_data.flags = CMDLINE_IPADDR_V4;
632 
633 	/* null token */
634 	if (cmdline_parse_ipaddr(NULL, buf, (void*)&result,
635 			sizeof(result)) != -1) {
636 		printf("Error: parser accepted invalid parameters!\n");
637 		return -1;
638 	}
639 	/* null buffer */
640 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
641 			NULL, (void*)&result, sizeof(result)) != -1) {
642 		printf("Error: parser accepted invalid parameters!\n");
643 		return -1;
644 	}
645 	/* empty buffer */
646 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
647 			"", (void*)&result, sizeof(result)) != -1) {
648 		printf("Error: parser accepted invalid parameters!\n");
649 		return -1;
650 	}
651 	/* null result */
652 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
653 			buf, NULL, 0) == -1) {
654 		printf("Error: parser rejected null result!\n");
655 		return -1;
656 	}
657 
658 	/* null token */
659 	if (cmdline_get_help_ipaddr(NULL, buf, 0) != -1) {
660 		printf("Error: help accepted invalid parameters!\n");
661 		return -1;
662 	}
663 	/* null buffer */
664 	if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
665 			NULL, 0) != -1) {
666 		printf("Error: help accepted invalid parameters!\n");
667 		return -1;
668 	}
669 	return 0;
670 }
671