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>
16 #include <sys/socket.h>
18 #include <rte_string_fns.h>
20 #include "cmdline_parse.h"
21 #include "cmdline_parse_ipaddr.h"
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,
31 #define V4PREFIXMAX 32
34 cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
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;
44 if (res && ressize < sizeof(cmdline_ipaddr_t))
47 if (!buf || !tk || ! *buf)
50 tk2 = (struct cmdline_token_ipaddr *)tk;
52 while (!cmdline_isendoftoken(buf[token_len]))
55 /* if token is too big... */
56 if (token_len >= INET6_ADDRSTRLEN+4)
59 strlcpy(ip_str, buf, token_len + 1);
61 /* convert the network prefix */
62 if (tk2->ipaddr_data.flags & CMDLINE_IPADDR_NETWORK) {
63 prefix = strrchr(ip_str, '/');
69 prefixlen = strtol(prefix, &prefix_end, 10);
70 if (errno || (*prefix_end != '\0')
71 || prefixlen < 0 || prefixlen > PREFIXMAX)
73 ipaddr.prefixlen = prefixlen;
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;
85 memcpy(res, &ipaddr, sizeof(ipaddr));
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;
92 memcpy(res, &ipaddr, sizeof(ipaddr));
99 int cmdline_get_help_ipaddr(cmdline_parse_token_hdr_t *tk, char *dstbuf,
102 struct cmdline_token_ipaddr *tk2;
107 tk2 = (struct cmdline_token_ipaddr *)tk;
109 switch (tk2->ipaddr_data.flags) {
110 case CMDLINE_IPADDR_V4:
111 snprintf(dstbuf, size, "IPv4");
113 case CMDLINE_IPADDR_V6:
114 snprintf(dstbuf, size, "IPv6");
116 case CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
117 snprintf(dstbuf, size, "IPv4/IPv6");
119 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4:
120 snprintf(dstbuf, size, "IPv4 network");
122 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V6:
123 snprintf(dstbuf, size, "IPv6 network");
125 case CMDLINE_IPADDR_NETWORK|CMDLINE_IPADDR_V4|CMDLINE_IPADDR_V6:
126 snprintf(dstbuf, size, "IPv4/IPv6 network");
129 snprintf(dstbuf, size, "IPaddr (bad flags)");