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