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