1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation.
3 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
14 #include <arpa/inet.h>
15 #include <netinet/in.h>
18 #include <net/socket.h>
20 #include <sys/socket.h>
24 #include <rte_string_fns.h>
26 #include "cmdline_parse.h"
27 #include "cmdline_parse_ipaddr.h"
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
,
37 #define V4PREFIXMAX 32
40 cmdline_parse_ipaddr(cmdline_parse_token_hdr_t
*tk
, const char *buf
, void *res
,
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
;
50 if (res
&& ressize
< sizeof(cmdline_ipaddr_t
))
53 if (!buf
|| !tk
|| ! *buf
)
56 tk2
= (struct cmdline_token_ipaddr
*)tk
;
58 while (!cmdline_isendoftoken(buf
[token_len
]))
61 /* if token is too big... */
62 if (token_len
>= INET6_ADDRSTRLEN
+4)
65 strlcpy(ip_str
, buf
, token_len
+ 1);
67 /* convert the network prefix */
68 if (tk2
->ipaddr_data
.flags
& CMDLINE_IPADDR_NETWORK
) {
69 prefix
= strrchr(ip_str
, '/');
75 prefixlen
= strtol(prefix
, &prefix_end
, 10);
76 if (errno
|| (*prefix_end
!= '\0')
77 || prefixlen
< 0 || prefixlen
> PREFIXMAX
)
79 ipaddr
.prefixlen
= prefixlen
;
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
;
91 memcpy(res
, &ipaddr
, sizeof(ipaddr
));
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
;
98 memcpy(res
, &ipaddr
, sizeof(ipaddr
));
105 int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t
*tk
, char *dstbuf
,
108 struct cmdline_token_ipaddr
*tk2
;
113 tk2
= (struct cmdline_token_ipaddr
*)tk
;
115 switch (tk2
->ipaddr_data
.flags
) {
116 case CMDLINE_IPADDR_V4
:
117 snprintf(dstbuf
, size
, "IPv4");
119 case CMDLINE_IPADDR_V6
:
120 snprintf(dstbuf
, size
, "IPv6");
122 case CMDLINE_IPADDR_V4
|CMDLINE_IPADDR_V6
:
123 snprintf(dstbuf
, size
, "IPv4/IPv6");
125 case CMDLINE_IPADDR_NETWORK
|CMDLINE_IPADDR_V4
:
126 snprintf(dstbuf
, size
, "IPv4 network");
128 case CMDLINE_IPADDR_NETWORK
|CMDLINE_IPADDR_V6
:
129 snprintf(dstbuf
, size
, "IPv6 network");
131 case CMDLINE_IPADDR_NETWORK
|CMDLINE_IPADDR_V4
|CMDLINE_IPADDR_V6
:
132 snprintf(dstbuf
, size
, "IPv4/IPv6 network");
135 snprintf(dstbuf
, size
, "IPaddr (bad flags)");