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