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
dump_addr(cmdline_ipaddr_t addr)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
is_addr_different(cmdline_ipaddr_t addr1,cmdline_ipaddr_t addr2)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
can_parse_addr(unsigned addr_flags,unsigned test_flags)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
test_parse_ipaddr_valid(void)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
test_parse_ipaddr_invalid_data(void)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
test_parse_ipaddr_invalid_param(void)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