net/bnxt: fix link during port toggle
[dpdk.git] / lib / librte_cmdline / cmdline_parse_ipaddr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4  * All rights reserved.
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <inttypes.h>
11 #include <ctype.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <arpa/inet.h>
15 #include <netinet/in.h>
16 #include <sys/socket.h>
17
18 #include <rte_string_fns.h>
19
20 #include "cmdline_parse.h"
21 #include "cmdline_parse_ipaddr.h"
22
23 struct cmdline_token_ops cmdline_token_ipaddr_ops = {
24         .parse = cmdline_parse_ipaddr,
25         .complete_get_nb = NULL,
26         .complete_get_elt = NULL,
27         .get_help = cmdline_get_help_ipaddr,
28 };
29
30 #define PREFIXMAX 128
31 #define V4PREFIXMAX 32
32
33 int
34 cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
35         unsigned ressize)
36 {
37         struct cmdline_token_ipaddr *tk2;
38         unsigned int token_len = 0;
39         char ip_str[INET6_ADDRSTRLEN+4+1]; /* '+4' is for prefixlen (if any) */
40         cmdline_ipaddr_t ipaddr;
41         char *prefix, *prefix_end;
42         long prefixlen = 0;
43
44         if (res && ressize < sizeof(cmdline_ipaddr_t))
45                 return -1;
46
47         if (!buf || !tk || ! *buf)
48                 return -1;
49
50         tk2 = (struct cmdline_token_ipaddr *)tk;
51
52         while (!cmdline_isendoftoken(buf[token_len]))
53                 token_len++;
54
55         /* if token is too big... */
56         if (token_len >= INET6_ADDRSTRLEN+4)
57                 return -1;
58
59         strlcpy(ip_str, buf, token_len + 1);
60
61         /* convert the network prefix */
62         if (tk2->ipaddr_data.flags & CMDLINE_IPADDR_NETWORK) {
63                 prefix = strrchr(ip_str, '/');
64                 if (prefix == NULL)
65                         return -1;
66                 *prefix = '\0';
67                 prefix ++;
68                 errno = 0;
69                 prefixlen = strtol(prefix, &prefix_end, 10);
70                 if (errno || (*prefix_end != '\0')
71                         || prefixlen < 0 || prefixlen > PREFIXMAX)
72                         return -1;
73                 ipaddr.prefixlen = prefixlen;
74         }
75         else {
76                 ipaddr.prefixlen = 0;
77         }
78
79         /* convert the IP addr */
80         if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V4) &&
81             inet_pton(AF_INET, ip_str, &ipaddr.addr.ipv4) == 1 &&
82                 prefixlen <= V4PREFIXMAX) {
83                 ipaddr.family = AF_INET;
84                 if (res)
85                         memcpy(res, &ipaddr, sizeof(ipaddr));
86                 return token_len;
87         }
88         if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V6) &&
89             inet_pton(AF_INET6, ip_str, &ipaddr.addr.ipv6) == 1) {
90                 ipaddr.family = AF_INET6;
91                 if (res)
92                         memcpy(res, &ipaddr, sizeof(ipaddr));
93                 return token_len;
94         }
95         return -1;
96
97 }
98
99 int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
100                             unsigned int size)
101 {
102         struct cmdline_token_ipaddr *tk2;
103
104         if (!tk || !dstbuf)
105                 return -1;
106
107         tk2 = (struct cmdline_token_ipaddr *)tk;
108
109         switch (tk2->ipaddr_data.flags) {
110         case CMDLINE_IPADDR_V4:
111                 snprintf(dstbuf, size, "IPv4");
112                 break;
113         case CMDLINE_IPADDR_V6:
114                 snprintf(dstbuf, size, "IPv6");
115                 break;
116         case CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
117                 snprintf(dstbuf, size, "IPv4/IPv6");
118                 break;
119         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4:
120                 snprintf(dstbuf, size, "IPv4 network");
121                 break;
122         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V6:
123                 snprintf(dstbuf, size, "IPv6 network");
124                 break;
125         case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
126                 snprintf(dstbuf, size, "IPv4/IPv6 network");
127                 break;
128         default:
129                 snprintf(dstbuf, size, "IPaddr (bad flags)");
130                 break;
131         }
132         return 0;
133 }