]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/lib/librte_cmdline/cmdline_parse_ipaddr.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / dpdk / 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 #ifndef __linux__
17 #ifndef __FreeBSD__
18 #include <net/socket.h>
19 #else
20 #include <sys/socket.h>
21 #endif
22 #endif
23
24 #include <rte_string_fns.h>
25
26 #include "cmdline_parse.h"
27 #include "cmdline_parse_ipaddr.h"
28
29 struct cmdline_token_ops cmdline_token_ipaddr_ops = {
30 .parse = cmdline_parse_ipaddr,
31 .complete_get_nb = NULL,
32 .complete_get_elt = NULL,
33 .get_help = cmdline_get_help_ipaddr,
34 };
35
36 #define PREFIXMAX 128
37 #define V4PREFIXMAX 32
38
39 int
40 cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
41 unsigned ressize)
42 {
43 struct cmdline_token_ipaddr *tk2;
44 unsigned int token_len = 0;
45 char ip_str[INET6_ADDRSTRLEN+4+1]; /* '+4' is for prefixlen (if any) */
46 cmdline_ipaddr_t ipaddr;
47 char *prefix, *prefix_end;
48 long prefixlen = 0;
49
50 if (res && ressize < sizeof(cmdline_ipaddr_t))
51 return -1;
52
53 if (!buf || !tk || ! *buf)
54 return -1;
55
56 tk2 = (struct cmdline_token_ipaddr *)tk;
57
58 while (!cmdline_isendoftoken(buf[token_len]))
59 token_len++;
60
61 /* if token is too big... */
62 if (token_len >= INET6_ADDRSTRLEN+4)
63 return -1;
64
65 strlcpy(ip_str, buf, token_len + 1);
66
67 /* convert the network prefix */
68 if (tk2->ipaddr_data.flags & CMDLINE_IPADDR_NETWORK) {
69 prefix = strrchr(ip_str, '/');
70 if (prefix == NULL)
71 return -1;
72 *prefix = '\0';
73 prefix ++;
74 errno = 0;
75 prefixlen = strtol(prefix, &prefix_end, 10);
76 if (errno || (*prefix_end != '\0')
77 || prefixlen < 0 || prefixlen > PREFIXMAX)
78 return -1;
79 ipaddr.prefixlen = prefixlen;
80 }
81 else {
82 ipaddr.prefixlen = 0;
83 }
84
85 /* convert the IP addr */
86 if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V4) &&
87 inet_pton(AF_INET, ip_str, &ipaddr.addr.ipv4) == 1 &&
88 prefixlen <= V4PREFIXMAX) {
89 ipaddr.family = AF_INET;
90 if (res)
91 memcpy(res, &ipaddr, sizeof(ipaddr));
92 return token_len;
93 }
94 if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V6) &&
95 inet_pton(AF_INET6, ip_str, &ipaddr.addr.ipv6) == 1) {
96 ipaddr.family = AF_INET6;
97 if (res)
98 memcpy(res, &ipaddr, sizeof(ipaddr));
99 return token_len;
100 }
101 return -1;
102
103 }
104
105 int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
106 unsigned int size)
107 {
108 struct cmdline_token_ipaddr *tk2;
109
110 if (!tk || !dstbuf)
111 return -1;
112
113 tk2 = (struct cmdline_token_ipaddr *)tk;
114
115 switch (tk2->ipaddr_data.flags) {
116 case CMDLINE_IPADDR_V4:
117 snprintf(dstbuf, size, "IPv4");
118 break;
119 case CMDLINE_IPADDR_V6:
120 snprintf(dstbuf, size, "IPv6");
121 break;
122 case CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
123 snprintf(dstbuf, size, "IPv4/IPv6");
124 break;
125 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4:
126 snprintf(dstbuf, size, "IPv4 network");
127 break;
128 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V6:
129 snprintf(dstbuf, size, "IPv6 network");
130 break;
131 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
132 snprintf(dstbuf, size, "IPv4/IPv6 network");
133 break;
134 default:
135 snprintf(dstbuf, size, "IPaddr (bad flags)");
136 break;
137 }
138 return 0;
139 }