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 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 4189e5eb11SGuduri Prathyusha parser_read_arg_bool(const char *p) 4289e5eb11SGuduri Prathyusha { 4389e5eb11SGuduri Prathyusha p = skip_white_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 7089e5eb11SGuduri Prathyusha p = skip_white_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 7989e5eb11SGuduri Prathyusha parser_read_uint64(uint64_t *value, const char *p) 8089e5eb11SGuduri Prathyusha { 8189e5eb11SGuduri Prathyusha char *next; 8289e5eb11SGuduri Prathyusha uint64_t val; 8389e5eb11SGuduri Prathyusha 8489e5eb11SGuduri Prathyusha p = skip_white_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 11089e5eb11SGuduri Prathyusha p = skip_white_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 11989e5eb11SGuduri Prathyusha parser_read_int32(int32_t *value, const char *p) 12089e5eb11SGuduri Prathyusha { 12189e5eb11SGuduri Prathyusha char *next; 12289e5eb11SGuduri Prathyusha int32_t val; 12389e5eb11SGuduri Prathyusha 12489e5eb11SGuduri Prathyusha p = skip_white_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 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 14289e5eb11SGuduri Prathyusha p = skip_white_spaces(p); 14389e5eb11SGuduri Prathyusha 14489e5eb11SGuduri Prathyusha val = strtoul(p, &next, 16); 14589e5eb11SGuduri Prathyusha if (p == next) 14689e5eb11SGuduri Prathyusha return -EINVAL; 14789e5eb11SGuduri Prathyusha 14889e5eb11SGuduri Prathyusha p = skip_white_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 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 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 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 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 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 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 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 27789e5eb11SGuduri Prathyusha parse_hex_string(char *src, uint8_t *dst, uint32_t *size) 27889e5eb11SGuduri Prathyusha { 27989e5eb11SGuduri Prathyusha char *c; 28089e5eb11SGuduri Prathyusha uint32_t len, i; 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 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; 348*ca90f20fSPavan 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