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