088cd5afc3adabea93a9ba0a080b8d67821313d2
[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 #include <sys/socket.h>
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},
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
265 #define IPADDR_VALID_STRS_SIZE \
266         (sizeof(ipaddr_valid_strs) / sizeof(ipaddr_valid_strs[0]))
267 #define IPADDR_GARBAGE_ADDR4_STRS_SIZE \
268         (sizeof(ipaddr_garbage_addr4_strs) / sizeof(ipaddr_garbage_addr4_strs[0]))
269 #define IPADDR_GARBAGE_ADDR6_STRS_SIZE \
270         (sizeof(ipaddr_garbage_addr6_strs) / sizeof(ipaddr_garbage_addr6_strs[0]))
271 #define IPADDR_GARBAGE_NETWORK4_STRS_SIZE \
272         (sizeof(ipaddr_garbage_network4_strs) / sizeof(ipaddr_garbage_network4_strs[0]))
273 #define IPADDR_GARBAGE_NETWORK6_STRS_SIZE \
274         (sizeof(ipaddr_garbage_network6_strs) / sizeof(ipaddr_garbage_network6_strs[0]))
275 #define IPADDR_INVALID_STRS_SIZE \
276         (sizeof(ipaddr_invalid_strs) / sizeof(ipaddr_invalid_strs[0]))
277
278 static void
279 dump_addr(cmdline_ipaddr_t addr)
280 {
281         switch (addr.family) {
282         case AF_INET:
283         {
284                 printf(NIPQUAD_FMT " prefixlen=%u\n",
285                                 NIPQUAD(addr.addr.ipv4.s_addr), addr.prefixlen);
286                 break;
287         }
288         case AF_INET6:
289         {
290                 printf(NIP6_FMT " prefixlen=%u\n",
291                                 NIP6(addr.addr.ipv6), addr.prefixlen);
292                 break;
293         }
294         default:
295                 printf("Can't dump: unknown address family.\n");
296                 return;
297         }
298 }
299
300
301 static int
302 is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2)
303 {
304         if (addr1.family != addr2.family)
305                 return 1;
306
307         if (addr1.prefixlen != addr2.prefixlen)
308                 return 1;
309
310         switch (addr1.family) {
311         /* IPv4 */
312         case AF_INET:
313                 if (memcmp(&addr1.addr.ipv4, &addr2.addr.ipv4,
314                                 sizeof(struct in_addr)) != 0)
315                         return 1;
316                 break;
317         /* IPv6 */
318         case AF_INET6:
319         {
320                 if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6,
321                                 sizeof(struct in6_addr)) != 0)
322                         return 1;
323                 break;
324         }
325         /* thing that should not be */
326         default:
327                 return -1;
328         }
329         return 0;
330 }
331
332 static int
333 can_parse_addr(unsigned addr_flags, unsigned test_flags)
334 {
335         if ((test_flags & addr_flags) == addr_flags) {
336                 /* if we are not trying to parse network addresses */
337                 if (test_flags < CMDLINE_IPADDR_NETWORK)
338                         return 1;
339                 /* if this is a network address */
340                 else if (addr_flags & CMDLINE_IPADDR_NETWORK)
341                         return 1;
342         }
343         return 0;
344 }
345
346 int
347 test_parse_ipaddr_valid(void)
348 {
349         cmdline_parse_token_ipaddr_t token;
350         char buf[CMDLINE_TEST_BUFSIZE];
351         cmdline_ipaddr_t result;
352         unsigned i;
353         uint8_t flags;
354         int ret;
355
356         /* cover all cases in help */
357         for (flags = 0x1; flags < 0x8; flags++) {
358                 token.ipaddr_data.flags = flags;
359
360                 memset(buf, 0, sizeof(buf));
361
362                 if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
363                                 buf, sizeof(buf)) == -1) {
364                         printf("Error: help rejected valid parameters!\n");
365                         return -1;
366                 }
367         }
368
369         /* test valid strings */
370         for (i = 0; i < IPADDR_VALID_STRS_SIZE; i++) {
371
372                 /* test each valid string against different flags */
373                 for (flags = 1; flags < 0x8; flags++) {
374
375                         /* skip bad flag */
376                         if (flags == CMDLINE_IPADDR_NETWORK)
377                                 continue;
378
379                         /* clear out everything */
380                         memset(buf, 0, sizeof(buf));
381                         memset(&result, 0, sizeof(result));
382                         memset(&token, 0, sizeof(token));
383
384                         token.ipaddr_data.flags = flags;
385
386                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
387                                                         buf, sizeof(buf));
388
389                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
390                                 ipaddr_valid_strs[i].str, (void*)&result,
391                                 sizeof(result));
392
393                         /* if should have passed, or should have failed */
394                         if ((ret < 0) ==
395                                         (can_parse_addr(ipaddr_valid_strs[i].flags, flags))) {
396                                 printf("Error: unexpected behavior when parsing %s as %s!\n",
397                                                 ipaddr_valid_strs[i].str, buf);
398                                 printf("Parsed result: ");
399                                 dump_addr(result);
400                                 printf("Expected result: ");
401                                 dump_addr(ipaddr_valid_strs[i].addr);
402                                 return -1;
403                         }
404                         if (ret != -1 &&
405                                         is_addr_different(result, ipaddr_valid_strs[i].addr)) {
406                                 printf("Error: result mismatch when parsing %s as %s!\n",
407                                                 ipaddr_valid_strs[i].str, buf);
408                                 printf("Parsed result: ");
409                                 dump_addr(result);
410                                 printf("Expected result: ");
411                                 dump_addr(ipaddr_valid_strs[i].addr);
412                                 return -1;
413                         }
414                 }
415         }
416
417         /* test garbage ipv4 address strings */
418         for (i = 0; i < IPADDR_GARBAGE_ADDR4_STRS_SIZE; i++) {
419
420                 struct in_addr tmp = IPv4_GARBAGE_ADDR;
421
422                 /* test each valid string against different flags */
423                 for (flags = 1; flags < 0x8; flags++) {
424
425                         /* skip bad flag */
426                         if (flags == CMDLINE_IPADDR_NETWORK)
427                                 continue;
428
429                         /* clear out everything */
430                         memset(buf, 0, sizeof(buf));
431                         memset(&result, 0, sizeof(result));
432                         memset(&token, 0, sizeof(token));
433
434                         token.ipaddr_data.flags = flags;
435
436                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
437                                                         buf, sizeof(buf));
438
439                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
440                                 ipaddr_garbage_addr4_strs[i], (void*)&result,
441                                 sizeof(result));
442
443                         /* if should have passed, or should have failed */
444                         if ((ret < 0) ==
445                                         (can_parse_addr(CMDLINE_IPADDR_V4, flags))) {
446                                 printf("Error: unexpected behavior when parsing %s as %s!\n",
447                                                 ipaddr_garbage_addr4_strs[i], buf);
448                                 return -1;
449                         }
450                         if (ret != -1 &&
451                                         memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
452                                 printf("Error: result mismatch when parsing %s as %s!\n",
453                                                 ipaddr_garbage_addr4_strs[i], buf);
454                                 return -1;
455                         }
456                 }
457         }
458
459         /* test garbage ipv6 address strings */
460         for (i = 0; i < IPADDR_GARBAGE_ADDR6_STRS_SIZE; i++) {
461
462                 cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
463
464                 /* test each valid string against different flags */
465                 for (flags = 1; flags < 0x8; flags++) {
466
467                         /* skip bad flag */
468                         if (flags == CMDLINE_IPADDR_NETWORK)
469                                 continue;
470
471                         /* clear out everything */
472                         memset(buf, 0, sizeof(buf));
473                         memset(&result, 0, sizeof(result));
474                         memset(&token, 0, sizeof(token));
475
476                         token.ipaddr_data.flags = flags;
477
478                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
479                                                         buf, sizeof(buf));
480
481                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
482                                 ipaddr_garbage_addr6_strs[i], (void*)&result,
483                                 sizeof(result));
484
485                         /* if should have passed, or should have failed */
486                         if ((ret < 0) ==
487                                         (can_parse_addr(CMDLINE_IPADDR_V6, flags))) {
488                                 printf("Error: unexpected behavior when parsing %s as %s!\n",
489                                                 ipaddr_garbage_addr6_strs[i], buf);
490                                 return -1;
491                         }
492                         if (ret != -1 &&
493                                         memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
494                                 printf("Error: result mismatch when parsing %s as %s!\n",
495                                                 ipaddr_garbage_addr6_strs[i], buf);
496                                 return -1;
497                         }
498                 }
499         }
500
501
502         /* test garbage ipv4 network strings */
503         for (i = 0; i < IPADDR_GARBAGE_NETWORK4_STRS_SIZE; i++) {
504
505                 struct in_addr tmp = IPv4_GARBAGE_ADDR;
506
507                 /* test each valid string against different flags */
508                 for (flags = 1; flags < 0x8; flags++) {
509
510                         /* skip bad flag */
511                         if (flags == CMDLINE_IPADDR_NETWORK)
512                                 continue;
513
514                         /* clear out everything */
515                         memset(buf, 0, sizeof(buf));
516                         memset(&result, 0, sizeof(result));
517                         memset(&token, 0, sizeof(token));
518
519                         token.ipaddr_data.flags = flags;
520
521                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
522                                                         buf, sizeof(buf));
523
524                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
525                                 ipaddr_garbage_network4_strs[i], (void*)&result,
526                                 sizeof(result));
527
528                         /* if should have passed, or should have failed */
529                         if ((ret < 0) ==
530                                         (can_parse_addr(CMDLINE_IPADDR_V4 | CMDLINE_IPADDR_NETWORK, flags))) {
531                                 printf("Error: unexpected behavior when parsing %s as %s!\n",
532                                                 ipaddr_garbage_network4_strs[i], buf);
533                                 return -1;
534                         }
535                         if (ret != -1 &&
536                                         memcmp(&result.addr.ipv4, &tmp, sizeof(tmp))) {
537                                 printf("Error: result mismatch when parsing %s as %s!\n",
538                                                 ipaddr_garbage_network4_strs[i], buf);
539                                 return -1;
540                         }
541                 }
542         }
543
544         /* test garbage ipv6 address strings */
545         for (i = 0; i < IPADDR_GARBAGE_NETWORK6_STRS_SIZE; i++) {
546
547                 cmdline_ipaddr_t tmp = {.addr = IPv6_GARBAGE_ADDR};
548
549                 /* test each valid string against different flags */
550                 for (flags = 1; flags < 0x8; flags++) {
551
552                         /* skip bad flag */
553                         if (flags == CMDLINE_IPADDR_NETWORK)
554                                 continue;
555
556                         /* clear out everything */
557                         memset(buf, 0, sizeof(buf));
558                         memset(&result, 0, sizeof(result));
559                         memset(&token, 0, sizeof(token));
560
561                         token.ipaddr_data.flags = flags;
562
563                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
564                                                         buf, sizeof(buf));
565
566                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
567                                 ipaddr_garbage_network6_strs[i], (void*)&result,
568                                 sizeof(result));
569
570                         /* if should have passed, or should have failed */
571                         if ((ret < 0) ==
572                                         (can_parse_addr(CMDLINE_IPADDR_V6 | CMDLINE_IPADDR_NETWORK, flags))) {
573                                 printf("Error: unexpected behavior when parsing %s as %s!\n",
574                                                 ipaddr_garbage_network6_strs[i], buf);
575                                 return -1;
576                         }
577                         if (ret != -1 &&
578                                         memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
579                                 printf("Error: result mismatch when parsing %s as %s!\n",
580                                                 ipaddr_garbage_network6_strs[i], buf);
581                                 return -1;
582                         }
583                 }
584         }
585
586         return 0;
587 }
588
589 int
590 test_parse_ipaddr_invalid_data(void)
591 {
592         cmdline_parse_token_ipaddr_t token;
593         char buf[CMDLINE_TEST_BUFSIZE];
594         cmdline_ipaddr_t result;
595         unsigned i;
596         uint8_t flags;
597         int ret;
598
599         memset(&result, 0, sizeof(result));
600
601         /* test invalid strings */
602         for (i = 0; i < IPADDR_INVALID_STRS_SIZE; i++) {
603
604                 /* test each valid string against different flags */
605                 for (flags = 1; flags < 0x8; flags++) {
606
607                         /* skip bad flag */
608                         if (flags == CMDLINE_IPADDR_NETWORK)
609                                 continue;
610
611                         /* clear out everything */
612                         memset(buf, 0, sizeof(buf));
613                         memset(&token, 0, sizeof(token));
614
615                         token.ipaddr_data.flags = flags;
616
617                         cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
618                                         buf, sizeof(buf));
619
620                         ret = cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
621                                 ipaddr_invalid_strs[i], (void*)&result,
622                                 sizeof(result));
623
624                         if (ret != -1) {
625                                 printf("Error: parsing %s as %s succeeded!\n",
626                                                 ipaddr_invalid_strs[i], buf);
627                                 printf("Parsed result: ");
628                                 dump_addr(result);
629                                 return -1;
630                         }
631                 }
632         }
633
634         return 0;
635 }
636
637 int
638 test_parse_ipaddr_invalid_param(void)
639 {
640         cmdline_parse_token_ipaddr_t token;
641         char buf[CMDLINE_TEST_BUFSIZE];
642         cmdline_ipaddr_t result;
643
644         snprintf(buf, sizeof(buf), "1.2.3.4");
645         token.ipaddr_data.flags = CMDLINE_IPADDR_V4;
646
647         /* null token */
648         if (cmdline_parse_ipaddr(NULL, buf, (void*)&result,
649                         sizeof(result)) != -1) {
650                 printf("Error: parser accepted invalid parameters!\n");
651                 return -1;
652         }
653         /* null buffer */
654         if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
655                         NULL, (void*)&result, sizeof(result)) != -1) {
656                 printf("Error: parser accepted invalid parameters!\n");
657                 return -1;
658         }
659         /* empty buffer */
660         if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
661                         "", (void*)&result, sizeof(result)) != -1) {
662                 printf("Error: parser accepted invalid parameters!\n");
663                 return -1;
664         }
665         /* null result */
666         if (cmdline_parse_ipaddr((cmdline_parse_token_hdr_t*)&token,
667                         buf, NULL, 0) == -1) {
668                 printf("Error: parser rejected null result!\n");
669                 return -1;
670         }
671
672         /* null token */
673         if (cmdline_get_help_ipaddr(NULL, buf, 0) != -1) {
674                 printf("Error: help accepted invalid parameters!\n");
675                 return -1;
676         }
677         /* null buffer */
678         if (cmdline_get_help_ipaddr((cmdline_parse_token_hdr_t*)&token,
679                         NULL, 0) != -1) {
680                 printf("Error: help accepted invalid parameters!\n");
681                 return -1;
682         }
683         return 0;
684 }