xref: /f-stack/dpdk/app/test/test_cmdline_ipaddr.c (revision 2d9fd380)
14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright(c) 2010-2014 Intel Corporation
34418919fSjohnjiang  */
44418919fSjohnjiang 
54418919fSjohnjiang #include <stdio.h>
64418919fSjohnjiang #include <string.h>
74418919fSjohnjiang #include <inttypes.h>
84418919fSjohnjiang #include <netinet/in.h>
94418919fSjohnjiang #include <sys/socket.h>
104418919fSjohnjiang 
114418919fSjohnjiang #include <rte_string_fns.h>
124418919fSjohnjiang 
134418919fSjohnjiang #include <cmdline_parse.h>
144418919fSjohnjiang #include <cmdline_parse_ipaddr.h>
154418919fSjohnjiang 
164418919fSjohnjiang #include "test_cmdline.h"
174418919fSjohnjiang 
184418919fSjohnjiang #define IP4(a,b,c,d) {((uint32_t)(((a) & 0xff)) | \
194418919fSjohnjiang 					   (((b) & 0xff) << 8) | \
204418919fSjohnjiang 					   (((c) & 0xff) << 16)  | \
214418919fSjohnjiang 					   ((d) & 0xff)  << 24)}
224418919fSjohnjiang 
234418919fSjohnjiang #define U16_SWAP(x) \
244418919fSjohnjiang 		(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
254418919fSjohnjiang 
264418919fSjohnjiang /* create IPv6 address, swapping bytes where needed */
274418919fSjohnjiang #ifndef s6_addr16
284418919fSjohnjiang # define s6_addr16      __u6_addr.__u6_addr16
294418919fSjohnjiang #endif
304418919fSjohnjiang #define IP6(a,b,c,d,e,f,g,h) .ipv6 = \
314418919fSjohnjiang 		{.s6_addr16 = \
324418919fSjohnjiang 		{U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\
334418919fSjohnjiang 		 U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}}
344418919fSjohnjiang 
354418919fSjohnjiang /** these are defined in netinet/in.h but not present in linux headers */
364418919fSjohnjiang #ifndef NIPQUAD
374418919fSjohnjiang 
384418919fSjohnjiang #define NIPQUAD_FMT "%u.%u.%u.%u"
394418919fSjohnjiang #define NIPQUAD(addr)				\
404418919fSjohnjiang 	(unsigned)((unsigned char *)&addr)[0],	\
414418919fSjohnjiang 	(unsigned)((unsigned char *)&addr)[1],	\
424418919fSjohnjiang 	(unsigned)((unsigned char *)&addr)[2],	\
434418919fSjohnjiang 	(unsigned)((unsigned char *)&addr)[3]
444418919fSjohnjiang 
454418919fSjohnjiang #define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
464418919fSjohnjiang #define NIP6(addr)					\
474418919fSjohnjiang 	(unsigned)((addr).s6_addr[0]),			\
484418919fSjohnjiang 	(unsigned)((addr).s6_addr[1]),			\
494418919fSjohnjiang 	(unsigned)((addr).s6_addr[2]),			\
504418919fSjohnjiang 	(unsigned)((addr).s6_addr[3]),			\
514418919fSjohnjiang 	(unsigned)((addr).s6_addr[4]),			\
524418919fSjohnjiang 	(unsigned)((addr).s6_addr[5]),			\
534418919fSjohnjiang 	(unsigned)((addr).s6_addr[6]),			\
544418919fSjohnjiang 	(unsigned)((addr).s6_addr[7]),			\
554418919fSjohnjiang 	(unsigned)((addr).s6_addr[8]),			\
564418919fSjohnjiang 	(unsigned)((addr).s6_addr[9]),			\
574418919fSjohnjiang 	(unsigned)((addr).s6_addr[10]),			\
584418919fSjohnjiang 	(unsigned)((addr).s6_addr[11]),			\
594418919fSjohnjiang 	(unsigned)((addr).s6_addr[12]),			\
604418919fSjohnjiang 	(unsigned)((addr).s6_addr[13]),			\
614418919fSjohnjiang 	(unsigned)((addr).s6_addr[14]),			\
624418919fSjohnjiang 	(unsigned)((addr).s6_addr[15])
634418919fSjohnjiang 
644418919fSjohnjiang #endif
654418919fSjohnjiang 
664418919fSjohnjiang 
674418919fSjohnjiang 
684418919fSjohnjiang struct ipaddr_str {
694418919fSjohnjiang 	const char * str;
704418919fSjohnjiang 	cmdline_ipaddr_t addr;
714418919fSjohnjiang 	unsigned flags;
724418919fSjohnjiang };
734418919fSjohnjiang 
744418919fSjohnjiang const struct ipaddr_str ipaddr_valid_strs[] = {
754418919fSjohnjiang 		{"0.0.0.0", {AF_INET, {IP4(0,0,0,0)}, 0},
764418919fSjohnjiang 				CMDLINE_IPADDR_V4},
774418919fSjohnjiang 		{"0.0.0.0/0", {AF_INET, {IP4(0,0,0,0)}, 0},
784418919fSjohnjiang 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
794418919fSjohnjiang 		{"0.0.0.0/24", {AF_INET, {IP4(0,0,0,0)}, 24},
804418919fSjohnjiang 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
814418919fSjohnjiang 		{"192.168.1.0/24", {AF_INET, {IP4(192,168,1,0)}, 24},
824418919fSjohnjiang 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
834418919fSjohnjiang 		{"34.56.78.90/1", {AF_INET, {IP4(34,56,78,90)}, 1},
844418919fSjohnjiang 				CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK},
854418919fSjohnjiang 		{"::", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 0},
864418919fSjohnjiang 					CMDLINE_IPADDR_V6},
874418919fSjohnjiang 		{"::1", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 0},
884418919fSjohnjiang 				CMDLINE_IPADDR_V6},
894418919fSjohnjiang 		{"::1/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,1)}, 32},
904418919fSjohnjiang 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
914418919fSjohnjiang 		{"::/32", {AF_INET6, {IP6(0,0,0,0,0,0,0,0)}, 32},
924418919fSjohnjiang 					CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
934418919fSjohnjiang 		/* RFC5952 requests that only lowercase should be used */
944418919fSjohnjiang 		{"1234:5678:90ab:cdef:4321:8765:BA09:FEDC", {AF_INET6,
954418919fSjohnjiang 				{IP6(0x1234,0x5678,0x90AB,0xCDEF,0x4321,0x8765,0xBA09,0xFEDC)},
964418919fSjohnjiang 				0},
974418919fSjohnjiang 				CMDLINE_IPADDR_V6},
984418919fSjohnjiang 		{"1234::1234/64", {AF_INET6,
994418919fSjohnjiang 				{IP6(0x1234,0,0,0,0,0,0,0x1234)},
1004418919fSjohnjiang 				64},
1014418919fSjohnjiang 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
1024418919fSjohnjiang 		{"1234::/64", {AF_INET6,
1034418919fSjohnjiang 				{IP6(0x1234,0,0,0,0,0,0,0)},
1044418919fSjohnjiang 				64},
1054418919fSjohnjiang 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
1064418919fSjohnjiang 		{"1:1::1/32", {AF_INET6,
1074418919fSjohnjiang 				{IP6(1,1,0,0,0,0,0,1)},
1084418919fSjohnjiang 				32},
1094418919fSjohnjiang 				CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
1104418919fSjohnjiang 		{"1:2:3:4::/64", {AF_INET6,
1114418919fSjohnjiang 				{IP6(1,2,3,4,0,0,0,0)},
1124418919fSjohnjiang 				64},
1134418919fSjohnjiang 			CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
1144418919fSjohnjiang 		{"::ffff:192.168.1.0/64", {AF_INET6,
1154418919fSjohnjiang 				{IP6(0,0,0,0,0,0xFFFF,0xC0A8,0x100)},
1164418919fSjohnjiang 				64},
1174418919fSjohnjiang 			CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK},
1184418919fSjohnjiang 		/* RFC5952 requests not using :: to skip one block of zeros*/
1194418919fSjohnjiang 		{"1::2:3:4:5:6:7", {AF_INET6,
1204418919fSjohnjiang 				{IP6(1,0,2,3,4,5,6,7)},
1214418919fSjohnjiang 				0},
1224418919fSjohnjiang 			CMDLINE_IPADDR_V6},
1234418919fSjohnjiang };
1244418919fSjohnjiang 
1254418919fSjohnjiang const char * ipaddr_garbage_addr4_strs[] = {
1264418919fSjohnjiang 		/* IPv4 */
1274418919fSjohnjiang 		"192.168.1.0 garbage",
1284418919fSjohnjiang 		"192.168.1.0\0garbage",
1294418919fSjohnjiang 		"192.168.1.0#garbage",
1304418919fSjohnjiang 		"192.168.1.0\tgarbage",
1314418919fSjohnjiang 		"192.168.1.0\rgarbage",
1324418919fSjohnjiang 		"192.168.1.0\ngarbage",
1334418919fSjohnjiang };
1344418919fSjohnjiang #define IPv4_GARBAGE_ADDR IP4(192,168,1,0)
1354418919fSjohnjiang 
1364418919fSjohnjiang const char * ipaddr_garbage_addr6_strs[] = {
1374418919fSjohnjiang 		/* IPv6 */
1384418919fSjohnjiang 		"1:2:3:4::8 garbage",
1394418919fSjohnjiang 		"1:2:3:4::8#garbage",
1404418919fSjohnjiang 		"1:2:3:4::8\0garbage",
1414418919fSjohnjiang 		"1:2:3:4::8\rgarbage",
1424418919fSjohnjiang 		"1:2:3:4::8\ngarbage",
1434418919fSjohnjiang 		"1:2:3:4::8\tgarbage",
1444418919fSjohnjiang };
1454418919fSjohnjiang #define IPv6_GARBAGE_ADDR {IP6(1,2,3,4,0,0,0,8)}
1464418919fSjohnjiang 
1474418919fSjohnjiang const char * ipaddr_garbage_network4_strs[] = {
1484418919fSjohnjiang 		/* IPv4 */
1494418919fSjohnjiang 		"192.168.1.0/24 garbage",
1504418919fSjohnjiang 		"192.168.1.0/24\0garbage",
1514418919fSjohnjiang 		"192.168.1.0/24#garbage",
1524418919fSjohnjiang 		"192.168.1.0/24\tgarbage",
1534418919fSjohnjiang 		"192.168.1.0/24\rgarbage",
1544418919fSjohnjiang 		"192.168.1.0/24\ngarbage",
1554418919fSjohnjiang };
1564418919fSjohnjiang #define IPv4_GARBAGE_PREFIX 24
1574418919fSjohnjiang 
1584418919fSjohnjiang const char * ipaddr_garbage_network6_strs[] = {
1594418919fSjohnjiang 		/* IPv6 */
1604418919fSjohnjiang 		"1:2:3:4::8/64 garbage",
1614418919fSjohnjiang 		"1:2:3:4::8/64#garbage",
1624418919fSjohnjiang 		"1:2:3:4::8/64\0garbage",
1634418919fSjohnjiang 		"1:2:3:4::8/64\rgarbage",
1644418919fSjohnjiang 		"1:2:3:4::8/64\ngarbage",
1654418919fSjohnjiang 		"1:2:3:4::8/64\tgarbage",
1664418919fSjohnjiang };
1674418919fSjohnjiang #define IPv6_GARBAGE_PREFIX 64
1684418919fSjohnjiang 
1694418919fSjohnjiang 
1704418919fSjohnjiang 
1714418919fSjohnjiang const char * ipaddr_invalid_strs[] = {
1724418919fSjohnjiang 		/** IPv4 **/
1734418919fSjohnjiang 
1744418919fSjohnjiang 		/* invalid numbers */
1754418919fSjohnjiang 		"0.0.0.-1",
1764418919fSjohnjiang 		"0.0.-1.0",
1774418919fSjohnjiang 		"0.-1.0.0",
1784418919fSjohnjiang 		"-1.0.0.0",
1794418919fSjohnjiang 		"0.0.0.-1/24",
1804418919fSjohnjiang 		"256.123.123.123",
1814418919fSjohnjiang 		"255.256.123.123",
1824418919fSjohnjiang 		"255.255.256.123",
1834418919fSjohnjiang 		"255.255.255.256",
1844418919fSjohnjiang 		"256.123.123.123/24",
1854418919fSjohnjiang 		"255.256.123.123/24",
1864418919fSjohnjiang 		"255.255.256.123/24",
1874418919fSjohnjiang 		"255.255.255.256/24",
1884418919fSjohnjiang 		/* invalid network mask */
1894418919fSjohnjiang 		"1.2.3.4/33",
1904418919fSjohnjiang 		"1.2.3.4/33231313",
1914418919fSjohnjiang 		"1.2.3.4/-1",
1924418919fSjohnjiang 		"1.2.3.4/24/33",
1934418919fSjohnjiang 		"1.2.3.4/24/-1",
1944418919fSjohnjiang 		"1.2.3.4/24/",
1954418919fSjohnjiang 		/* wrong format */
1964418919fSjohnjiang 		"1/24"
1974418919fSjohnjiang 		"/24"
1984418919fSjohnjiang 		"123.123.123",
1994418919fSjohnjiang 		"123.123.123.",
2004418919fSjohnjiang 		"123.123.123.123.",
2014418919fSjohnjiang 		"123.123.123..123",
2024418919fSjohnjiang 		"123.123.123.123.123",
2034418919fSjohnjiang 		".123.123.123",
2044418919fSjohnjiang 		".123.123.123.123",
2054418919fSjohnjiang 		"123.123.123/24",
2064418919fSjohnjiang 		"123.123.123./24",
2074418919fSjohnjiang 		"123.123.123.123./24",
2084418919fSjohnjiang 		"123.123.123..123/24",
2094418919fSjohnjiang 		"123.123.123.123.123/24",
2104418919fSjohnjiang 		".123.123.123/24",
2114418919fSjohnjiang 		".123.123.123.123/24",
2124418919fSjohnjiang 		/* invalid characters */
2134418919fSjohnjiang 		"123.123.123.12F",
2144418919fSjohnjiang 		"123.123.12F.123",
2154418919fSjohnjiang 		"123.12F.123.123",
2164418919fSjohnjiang 		"12F.123.123.123",
2174418919fSjohnjiang 		"12J.123.123.123",
2184418919fSjohnjiang 		"123,123,123,123",
2194418919fSjohnjiang 		"123!123!123!12F",
2204418919fSjohnjiang 		"123.123.123.123/4F",
2214418919fSjohnjiang 
2224418919fSjohnjiang 		/** IPv6 **/
2234418919fSjohnjiang 
2244418919fSjohnjiang 		/* wrong format */
2254418919fSjohnjiang 		"::fffff",
2264418919fSjohnjiang 		"ffff:",
2274418919fSjohnjiang 		"1:2:3:4:5:6:7:192.168.1.1",
2284418919fSjohnjiang 		"1234:192.168.1.1:ffff::",
2294418919fSjohnjiang 		"1:2:3:4:5:6:7:890ab",
2304418919fSjohnjiang 		"1:2:3:4:5:6:7890a:b",
2314418919fSjohnjiang 		"1:2:3:4:5:67890:a:b",
2324418919fSjohnjiang 		"1:2:3:4:56789:0:a:b",
2334418919fSjohnjiang 		"1:2:3:45678:9:0:a:b",
2344418919fSjohnjiang 		"1:2:34567:8:9:0:a:b",
2354418919fSjohnjiang 		"1:23456:7:8:9:0:a:b",
2364418919fSjohnjiang 		"12345:6:7:8:9:0:a:b",
2374418919fSjohnjiang 		"1:::2",
2384418919fSjohnjiang 		"1::::2",
2394418919fSjohnjiang 		"::fffff/64",
2404418919fSjohnjiang 		"1::2::3",
2414418919fSjohnjiang 		"1::2::3/64",
2424418919fSjohnjiang 		":1:2",
2434418919fSjohnjiang 		":1:2/64",
2444418919fSjohnjiang 		":1::2",
2454418919fSjohnjiang 		":1::2/64",
2464418919fSjohnjiang 		"1::2:3:4:5:6:7:8/64",
2474418919fSjohnjiang 
2484418919fSjohnjiang 		/* invalid network mask */
2494418919fSjohnjiang 		"1:2:3:4:5:6:7:8/129",
2504418919fSjohnjiang 		"1:2:3:4:5:6:7:8/-1",
2514418919fSjohnjiang 
2524418919fSjohnjiang 		/* invalid characters */
2534418919fSjohnjiang 		"a:b:c:d:e:f:g::",
2544418919fSjohnjiang 
2554418919fSjohnjiang 		/** misc **/
2564418919fSjohnjiang 
2574418919fSjohnjiang 		/* too long */
2584418919fSjohnjiang 		"1234:1234:1234:1234:1234:1234:1234:1234:1234:1234:1234"
2594418919fSjohnjiang 		"random invalid text",
2604418919fSjohnjiang 		"",
2614418919fSjohnjiang 		"\0",
2624418919fSjohnjiang 		" ",
2634418919fSjohnjiang };
2644418919fSjohnjiang 
2654418919fSjohnjiang static void
dump_addr(cmdline_ipaddr_t addr)2664418919fSjohnjiang dump_addr(cmdline_ipaddr_t addr)
2674418919fSjohnjiang {
2684418919fSjohnjiang 	switch (addr.family) {
2694418919fSjohnjiang 	case AF_INET:
2704418919fSjohnjiang 	{
2714418919fSjohnjiang 		printf(NIPQUAD_FMT " prefixlen=%u\n",
2724418919fSjohnjiang 				NIPQUAD(addr.addr.ipv4.s_addr), addr.prefixlen);
2734418919fSjohnjiang 		break;
2744418919fSjohnjiang 	}
2754418919fSjohnjiang 	case AF_INET6:
2764418919fSjohnjiang 	{
2774418919fSjohnjiang 		printf(NIP6_FMT " prefixlen=%u\n",
2784418919fSjohnjiang 				NIP6(addr.addr.ipv6), addr.prefixlen);
2794418919fSjohnjiang 		break;
2804418919fSjohnjiang 	}
2814418919fSjohnjiang 	default:
2824418919fSjohnjiang 		printf("Can't dump: unknown address family.\n");
2834418919fSjohnjiang 		return;
2844418919fSjohnjiang 	}
2854418919fSjohnjiang }
2864418919fSjohnjiang 
2874418919fSjohnjiang 
2884418919fSjohnjiang static int
is_addr_different(cmdline_ipaddr_t addr1,cmdline_ipaddr_t addr2)2894418919fSjohnjiang is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2)
2904418919fSjohnjiang {
2914418919fSjohnjiang 	if (addr1.family != addr2.family)
2924418919fSjohnjiang 		return 1;
2934418919fSjohnjiang 
2944418919fSjohnjiang 	if (addr1.prefixlen != addr2.prefixlen)
2954418919fSjohnjiang 		return 1;
2964418919fSjohnjiang 
2974418919fSjohnjiang 	switch (addr1.family) {
2984418919fSjohnjiang 	/* IPv4 */
2994418919fSjohnjiang 	case AF_INET:
3004418919fSjohnjiang 		if (memcmp(&addr1.addr.ipv4, &addr2.addr.ipv4,
3014418919fSjohnjiang 				sizeof(struct in_addr)) != 0)
3024418919fSjohnjiang 			return 1;
3034418919fSjohnjiang 		break;
3044418919fSjohnjiang 	/* IPv6 */
3054418919fSjohnjiang 	case AF_INET6:
3064418919fSjohnjiang 	{
3074418919fSjohnjiang 		if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6,
3084418919fSjohnjiang 				sizeof(struct in6_addr)) != 0)
3094418919fSjohnjiang 			return 1;
3104418919fSjohnjiang 		break;
3114418919fSjohnjiang 	}
3124418919fSjohnjiang 	/* thing that should not be */
3134418919fSjohnjiang 	default:
3144418919fSjohnjiang 		return -1;
3154418919fSjohnjiang 	}
3164418919fSjohnjiang 	return 0;
3174418919fSjohnjiang }
3184418919fSjohnjiang 
3194418919fSjohnjiang static int
can_parse_addr(unsigned addr_flags,unsigned test_flags)3204418919fSjohnjiang can_parse_addr(unsigned addr_flags, unsigned test_flags)
3214418919fSjohnjiang {
3224418919fSjohnjiang 	if ((test_flags & addr_flags) == addr_flags) {
3234418919fSjohnjiang 		/* if we are not trying to parse network addresses */
3244418919fSjohnjiang 		if (test_flags < CMDLINE_IPADDR_NETWORK)
3254418919fSjohnjiang 			return 1;
3264418919fSjohnjiang 		/* if this is a network address */
3274418919fSjohnjiang 		else if (addr_flags & CMDLINE_IPADDR_NETWORK)
3284418919fSjohnjiang 			return 1;
3294418919fSjohnjiang 	}
3304418919fSjohnjiang 	return 0;
3314418919fSjohnjiang }
3324418919fSjohnjiang 
3334418919fSjohnjiang int
test_parse_ipaddr_valid(void)3344418919fSjohnjiang test_parse_ipaddr_valid(void)
3354418919fSjohnjiang {
3364418919fSjohnjiang 	cmdline_parse_token_ipaddr_t token;
3374418919fSjohnjiang 	char buf[CMDLINE_TEST_BUFSIZE];
3384418919fSjohnjiang 	cmdline_ipaddr_t result;
3394418919fSjohnjiang 	unsigned i;
3404418919fSjohnjiang 	uint8_t flags;
3414418919fSjohnjiang 	int ret;
3424418919fSjohnjiang 
3434418919fSjohnjiang 	/* cover all cases in help */
3444418919fSjohnjiang 	for (flags = 0x1; flags < 0x8; flags++) {
3454418919fSjohnjiang 		token.ipaddr_data.flags = flags;
3464418919fSjohnjiang 
3474418919fSjohnjiang 		memset(buf, 0, sizeof(buf));
3484418919fSjohnjiang 
3494418919fSjohnjiang 		if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
3504418919fSjohnjiang 				buf, sizeof(buf)) == -1) {
3514418919fSjohnjiang 			printf("Error: help rejected valid parameters!\n");
3524418919fSjohnjiang 			return -1;
3534418919fSjohnjiang 		}
3544418919fSjohnjiang 	}
3554418919fSjohnjiang 
3564418919fSjohnjiang 	/* test valid strings */
357*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_valid_strs); i++) {
3584418919fSjohnjiang 
3594418919fSjohnjiang 		/* test each valid string against different flags */
3604418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
3614418919fSjohnjiang 
3624418919fSjohnjiang 			/* skip bad flag */
3634418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
3644418919fSjohnjiang 				continue;
3654418919fSjohnjiang 
3664418919fSjohnjiang 			/* clear out everything */
3674418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
3684418919fSjohnjiang 			memset(&result, 0, sizeof(result));
3694418919fSjohnjiang 			memset(&token, 0, sizeof(token));
3704418919fSjohnjiang 
3714418919fSjohnjiang 			token.ipaddr_data.flags = flags;
3724418919fSjohnjiang 
3734418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
3744418919fSjohnjiang 							buf, sizeof(buf));
3754418919fSjohnjiang 
3764418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
3774418919fSjohnjiang 				ipaddr_valid_strs[i].str, (void*)&result,
3784418919fSjohnjiang 				sizeof(result));
3794418919fSjohnjiang 
3804418919fSjohnjiang 			/* if should have passed, or should have failed */
3814418919fSjohnjiang 			if ((ret < 0) ==
3824418919fSjohnjiang 					(can_parse_addr(ipaddr_valid_strs[i].flags, flags))) {
3834418919fSjohnjiang 				printf("Error: unexpected behavior when parsing %s as %s!\n",
3844418919fSjohnjiang 						ipaddr_valid_strs[i].str, buf);
3854418919fSjohnjiang 				printf("Parsed result: ");
3864418919fSjohnjiang 				dump_addr(result);
3874418919fSjohnjiang 				printf("Expected result: ");
3884418919fSjohnjiang 				dump_addr(ipaddr_valid_strs[i].addr);
3894418919fSjohnjiang 				return -1;
3904418919fSjohnjiang 			}
3914418919fSjohnjiang 			if (ret != -1 &&
3924418919fSjohnjiang 					is_addr_different(result, ipaddr_valid_strs[i].addr)) {
3934418919fSjohnjiang 				printf("Error: result mismatch when parsing %s as %s!\n",
3944418919fSjohnjiang 						ipaddr_valid_strs[i].str, buf);
3954418919fSjohnjiang 				printf("Parsed result: ");
3964418919fSjohnjiang 				dump_addr(result);
3974418919fSjohnjiang 				printf("Expected result: ");
3984418919fSjohnjiang 				dump_addr(ipaddr_valid_strs[i].addr);
3994418919fSjohnjiang 				return -1;
4004418919fSjohnjiang 			}
4014418919fSjohnjiang 		}
4024418919fSjohnjiang 	}
4034418919fSjohnjiang 
4044418919fSjohnjiang 	/* test garbage ipv4 address strings */
405*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_garbage_addr4_strs); i++) {
4064418919fSjohnjiang 
4074418919fSjohnjiang 		struct in_addr tmp = IPv4_GARBAGE_ADDR;
4084418919fSjohnjiang 
4094418919fSjohnjiang 		/* test each valid string against different flags */
4104418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
4114418919fSjohnjiang 
4124418919fSjohnjiang 			/* skip bad flag */
4134418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
4144418919fSjohnjiang 				continue;
4154418919fSjohnjiang 
4164418919fSjohnjiang 			/* clear out everything */
4174418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
4184418919fSjohnjiang 			memset(&result, 0, sizeof(result));
4194418919fSjohnjiang 			memset(&token, 0, sizeof(token));
4204418919fSjohnjiang 
4214418919fSjohnjiang 			token.ipaddr_data.flags = flags;
4224418919fSjohnjiang 
4234418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
4244418919fSjohnjiang 							buf, sizeof(buf));
4254418919fSjohnjiang 
4264418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
4274418919fSjohnjiang 				ipaddr_garbage_addr4_strs[i], (void*)&result,
4284418919fSjohnjiang 				sizeof(result));
4294418919fSjohnjiang 
4304418919fSjohnjiang 			/* if should have passed, or should have failed */
4314418919fSjohnjiang 			if ((ret < 0) ==
4324418919fSjohnjiang 					(can_parse_addr(CMDLINE_IPADDR_V4, flags))) {
4334418919fSjohnjiang 				printf("Error: unexpected behavior when parsing %s as %s!\n",
4344418919fSjohnjiang 						ipaddr_garbage_addr4_strs[i], buf);
4354418919fSjohnjiang 				return -1;
4364418919fSjohnjiang 			}
4374418919fSjohnjiang 			if (ret != -1 &&
4384418919fSjohnjiang 					memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
4394418919fSjohnjiang 				printf("Error: result mismatch when parsing %s as %s!\n",
4404418919fSjohnjiang 						ipaddr_garbage_addr4_strs[i], buf);
4414418919fSjohnjiang 				return -1;
4424418919fSjohnjiang 			}
4434418919fSjohnjiang 		}
4444418919fSjohnjiang 	}
4454418919fSjohnjiang 
4464418919fSjohnjiang 	/* test garbage ipv6 address strings */
447*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_garbage_addr6_strs); i++) {
4484418919fSjohnjiang 
4494418919fSjohnjiang 		cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
4504418919fSjohnjiang 
4514418919fSjohnjiang 		/* test each valid string against different flags */
4524418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
4534418919fSjohnjiang 
4544418919fSjohnjiang 			/* skip bad flag */
4554418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
4564418919fSjohnjiang 				continue;
4574418919fSjohnjiang 
4584418919fSjohnjiang 			/* clear out everything */
4594418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
4604418919fSjohnjiang 			memset(&result, 0, sizeof(result));
4614418919fSjohnjiang 			memset(&token, 0, sizeof(token));
4624418919fSjohnjiang 
4634418919fSjohnjiang 			token.ipaddr_data.flags = flags;
4644418919fSjohnjiang 
4654418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
4664418919fSjohnjiang 							buf, sizeof(buf));
4674418919fSjohnjiang 
4684418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
4694418919fSjohnjiang 				ipaddr_garbage_addr6_strs[i], (void*)&result,
4704418919fSjohnjiang 				sizeof(result));
4714418919fSjohnjiang 
4724418919fSjohnjiang 			/* if should have passed, or should have failed */
4734418919fSjohnjiang 			if ((ret < 0) ==
4744418919fSjohnjiang 					(can_parse_addr(CMDLINE_IPADDR_V6, flags))) {
4754418919fSjohnjiang 				printf("Error: unexpected behavior when parsing %s as %s!\n",
4764418919fSjohnjiang 						ipaddr_garbage_addr6_strs[i], buf);
4774418919fSjohnjiang 				return -1;
4784418919fSjohnjiang 			}
4794418919fSjohnjiang 			if (ret != -1 &&
4804418919fSjohnjiang 					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
4814418919fSjohnjiang 				printf("Error: result mismatch when parsing %s as %s!\n",
4824418919fSjohnjiang 						ipaddr_garbage_addr6_strs[i], buf);
4834418919fSjohnjiang 				return -1;
4844418919fSjohnjiang 			}
4854418919fSjohnjiang 		}
4864418919fSjohnjiang 	}
4874418919fSjohnjiang 
4884418919fSjohnjiang 
4894418919fSjohnjiang 	/* test garbage ipv4 network strings */
490*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_garbage_network4_strs); i++) {
4914418919fSjohnjiang 
4924418919fSjohnjiang 		struct in_addr tmp = IPv4_GARBAGE_ADDR;
4934418919fSjohnjiang 
4944418919fSjohnjiang 		/* test each valid string against different flags */
4954418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
4964418919fSjohnjiang 
4974418919fSjohnjiang 			/* skip bad flag */
4984418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
4994418919fSjohnjiang 				continue;
5004418919fSjohnjiang 
5014418919fSjohnjiang 			/* clear out everything */
5024418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
5034418919fSjohnjiang 			memset(&result, 0, sizeof(result));
5044418919fSjohnjiang 			memset(&token, 0, sizeof(token));
5054418919fSjohnjiang 
5064418919fSjohnjiang 			token.ipaddr_data.flags = flags;
5074418919fSjohnjiang 
5084418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
5094418919fSjohnjiang 							buf, sizeof(buf));
5104418919fSjohnjiang 
5114418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
5124418919fSjohnjiang 				ipaddr_garbage_network4_strs[i], (void*)&result,
5134418919fSjohnjiang 				sizeof(result));
5144418919fSjohnjiang 
5154418919fSjohnjiang 			/* if should have passed, or should have failed */
5164418919fSjohnjiang 			if ((ret < 0) ==
5174418919fSjohnjiang 					(can_parse_addr(CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK, flags))) {
5184418919fSjohnjiang 				printf("Error: unexpected behavior when parsing %s as %s!\n",
5194418919fSjohnjiang 						ipaddr_garbage_network4_strs[i], buf);
5204418919fSjohnjiang 				return -1;
5214418919fSjohnjiang 			}
5224418919fSjohnjiang 			if (ret != -1 &&
5234418919fSjohnjiang 					memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
5244418919fSjohnjiang 				printf("Error: result mismatch when parsing %s as %s!\n",
5254418919fSjohnjiang 						ipaddr_garbage_network4_strs[i], buf);
5264418919fSjohnjiang 				return -1;
5274418919fSjohnjiang 			}
5284418919fSjohnjiang 		}
5294418919fSjohnjiang 	}
5304418919fSjohnjiang 
5314418919fSjohnjiang 	/* test garbage ipv6 address strings */
532*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_garbage_network6_strs); i++) {
5334418919fSjohnjiang 
5344418919fSjohnjiang 		cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
5354418919fSjohnjiang 
5364418919fSjohnjiang 		/* test each valid string against different flags */
5374418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
5384418919fSjohnjiang 
5394418919fSjohnjiang 			/* skip bad flag */
5404418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
5414418919fSjohnjiang 				continue;
5424418919fSjohnjiang 
5434418919fSjohnjiang 			/* clear out everything */
5444418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
5454418919fSjohnjiang 			memset(&result, 0, sizeof(result));
5464418919fSjohnjiang 			memset(&token, 0, sizeof(token));
5474418919fSjohnjiang 
5484418919fSjohnjiang 			token.ipaddr_data.flags = flags;
5494418919fSjohnjiang 
5504418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
5514418919fSjohnjiang 							buf, sizeof(buf));
5524418919fSjohnjiang 
5534418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
5544418919fSjohnjiang 				ipaddr_garbage_network6_strs[i], (void*)&result,
5554418919fSjohnjiang 				sizeof(result));
5564418919fSjohnjiang 
5574418919fSjohnjiang 			/* if should have passed, or should have failed */
5584418919fSjohnjiang 			if ((ret < 0) ==
5594418919fSjohnjiang 					(can_parse_addr(CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK, flags))) {
5604418919fSjohnjiang 				printf("Error: unexpected behavior when parsing %s as %s!\n",
5614418919fSjohnjiang 						ipaddr_garbage_network6_strs[i], buf);
5624418919fSjohnjiang 				return -1;
5634418919fSjohnjiang 			}
5644418919fSjohnjiang 			if (ret != -1 &&
5654418919fSjohnjiang 					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
5664418919fSjohnjiang 				printf("Error: result mismatch when parsing %s as %s!\n",
5674418919fSjohnjiang 						ipaddr_garbage_network6_strs[i], buf);
5684418919fSjohnjiang 				return -1;
5694418919fSjohnjiang 			}
5704418919fSjohnjiang 		}
5714418919fSjohnjiang 	}
5724418919fSjohnjiang 
5734418919fSjohnjiang 	return 0;
5744418919fSjohnjiang }
5754418919fSjohnjiang 
5764418919fSjohnjiang int
test_parse_ipaddr_invalid_data(void)5774418919fSjohnjiang test_parse_ipaddr_invalid_data(void)
5784418919fSjohnjiang {
5794418919fSjohnjiang 	cmdline_parse_token_ipaddr_t token;
5804418919fSjohnjiang 	char buf[CMDLINE_TEST_BUFSIZE];
5814418919fSjohnjiang 	cmdline_ipaddr_t result;
5824418919fSjohnjiang 	unsigned i;
5834418919fSjohnjiang 	uint8_t flags;
5844418919fSjohnjiang 	int ret;
5854418919fSjohnjiang 
5864418919fSjohnjiang 	memset(&result, 0, sizeof(result));
5874418919fSjohnjiang 
5884418919fSjohnjiang 	/* test invalid strings */
589*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(ipaddr_invalid_strs); i++) {
5904418919fSjohnjiang 
5914418919fSjohnjiang 		/* test each valid string against different flags */
5924418919fSjohnjiang 		for (flags = 1; flags < 0x8; flags++) {
5934418919fSjohnjiang 
5944418919fSjohnjiang 			/* skip bad flag */
5954418919fSjohnjiang 			if (flags == CMDLINE_IPADDR_NETWORK)
5964418919fSjohnjiang 				continue;
5974418919fSjohnjiang 
5984418919fSjohnjiang 			/* clear out everything */
5994418919fSjohnjiang 			memset(buf, 0, sizeof(buf));
6004418919fSjohnjiang 			memset(&token, 0, sizeof(token));
6014418919fSjohnjiang 
6024418919fSjohnjiang 			token.ipaddr_data.flags = flags;
6034418919fSjohnjiang 
6044418919fSjohnjiang 			cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
6054418919fSjohnjiang 					buf, sizeof(buf));
6064418919fSjohnjiang 
6074418919fSjohnjiang 			ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
6084418919fSjohnjiang 				ipaddr_invalid_strs[i], (void*)&result,
6094418919fSjohnjiang 				sizeof(result));
6104418919fSjohnjiang 
6114418919fSjohnjiang 			if (ret != -1) {
6124418919fSjohnjiang 				printf("Error: parsing %s as %s succeeded!\n",
6134418919fSjohnjiang 						ipaddr_invalid_strs[i], buf);
6144418919fSjohnjiang 				printf("Parsed result: ");
6154418919fSjohnjiang 				dump_addr(result);
6164418919fSjohnjiang 				return -1;
6174418919fSjohnjiang 			}
6184418919fSjohnjiang 		}
6194418919fSjohnjiang 	}
6204418919fSjohnjiang 
6214418919fSjohnjiang 	return 0;
6224418919fSjohnjiang }
6234418919fSjohnjiang 
6244418919fSjohnjiang int
test_parse_ipaddr_invalid_param(void)6254418919fSjohnjiang test_parse_ipaddr_invalid_param(void)
6264418919fSjohnjiang {
6274418919fSjohnjiang 	cmdline_parse_token_ipaddr_t token;
6284418919fSjohnjiang 	char buf[CMDLINE_TEST_BUFSIZE];
6294418919fSjohnjiang 	cmdline_ipaddr_t result;
6304418919fSjohnjiang 
6314418919fSjohnjiang 	snprintf(buf, sizeof(buf), "1.2.3.4");
6324418919fSjohnjiang 	token.ipaddr_data.flags = CMDLINE_IPADDR_V4;
6334418919fSjohnjiang 
6344418919fSjohnjiang 	/* null token */
6354418919fSjohnjiang 	if (cmdline_parse_ipaddr(NULL, buf, (void*)&result,
6364418919fSjohnjiang 			sizeof(result)) != -1) {
6374418919fSjohnjiang 		printf("Error: parser accepted invalid parameters!\n");
6384418919fSjohnjiang 		return -1;
6394418919fSjohnjiang 	}
6404418919fSjohnjiang 	/* null buffer */
6414418919fSjohnjiang 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
6424418919fSjohnjiang 			NULL, (void*)&result, sizeof(result)) != -1) {
6434418919fSjohnjiang 		printf("Error: parser accepted invalid parameters!\n");
6444418919fSjohnjiang 		return -1;
6454418919fSjohnjiang 	}
6464418919fSjohnjiang 	/* empty buffer */
6474418919fSjohnjiang 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
6484418919fSjohnjiang 			"", (void*)&result, sizeof(result)) != -1) {
6494418919fSjohnjiang 		printf("Error: parser accepted invalid parameters!\n");
6504418919fSjohnjiang 		return -1;
6514418919fSjohnjiang 	}
6524418919fSjohnjiang 	/* null result */
6534418919fSjohnjiang 	if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
6544418919fSjohnjiang 			buf, NULL, 0) == -1) {
6554418919fSjohnjiang 		printf("Error: parser rejected null result!\n");
6564418919fSjohnjiang 		return -1;
6574418919fSjohnjiang 	}
6584418919fSjohnjiang 
6594418919fSjohnjiang 	/* null token */
6604418919fSjohnjiang 	if (cmdline_get_help_ipaddr(NULL, buf, 0) != -1) {
6614418919fSjohnjiang 		printf("Error: help accepted invalid parameters!\n");
6624418919fSjohnjiang 		return -1;
6634418919fSjohnjiang 	}
6644418919fSjohnjiang 	/* null buffer */
6654418919fSjohnjiang 	if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
6664418919fSjohnjiang 			NULL, 0) != -1) {
6674418919fSjohnjiang 		printf("Error: help accepted invalid parameters!\n");
6684418919fSjohnjiang 		return -1;
6694418919fSjohnjiang 	}
6704418919fSjohnjiang 	return 0;
6714418919fSjohnjiang }
672