15d0a4048SXiaolong Ye /* SPDX-License-Identifier: BSD-3-Clause
25d0a4048SXiaolong Ye * Copyright(c) 2016 Intel Corporation.
35d0a4048SXiaolong Ye * Copyright(c) 2017 Cavium, Inc.
489e5eb11SGuduri Prathyusha */
589e5eb11SGuduri Prathyusha
689e5eb11SGuduri Prathyusha #include <stdint.h>
789e5eb11SGuduri Prathyusha #include <stdlib.h>
889e5eb11SGuduri Prathyusha #include <stdio.h>
989e5eb11SGuduri Prathyusha #include <ctype.h>
1089e5eb11SGuduri Prathyusha #include <getopt.h>
1189e5eb11SGuduri Prathyusha #include <errno.h>
1289e5eb11SGuduri Prathyusha #include <stdarg.h>
1389e5eb11SGuduri Prathyusha #include <string.h>
1489e5eb11SGuduri Prathyusha #include <libgen.h>
1589e5eb11SGuduri Prathyusha #include <unistd.h>
1689e5eb11SGuduri Prathyusha #include <sys/wait.h>
1789e5eb11SGuduri Prathyusha #include <stdbool.h>
1889e5eb11SGuduri Prathyusha
1989e5eb11SGuduri Prathyusha #include <rte_errno.h>
2089e5eb11SGuduri Prathyusha #include <rte_string_fns.h>
2189e5eb11SGuduri Prathyusha
2289e5eb11SGuduri Prathyusha #include "parser.h"
2389e5eb11SGuduri Prathyusha
2489e5eb11SGuduri Prathyusha static uint32_t
get_hex_val(char c)2589e5eb11SGuduri Prathyusha get_hex_val(char c)
2689e5eb11SGuduri Prathyusha {
2789e5eb11SGuduri Prathyusha switch (c) {
2889e5eb11SGuduri Prathyusha case '0': case '1': case '2': case '3': case '4': case '5':
2989e5eb11SGuduri Prathyusha case '6': case '7': case '8': case '9':
3089e5eb11SGuduri Prathyusha return c - '0';
3189e5eb11SGuduri Prathyusha case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
3289e5eb11SGuduri Prathyusha return c - 'A' + 10;
3389e5eb11SGuduri Prathyusha case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
3489e5eb11SGuduri Prathyusha return c - 'a' + 10;
3589e5eb11SGuduri Prathyusha default:
3689e5eb11SGuduri Prathyusha return 0;
3789e5eb11SGuduri Prathyusha }
3889e5eb11SGuduri Prathyusha }
3989e5eb11SGuduri Prathyusha
4089e5eb11SGuduri Prathyusha int
parser_read_arg_bool(const char * p)4189e5eb11SGuduri Prathyusha parser_read_arg_bool(const char *p)
4289e5eb11SGuduri Prathyusha {
43*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
4489e5eb11SGuduri Prathyusha int result = -EINVAL;
4589e5eb11SGuduri Prathyusha
4689e5eb11SGuduri Prathyusha if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
4789e5eb11SGuduri Prathyusha ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
4889e5eb11SGuduri Prathyusha p += 3;
4989e5eb11SGuduri Prathyusha result = 1;
5089e5eb11SGuduri Prathyusha }
5189e5eb11SGuduri Prathyusha
5289e5eb11SGuduri Prathyusha if (((p[0] == 'o') && (p[1] == 'n')) ||
5389e5eb11SGuduri Prathyusha ((p[0] == 'O') && (p[1] == 'N'))) {
5489e5eb11SGuduri Prathyusha p += 2;
5589e5eb11SGuduri Prathyusha result = 1;
5689e5eb11SGuduri Prathyusha }
5789e5eb11SGuduri Prathyusha
5889e5eb11SGuduri Prathyusha if (((p[0] == 'n') && (p[1] == 'o')) ||
5989e5eb11SGuduri Prathyusha ((p[0] == 'N') && (p[1] == 'O'))) {
6089e5eb11SGuduri Prathyusha p += 2;
6189e5eb11SGuduri Prathyusha result = 0;
6289e5eb11SGuduri Prathyusha }
6389e5eb11SGuduri Prathyusha
6489e5eb11SGuduri Prathyusha if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
6589e5eb11SGuduri Prathyusha ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
6689e5eb11SGuduri Prathyusha p += 3;
6789e5eb11SGuduri Prathyusha result = 0;
6889e5eb11SGuduri Prathyusha }
6989e5eb11SGuduri Prathyusha
70*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
7189e5eb11SGuduri Prathyusha
7289e5eb11SGuduri Prathyusha if (p[0] != '\0')
7389e5eb11SGuduri Prathyusha return -EINVAL;
7489e5eb11SGuduri Prathyusha
7589e5eb11SGuduri Prathyusha return result;
7689e5eb11SGuduri Prathyusha }
7789e5eb11SGuduri Prathyusha
7889e5eb11SGuduri Prathyusha int
parser_read_uint64(uint64_t * value,const char * p)7989e5eb11SGuduri Prathyusha parser_read_uint64(uint64_t *value, const char *p)
8089e5eb11SGuduri Prathyusha {
8189e5eb11SGuduri Prathyusha char *next;
8289e5eb11SGuduri Prathyusha uint64_t val;
8389e5eb11SGuduri Prathyusha
84*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
8589e5eb11SGuduri Prathyusha if (!isdigit(*p))
8689e5eb11SGuduri Prathyusha return -EINVAL;
8789e5eb11SGuduri Prathyusha
8889e5eb11SGuduri Prathyusha val = strtoul(p, &next, 10);
8989e5eb11SGuduri Prathyusha if (p == next)
9089e5eb11SGuduri Prathyusha return -EINVAL;
9189e5eb11SGuduri Prathyusha
9289e5eb11SGuduri Prathyusha p = next;
9389e5eb11SGuduri Prathyusha switch (*p) {
9489e5eb11SGuduri Prathyusha case 'T':
9589e5eb11SGuduri Prathyusha val *= 1024ULL;
9689e5eb11SGuduri Prathyusha /* fall through */
9789e5eb11SGuduri Prathyusha case 'G':
9889e5eb11SGuduri Prathyusha val *= 1024ULL;
9989e5eb11SGuduri Prathyusha /* fall through */
10089e5eb11SGuduri Prathyusha case 'M':
10189e5eb11SGuduri Prathyusha val *= 1024ULL;
10289e5eb11SGuduri Prathyusha /* fall through */
10389e5eb11SGuduri Prathyusha case 'k':
10489e5eb11SGuduri Prathyusha case 'K':
10589e5eb11SGuduri Prathyusha val *= 1024ULL;
10689e5eb11SGuduri Prathyusha p++;
10789e5eb11SGuduri Prathyusha break;
10889e5eb11SGuduri Prathyusha }
10989e5eb11SGuduri Prathyusha
110*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
11189e5eb11SGuduri Prathyusha if (*p != '\0')
11289e5eb11SGuduri Prathyusha return -EINVAL;
11389e5eb11SGuduri Prathyusha
11489e5eb11SGuduri Prathyusha *value = val;
11589e5eb11SGuduri Prathyusha return 0;
11689e5eb11SGuduri Prathyusha }
11789e5eb11SGuduri Prathyusha
11889e5eb11SGuduri Prathyusha int
parser_read_int32(int32_t * value,const char * p)11989e5eb11SGuduri Prathyusha parser_read_int32(int32_t *value, const char *p)
12089e5eb11SGuduri Prathyusha {
12189e5eb11SGuduri Prathyusha char *next;
12289e5eb11SGuduri Prathyusha int32_t val;
12389e5eb11SGuduri Prathyusha
124*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
12589e5eb11SGuduri Prathyusha if (!isdigit(*p))
12689e5eb11SGuduri Prathyusha return -EINVAL;
12789e5eb11SGuduri Prathyusha
12889e5eb11SGuduri Prathyusha val = strtol(p, &next, 10);
12989e5eb11SGuduri Prathyusha if (p == next)
13089e5eb11SGuduri Prathyusha return -EINVAL;
13189e5eb11SGuduri Prathyusha
13289e5eb11SGuduri Prathyusha *value = val;
13389e5eb11SGuduri Prathyusha return 0;
13489e5eb11SGuduri Prathyusha }
13589e5eb11SGuduri Prathyusha
13689e5eb11SGuduri Prathyusha int
parser_read_uint64_hex(uint64_t * value,const char * p)13789e5eb11SGuduri Prathyusha parser_read_uint64_hex(uint64_t *value, const char *p)
13889e5eb11SGuduri Prathyusha {
13989e5eb11SGuduri Prathyusha char *next;
14089e5eb11SGuduri Prathyusha uint64_t val;
14189e5eb11SGuduri Prathyusha
142*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(p);
14389e5eb11SGuduri Prathyusha
14489e5eb11SGuduri Prathyusha val = strtoul(p, &next, 16);
14589e5eb11SGuduri Prathyusha if (p == next)
14689e5eb11SGuduri Prathyusha return -EINVAL;
14789e5eb11SGuduri Prathyusha
148*2df20a1dSDavid Marchand p = rte_str_skip_leading_spaces(next);
14989e5eb11SGuduri Prathyusha if (*p != '\0')
15089e5eb11SGuduri Prathyusha return -EINVAL;
15189e5eb11SGuduri Prathyusha
15289e5eb11SGuduri Prathyusha *value = val;
15389e5eb11SGuduri Prathyusha return 0;
15489e5eb11SGuduri Prathyusha }
15589e5eb11SGuduri Prathyusha
15689e5eb11SGuduri Prathyusha int
parser_read_uint32(uint32_t * value,const char * p)15789e5eb11SGuduri Prathyusha parser_read_uint32(uint32_t *value, const char *p)
15889e5eb11SGuduri Prathyusha {
15989e5eb11SGuduri Prathyusha uint64_t val = 0;
16089e5eb11SGuduri Prathyusha int ret = parser_read_uint64(&val, p);
16189e5eb11SGuduri Prathyusha
16289e5eb11SGuduri Prathyusha if (ret < 0)
16389e5eb11SGuduri Prathyusha return ret;
16489e5eb11SGuduri Prathyusha
16589e5eb11SGuduri Prathyusha if (val > UINT32_MAX)
16689e5eb11SGuduri Prathyusha return -ERANGE;
16789e5eb11SGuduri Prathyusha
16889e5eb11SGuduri Prathyusha *value = val;
16989e5eb11SGuduri Prathyusha return 0;
17089e5eb11SGuduri Prathyusha }
17189e5eb11SGuduri Prathyusha
17289e5eb11SGuduri Prathyusha int
parser_read_uint32_hex(uint32_t * value,const char * p)17389e5eb11SGuduri Prathyusha parser_read_uint32_hex(uint32_t *value, const char *p)
17489e5eb11SGuduri Prathyusha {
17589e5eb11SGuduri Prathyusha uint64_t val = 0;
17689e5eb11SGuduri Prathyusha int ret = parser_read_uint64_hex(&val, p);
17789e5eb11SGuduri Prathyusha
17889e5eb11SGuduri Prathyusha if (ret < 0)
17989e5eb11SGuduri Prathyusha return ret;
18089e5eb11SGuduri Prathyusha
18189e5eb11SGuduri Prathyusha if (val > UINT32_MAX)
18289e5eb11SGuduri Prathyusha return -ERANGE;
18389e5eb11SGuduri Prathyusha
18489e5eb11SGuduri Prathyusha *value = val;
18589e5eb11SGuduri Prathyusha return 0;
18689e5eb11SGuduri Prathyusha }
18789e5eb11SGuduri Prathyusha
18889e5eb11SGuduri Prathyusha int
parser_read_uint16(uint16_t * value,const char * p)18989e5eb11SGuduri Prathyusha parser_read_uint16(uint16_t *value, const char *p)
19089e5eb11SGuduri Prathyusha {
19189e5eb11SGuduri Prathyusha uint64_t val = 0;
19289e5eb11SGuduri Prathyusha int ret = parser_read_uint64(&val, p);
19389e5eb11SGuduri Prathyusha
19489e5eb11SGuduri Prathyusha if (ret < 0)
19589e5eb11SGuduri Prathyusha return ret;
19689e5eb11SGuduri Prathyusha
19789e5eb11SGuduri Prathyusha if (val > UINT16_MAX)
19889e5eb11SGuduri Prathyusha return -ERANGE;
19989e5eb11SGuduri Prathyusha
20089e5eb11SGuduri Prathyusha *value = val;
20189e5eb11SGuduri Prathyusha return 0;
20289e5eb11SGuduri Prathyusha }
20389e5eb11SGuduri Prathyusha
20489e5eb11SGuduri Prathyusha int
parser_read_uint16_hex(uint16_t * value,const char * p)20589e5eb11SGuduri Prathyusha parser_read_uint16_hex(uint16_t *value, const char *p)
20689e5eb11SGuduri Prathyusha {
20789e5eb11SGuduri Prathyusha uint64_t val = 0;
20889e5eb11SGuduri Prathyusha int ret = parser_read_uint64_hex(&val, p);
20989e5eb11SGuduri Prathyusha
21089e5eb11SGuduri Prathyusha if (ret < 0)
21189e5eb11SGuduri Prathyusha return ret;
21289e5eb11SGuduri Prathyusha
21389e5eb11SGuduri Prathyusha if (val > UINT16_MAX)
21489e5eb11SGuduri Prathyusha return -ERANGE;
21589e5eb11SGuduri Prathyusha
21689e5eb11SGuduri Prathyusha *value = val;
21789e5eb11SGuduri Prathyusha return 0;
21889e5eb11SGuduri Prathyusha }
21989e5eb11SGuduri Prathyusha
22089e5eb11SGuduri Prathyusha int
parser_read_uint8(uint8_t * value,const char * p)22189e5eb11SGuduri Prathyusha parser_read_uint8(uint8_t *value, const char *p)
22289e5eb11SGuduri Prathyusha {
22389e5eb11SGuduri Prathyusha uint64_t val = 0;
22489e5eb11SGuduri Prathyusha int ret = parser_read_uint64(&val, p);
22589e5eb11SGuduri Prathyusha
22689e5eb11SGuduri Prathyusha if (ret < 0)
22789e5eb11SGuduri Prathyusha return ret;
22889e5eb11SGuduri Prathyusha
22989e5eb11SGuduri Prathyusha if (val > UINT8_MAX)
23089e5eb11SGuduri Prathyusha return -ERANGE;
23189e5eb11SGuduri Prathyusha
23289e5eb11SGuduri Prathyusha *value = val;
23389e5eb11SGuduri Prathyusha return 0;
23489e5eb11SGuduri Prathyusha }
23589e5eb11SGuduri Prathyusha
23689e5eb11SGuduri Prathyusha int
parser_read_uint8_hex(uint8_t * value,const char * p)23789e5eb11SGuduri Prathyusha parser_read_uint8_hex(uint8_t *value, const char *p)
23889e5eb11SGuduri Prathyusha {
23989e5eb11SGuduri Prathyusha uint64_t val = 0;
24089e5eb11SGuduri Prathyusha int ret = parser_read_uint64_hex(&val, p);
24189e5eb11SGuduri Prathyusha
24289e5eb11SGuduri Prathyusha if (ret < 0)
24389e5eb11SGuduri Prathyusha return ret;
24489e5eb11SGuduri Prathyusha
24589e5eb11SGuduri Prathyusha if (val > UINT8_MAX)
24689e5eb11SGuduri Prathyusha return -ERANGE;
24789e5eb11SGuduri Prathyusha
24889e5eb11SGuduri Prathyusha *value = val;
24989e5eb11SGuduri Prathyusha return 0;
25089e5eb11SGuduri Prathyusha }
25189e5eb11SGuduri Prathyusha
25289e5eb11SGuduri Prathyusha int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)25389e5eb11SGuduri Prathyusha parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
25489e5eb11SGuduri Prathyusha {
25589e5eb11SGuduri Prathyusha uint32_t i;
25689e5eb11SGuduri Prathyusha
25789e5eb11SGuduri Prathyusha if ((string == NULL) ||
25889e5eb11SGuduri Prathyusha (tokens == NULL) ||
25989e5eb11SGuduri Prathyusha (*n_tokens < 1))
26089e5eb11SGuduri Prathyusha return -EINVAL;
26189e5eb11SGuduri Prathyusha
26289e5eb11SGuduri Prathyusha for (i = 0; i < *n_tokens; i++) {
26389e5eb11SGuduri Prathyusha tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
26489e5eb11SGuduri Prathyusha if (tokens[i] == NULL)
26589e5eb11SGuduri Prathyusha break;
26689e5eb11SGuduri Prathyusha }
26789e5eb11SGuduri Prathyusha
26889e5eb11SGuduri Prathyusha if ((i == *n_tokens) &&
26989e5eb11SGuduri Prathyusha (strtok_r(string, PARSE_DELIMITER, &string) != NULL))
27089e5eb11SGuduri Prathyusha return -E2BIG;
27189e5eb11SGuduri Prathyusha
27289e5eb11SGuduri Prathyusha *n_tokens = i;
27389e5eb11SGuduri Prathyusha return 0;
27489e5eb11SGuduri Prathyusha }
27589e5eb11SGuduri Prathyusha
27689e5eb11SGuduri Prathyusha int
parse_hex_string(const char * src,uint8_t * dst,uint32_t * size)277750ab9d5SAakash Sasidharan parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
27889e5eb11SGuduri Prathyusha {
27989e5eb11SGuduri Prathyusha uint32_t len, i;
280750ab9d5SAakash Sasidharan const char *c;
28189e5eb11SGuduri Prathyusha
28289e5eb11SGuduri Prathyusha /* Check input parameters */
28389e5eb11SGuduri Prathyusha if ((src == NULL) ||
28489e5eb11SGuduri Prathyusha (dst == NULL) ||
28589e5eb11SGuduri Prathyusha (size == NULL) ||
28689e5eb11SGuduri Prathyusha (*size == 0))
28789e5eb11SGuduri Prathyusha return -1;
28889e5eb11SGuduri Prathyusha
28989e5eb11SGuduri Prathyusha len = strlen(src);
29089e5eb11SGuduri Prathyusha if (((len & 3) != 0) ||
29189e5eb11SGuduri Prathyusha (len > (*size) * 2))
29289e5eb11SGuduri Prathyusha return -1;
29389e5eb11SGuduri Prathyusha *size = len / 2;
29489e5eb11SGuduri Prathyusha
29589e5eb11SGuduri Prathyusha for (c = src; *c != 0; c++) {
29689e5eb11SGuduri Prathyusha if ((((*c) >= '0') && ((*c) <= '9')) ||
29789e5eb11SGuduri Prathyusha (((*c) >= 'A') && ((*c) <= 'F')) ||
29889e5eb11SGuduri Prathyusha (((*c) >= 'a') && ((*c) <= 'f')))
29989e5eb11SGuduri Prathyusha continue;
30089e5eb11SGuduri Prathyusha
30189e5eb11SGuduri Prathyusha return -1;
30289e5eb11SGuduri Prathyusha }
30389e5eb11SGuduri Prathyusha
30489e5eb11SGuduri Prathyusha /* Convert chars to bytes */
30589e5eb11SGuduri Prathyusha for (i = 0; i < *size; i++)
30689e5eb11SGuduri Prathyusha dst[i] = get_hex_val(src[2 * i]) * 16 +
30789e5eb11SGuduri Prathyusha get_hex_val(src[2 * i + 1]);
30889e5eb11SGuduri Prathyusha
30989e5eb11SGuduri Prathyusha return 0;
31089e5eb11SGuduri Prathyusha }
31189e5eb11SGuduri Prathyusha
31289e5eb11SGuduri Prathyusha int
parse_lcores_list(bool lcores[],int lcores_num,const char * corelist)31332d7dbf2SMin Hu (Connor) parse_lcores_list(bool lcores[], int lcores_num, const char *corelist)
31489e5eb11SGuduri Prathyusha {
31589e5eb11SGuduri Prathyusha int i, idx = 0;
31689e5eb11SGuduri Prathyusha int min, max;
31789e5eb11SGuduri Prathyusha char *end = NULL;
31889e5eb11SGuduri Prathyusha
31989e5eb11SGuduri Prathyusha if (corelist == NULL)
32089e5eb11SGuduri Prathyusha return -1;
32189e5eb11SGuduri Prathyusha while (isblank(*corelist))
32289e5eb11SGuduri Prathyusha corelist++;
32389e5eb11SGuduri Prathyusha i = strlen(corelist);
32489e5eb11SGuduri Prathyusha while ((i > 0) && isblank(corelist[i - 1]))
32589e5eb11SGuduri Prathyusha i--;
32689e5eb11SGuduri Prathyusha
32789e5eb11SGuduri Prathyusha /* Get list of lcores */
32889e5eb11SGuduri Prathyusha min = RTE_MAX_LCORE;
32989e5eb11SGuduri Prathyusha do {
33089e5eb11SGuduri Prathyusha while (isblank(*corelist))
33189e5eb11SGuduri Prathyusha corelist++;
33289e5eb11SGuduri Prathyusha if (*corelist == '\0')
33389e5eb11SGuduri Prathyusha return -1;
33489e5eb11SGuduri Prathyusha idx = strtoul(corelist, &end, 10);
33532d7dbf2SMin Hu (Connor) if (idx < 0 || idx > lcores_num)
33632d7dbf2SMin Hu (Connor) return -1;
33789e5eb11SGuduri Prathyusha
33889e5eb11SGuduri Prathyusha if (end == NULL)
33989e5eb11SGuduri Prathyusha return -1;
34089e5eb11SGuduri Prathyusha while (isblank(*end))
34189e5eb11SGuduri Prathyusha end++;
34289e5eb11SGuduri Prathyusha if (*end == '-') {
34389e5eb11SGuduri Prathyusha min = idx;
34489e5eb11SGuduri Prathyusha } else if ((*end == ',') || (*end == '\0')) {
34589e5eb11SGuduri Prathyusha max = idx;
34689e5eb11SGuduri Prathyusha if (min == RTE_MAX_LCORE)
34789e5eb11SGuduri Prathyusha min = idx;
348ca90f20fSPavan Nikhilesh for (idx = min; idx <= max; idx++) {
34989e5eb11SGuduri Prathyusha if (lcores[idx] == 1)
35089e5eb11SGuduri Prathyusha return -E2BIG;
35189e5eb11SGuduri Prathyusha lcores[idx] = 1;
35289e5eb11SGuduri Prathyusha }
35389e5eb11SGuduri Prathyusha
35489e5eb11SGuduri Prathyusha min = RTE_MAX_LCORE;
35589e5eb11SGuduri Prathyusha } else
35689e5eb11SGuduri Prathyusha return -1;
35789e5eb11SGuduri Prathyusha corelist = end + 1;
35889e5eb11SGuduri Prathyusha } while (*end != '\0');
35989e5eb11SGuduri Prathyusha
36089e5eb11SGuduri Prathyusha return 0;
36189e5eb11SGuduri Prathyusha }
362