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