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