xref: /dpdk/app/test/test_cmdline_ipaddr.c (revision 52e04a6323319ff1a7b4e1d7ed1df2b45d11a0a4)
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