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