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