1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*99a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation.
3*99a2dd95SBruce Richardson * Copyright (c) 2010, Keith Wiles <keith.wiles@windriver.com>
4*99a2dd95SBruce Richardson * All rights reserved.
5*99a2dd95SBruce Richardson */
6*99a2dd95SBruce Richardson
7*99a2dd95SBruce Richardson #include <stdio.h>
8*99a2dd95SBruce Richardson #include <stdlib.h>
9*99a2dd95SBruce Richardson #include <string.h>
10*99a2dd95SBruce Richardson #include <errno.h>
11*99a2dd95SBruce Richardson
12*99a2dd95SBruce Richardson #include <rte_string_fns.h>
13*99a2dd95SBruce Richardson #include "cmdline_parse.h"
14*99a2dd95SBruce Richardson #include "cmdline_parse_portlist.h"
15*99a2dd95SBruce Richardson
16*99a2dd95SBruce Richardson struct cmdline_token_ops cmdline_token_portlist_ops = {
17*99a2dd95SBruce Richardson .parse = cmdline_parse_portlist,
18*99a2dd95SBruce Richardson .complete_get_nb = NULL,
19*99a2dd95SBruce Richardson .complete_get_elt = NULL,
20*99a2dd95SBruce Richardson .get_help = cmdline_get_help_portlist,
21*99a2dd95SBruce Richardson };
22*99a2dd95SBruce Richardson
23*99a2dd95SBruce Richardson static void
parse_set_list(cmdline_portlist_t * pl,size_t low,size_t high)24*99a2dd95SBruce Richardson parse_set_list(cmdline_portlist_t *pl, size_t low, size_t high)
25*99a2dd95SBruce Richardson {
26*99a2dd95SBruce Richardson do {
27*99a2dd95SBruce Richardson pl->map |= (1 << low++);
28*99a2dd95SBruce Richardson } while (low <= high);
29*99a2dd95SBruce Richardson }
30*99a2dd95SBruce Richardson
31*99a2dd95SBruce Richardson static int
parse_ports(cmdline_portlist_t * pl,const char * str)32*99a2dd95SBruce Richardson parse_ports(cmdline_portlist_t *pl, const char *str)
33*99a2dd95SBruce Richardson {
34*99a2dd95SBruce Richardson size_t ps, pe;
35*99a2dd95SBruce Richardson const char *first, *last;
36*99a2dd95SBruce Richardson char *end;
37*99a2dd95SBruce Richardson
38*99a2dd95SBruce Richardson for (first = str, last = first;
39*99a2dd95SBruce Richardson first != NULL && last != NULL;
40*99a2dd95SBruce Richardson first = last + 1) {
41*99a2dd95SBruce Richardson
42*99a2dd95SBruce Richardson last = strchr(first, ',');
43*99a2dd95SBruce Richardson
44*99a2dd95SBruce Richardson errno = 0;
45*99a2dd95SBruce Richardson ps = strtoul(first, &end, 10);
46*99a2dd95SBruce Richardson if (errno != 0 || end == first ||
47*99a2dd95SBruce Richardson (end[0] != '-' && end[0] != 0 && end != last))
48*99a2dd95SBruce Richardson return -1;
49*99a2dd95SBruce Richardson
50*99a2dd95SBruce Richardson /* Support for N-M portlist format */
51*99a2dd95SBruce Richardson if (end[0] == '-') {
52*99a2dd95SBruce Richardson errno = 0;
53*99a2dd95SBruce Richardson first = end + 1;
54*99a2dd95SBruce Richardson pe = strtoul(first, &end, 10);
55*99a2dd95SBruce Richardson if (errno != 0 || end == first ||
56*99a2dd95SBruce Richardson (end[0] != 0 && end != last))
57*99a2dd95SBruce Richardson return -1;
58*99a2dd95SBruce Richardson } else {
59*99a2dd95SBruce Richardson pe = ps;
60*99a2dd95SBruce Richardson }
61*99a2dd95SBruce Richardson
62*99a2dd95SBruce Richardson if (ps > pe || pe >= sizeof (pl->map) * 8)
63*99a2dd95SBruce Richardson return -1;
64*99a2dd95SBruce Richardson
65*99a2dd95SBruce Richardson parse_set_list(pl, ps, pe);
66*99a2dd95SBruce Richardson }
67*99a2dd95SBruce Richardson
68*99a2dd95SBruce Richardson return 0;
69*99a2dd95SBruce Richardson }
70*99a2dd95SBruce Richardson
71*99a2dd95SBruce Richardson int
cmdline_parse_portlist(__rte_unused cmdline_parse_token_hdr_t * tk,const char * buf,void * res,unsigned ressize)72*99a2dd95SBruce Richardson cmdline_parse_portlist(__rte_unused cmdline_parse_token_hdr_t *tk,
73*99a2dd95SBruce Richardson const char *buf, void *res, unsigned ressize)
74*99a2dd95SBruce Richardson {
75*99a2dd95SBruce Richardson unsigned int token_len = 0;
76*99a2dd95SBruce Richardson char portlist_str[PORTLIST_TOKEN_SIZE+1];
77*99a2dd95SBruce Richardson cmdline_portlist_t *pl;
78*99a2dd95SBruce Richardson
79*99a2dd95SBruce Richardson if (!buf || ! *buf)
80*99a2dd95SBruce Richardson return -1;
81*99a2dd95SBruce Richardson
82*99a2dd95SBruce Richardson if (res && ressize < sizeof(cmdline_portlist_t))
83*99a2dd95SBruce Richardson return -1;
84*99a2dd95SBruce Richardson
85*99a2dd95SBruce Richardson pl = res;
86*99a2dd95SBruce Richardson
87*99a2dd95SBruce Richardson while (!cmdline_isendoftoken(buf[token_len]) &&
88*99a2dd95SBruce Richardson (token_len < PORTLIST_TOKEN_SIZE))
89*99a2dd95SBruce Richardson token_len++;
90*99a2dd95SBruce Richardson
91*99a2dd95SBruce Richardson if (token_len >= PORTLIST_TOKEN_SIZE)
92*99a2dd95SBruce Richardson return -1;
93*99a2dd95SBruce Richardson
94*99a2dd95SBruce Richardson strlcpy(portlist_str, buf, token_len + 1);
95*99a2dd95SBruce Richardson
96*99a2dd95SBruce Richardson if (pl) {
97*99a2dd95SBruce Richardson pl->map = 0;
98*99a2dd95SBruce Richardson if (strcmp("all", portlist_str) == 0)
99*99a2dd95SBruce Richardson pl->map = UINT32_MAX;
100*99a2dd95SBruce Richardson else if (parse_ports(pl, portlist_str) != 0)
101*99a2dd95SBruce Richardson return -1;
102*99a2dd95SBruce Richardson }
103*99a2dd95SBruce Richardson
104*99a2dd95SBruce Richardson return token_len;
105*99a2dd95SBruce Richardson }
106*99a2dd95SBruce Richardson
107*99a2dd95SBruce Richardson int
cmdline_get_help_portlist(__rte_unused cmdline_parse_token_hdr_t * tk,char * dstbuf,unsigned int size)108*99a2dd95SBruce Richardson cmdline_get_help_portlist(__rte_unused cmdline_parse_token_hdr_t *tk,
109*99a2dd95SBruce Richardson char *dstbuf, unsigned int size)
110*99a2dd95SBruce Richardson {
111*99a2dd95SBruce Richardson int ret;
112*99a2dd95SBruce Richardson ret = snprintf(dstbuf, size, "range of ports as 3,4-6,8-19,20");
113*99a2dd95SBruce Richardson if (ret < 0)
114*99a2dd95SBruce Richardson return -1;
115*99a2dd95SBruce Richardson return 0;
116*99a2dd95SBruce Richardson }
117