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