xref: /dpdk/examples/ip_pipeline/parser.c (revision 5ac1abdd37aa43692603cd8670111c354014766f)
1f819588bSLee Daly /* SPDX-License-Identifier: BSD-3-Clause
2f819588bSLee Daly  * Copyright(c) 2016 Intel Corporation.
3ed7a0490SPiotr Azarewicz  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4ed7a0490SPiotr Azarewicz  * All rights reserved.
5ed7a0490SPiotr Azarewicz  */
6ed7a0490SPiotr Azarewicz 
7ed7a0490SPiotr Azarewicz #include <stdint.h>
8ed7a0490SPiotr Azarewicz #include <stdlib.h>
9ed7a0490SPiotr Azarewicz #include <stdio.h>
10ed7a0490SPiotr Azarewicz #include <ctype.h>
11ed7a0490SPiotr Azarewicz #include <getopt.h>
12ed7a0490SPiotr Azarewicz #include <errno.h>
13ed7a0490SPiotr Azarewicz #include <stdarg.h>
14ed7a0490SPiotr Azarewicz #include <string.h>
15ed7a0490SPiotr Azarewicz #include <libgen.h>
16ed7a0490SPiotr Azarewicz #include <unistd.h>
17ed7a0490SPiotr Azarewicz #include <sys/wait.h>
1803ef8c1bSIbtisam Tariq #include <arpa/inet.h>
1903ef8c1bSIbtisam Tariq #include <sys/socket.h>
20ed7a0490SPiotr Azarewicz 
21ed7a0490SPiotr Azarewicz #include <rte_errno.h>
22ed7a0490SPiotr Azarewicz #include <rte_string_fns.h>
23ed7a0490SPiotr Azarewicz 
24ed7a0490SPiotr Azarewicz #include "parser.h"
25ed7a0490SPiotr Azarewicz 
26ed7a0490SPiotr Azarewicz static uint32_t
27ed7a0490SPiotr Azarewicz get_hex_val(char c)
28ed7a0490SPiotr Azarewicz {
29ed7a0490SPiotr Azarewicz 	switch (c) {
30ed7a0490SPiotr Azarewicz 	case '0': case '1': case '2': case '3': case '4': case '5':
31ed7a0490SPiotr Azarewicz 	case '6': case '7': case '8': case '9':
32ed7a0490SPiotr Azarewicz 		return c - '0';
33ed7a0490SPiotr Azarewicz 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
34ed7a0490SPiotr Azarewicz 		return c - 'A' + 10;
35ed7a0490SPiotr Azarewicz 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
36ed7a0490SPiotr Azarewicz 		return c - 'a' + 10;
37ed7a0490SPiotr Azarewicz 	default:
38ed7a0490SPiotr Azarewicz 		return 0;
39ed7a0490SPiotr Azarewicz 	}
40ed7a0490SPiotr Azarewicz }
41ed7a0490SPiotr Azarewicz 
42ed7a0490SPiotr Azarewicz int
43ed7a0490SPiotr Azarewicz parser_read_arg_bool(const char *p)
44ed7a0490SPiotr Azarewicz {
452df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(p);
46ed7a0490SPiotr Azarewicz 	int result = -EINVAL;
47ed7a0490SPiotr Azarewicz 
48ed7a0490SPiotr Azarewicz 	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
49ed7a0490SPiotr Azarewicz 		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
50ed7a0490SPiotr Azarewicz 		p += 3;
51ed7a0490SPiotr Azarewicz 		result = 1;
52ed7a0490SPiotr Azarewicz 	}
53ed7a0490SPiotr Azarewicz 
54ed7a0490SPiotr Azarewicz 	if (((p[0] == 'o') && (p[1] == 'n')) ||
55ed7a0490SPiotr Azarewicz 		((p[0] == 'O') && (p[1] == 'N'))) {
56ed7a0490SPiotr Azarewicz 		p += 2;
57ed7a0490SPiotr Azarewicz 		result = 1;
58ed7a0490SPiotr Azarewicz 	}
59ed7a0490SPiotr Azarewicz 
60ed7a0490SPiotr Azarewicz 	if (((p[0] == 'n') && (p[1] == 'o')) ||
61ed7a0490SPiotr Azarewicz 		((p[0] == 'N') && (p[1] == 'O'))) {
62ed7a0490SPiotr Azarewicz 		p += 2;
63ed7a0490SPiotr Azarewicz 		result = 0;
64ed7a0490SPiotr Azarewicz 	}
65ed7a0490SPiotr Azarewicz 
66ed7a0490SPiotr Azarewicz 	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
67ed7a0490SPiotr Azarewicz 		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
68ed7a0490SPiotr Azarewicz 		p += 3;
69ed7a0490SPiotr Azarewicz 		result = 0;
70ed7a0490SPiotr Azarewicz 	}
71ed7a0490SPiotr Azarewicz 
722df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(p);
73ed7a0490SPiotr Azarewicz 
74ed7a0490SPiotr Azarewicz 	if (p[0] != '\0')
75ed7a0490SPiotr Azarewicz 		return -EINVAL;
76ed7a0490SPiotr Azarewicz 
77ed7a0490SPiotr Azarewicz 	return result;
78ed7a0490SPiotr Azarewicz }
79ed7a0490SPiotr Azarewicz 
80ed7a0490SPiotr Azarewicz int
81ed7a0490SPiotr Azarewicz parser_read_uint64(uint64_t *value, const char *p)
82ed7a0490SPiotr Azarewicz {
83ed7a0490SPiotr Azarewicz 	char *next;
84ed7a0490SPiotr Azarewicz 	uint64_t val;
85ed7a0490SPiotr Azarewicz 
862df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(p);
87ed7a0490SPiotr Azarewicz 	if (!isdigit(*p))
88ed7a0490SPiotr Azarewicz 		return -EINVAL;
89ed7a0490SPiotr Azarewicz 
90ed7a0490SPiotr Azarewicz 	val = strtoul(p, &next, 10);
91ed7a0490SPiotr Azarewicz 	if (p == next)
92ed7a0490SPiotr Azarewicz 		return -EINVAL;
93ed7a0490SPiotr Azarewicz 
94ed7a0490SPiotr Azarewicz 	p = next;
95ed7a0490SPiotr Azarewicz 	switch (*p) {
96ed7a0490SPiotr Azarewicz 	case 'T':
97ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
98ed7a0490SPiotr Azarewicz 		/* fall through */
99ed7a0490SPiotr Azarewicz 	case 'G':
100ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
101ed7a0490SPiotr Azarewicz 		/* fall through */
102ed7a0490SPiotr Azarewicz 	case 'M':
103ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
104ed7a0490SPiotr Azarewicz 		/* fall through */
105ed7a0490SPiotr Azarewicz 	case 'k':
106ed7a0490SPiotr Azarewicz 	case 'K':
107ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
108ed7a0490SPiotr Azarewicz 		p++;
109ed7a0490SPiotr Azarewicz 		break;
110ed7a0490SPiotr Azarewicz 	}
111ed7a0490SPiotr Azarewicz 
1122df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(p);
113ed7a0490SPiotr Azarewicz 	if (*p != '\0')
114ed7a0490SPiotr Azarewicz 		return -EINVAL;
115ed7a0490SPiotr Azarewicz 
116ed7a0490SPiotr Azarewicz 	*value = val;
117ed7a0490SPiotr Azarewicz 	return 0;
118ed7a0490SPiotr Azarewicz }
119ed7a0490SPiotr Azarewicz 
120ed7a0490SPiotr Azarewicz int
121ed7a0490SPiotr Azarewicz parser_read_uint64_hex(uint64_t *value, const char *p)
122ed7a0490SPiotr Azarewicz {
123ed7a0490SPiotr Azarewicz 	char *next;
124ed7a0490SPiotr Azarewicz 	uint64_t val;
125ed7a0490SPiotr Azarewicz 
1262df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(p);
127ed7a0490SPiotr Azarewicz 
128ed7a0490SPiotr Azarewicz 	val = strtoul(p, &next, 16);
129ed7a0490SPiotr Azarewicz 	if (p == next)
130ed7a0490SPiotr Azarewicz 		return -EINVAL;
131ed7a0490SPiotr Azarewicz 
1322df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(next);
133ed7a0490SPiotr Azarewicz 	if (*p != '\0')
134ed7a0490SPiotr Azarewicz 		return -EINVAL;
135ed7a0490SPiotr Azarewicz 
136ed7a0490SPiotr Azarewicz 	*value = val;
137ed7a0490SPiotr Azarewicz 	return 0;
138ed7a0490SPiotr Azarewicz }
139ed7a0490SPiotr Azarewicz 
140ed7a0490SPiotr Azarewicz int
141ed7a0490SPiotr Azarewicz parser_read_uint32(uint32_t *value, const char *p)
142ed7a0490SPiotr Azarewicz {
143ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
144ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
145ed7a0490SPiotr Azarewicz 
146ed7a0490SPiotr Azarewicz 	if (ret < 0)
147ed7a0490SPiotr Azarewicz 		return ret;
148ed7a0490SPiotr Azarewicz 
149ed7a0490SPiotr Azarewicz 	if (val > UINT32_MAX)
150ed7a0490SPiotr Azarewicz 		return -ERANGE;
151ed7a0490SPiotr Azarewicz 
152ed7a0490SPiotr Azarewicz 	*value = val;
153ed7a0490SPiotr Azarewicz 	return 0;
154ed7a0490SPiotr Azarewicz }
155ed7a0490SPiotr Azarewicz 
156ed7a0490SPiotr Azarewicz int
157ed7a0490SPiotr Azarewicz parser_read_uint32_hex(uint32_t *value, const char *p)
158ed7a0490SPiotr Azarewicz {
159ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
160ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
161ed7a0490SPiotr Azarewicz 
162ed7a0490SPiotr Azarewicz 	if (ret < 0)
163ed7a0490SPiotr Azarewicz 		return ret;
164ed7a0490SPiotr Azarewicz 
165ed7a0490SPiotr Azarewicz 	if (val > UINT32_MAX)
166ed7a0490SPiotr Azarewicz 		return -ERANGE;
167ed7a0490SPiotr Azarewicz 
168ed7a0490SPiotr Azarewicz 	*value = val;
169ed7a0490SPiotr Azarewicz 	return 0;
170ed7a0490SPiotr Azarewicz }
171ed7a0490SPiotr Azarewicz 
172ed7a0490SPiotr Azarewicz int
173ed7a0490SPiotr Azarewicz parser_read_uint16(uint16_t *value, const char *p)
174ed7a0490SPiotr Azarewicz {
175ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
176ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
177ed7a0490SPiotr Azarewicz 
178ed7a0490SPiotr Azarewicz 	if (ret < 0)
179ed7a0490SPiotr Azarewicz 		return ret;
180ed7a0490SPiotr Azarewicz 
181ed7a0490SPiotr Azarewicz 	if (val > UINT16_MAX)
182ed7a0490SPiotr Azarewicz 		return -ERANGE;
183ed7a0490SPiotr Azarewicz 
184ed7a0490SPiotr Azarewicz 	*value = val;
185ed7a0490SPiotr Azarewicz 	return 0;
186ed7a0490SPiotr Azarewicz }
187ed7a0490SPiotr Azarewicz 
188ed7a0490SPiotr Azarewicz int
189ed7a0490SPiotr Azarewicz parser_read_uint16_hex(uint16_t *value, const char *p)
190ed7a0490SPiotr Azarewicz {
191ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
192ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
193ed7a0490SPiotr Azarewicz 
194ed7a0490SPiotr Azarewicz 	if (ret < 0)
195ed7a0490SPiotr Azarewicz 		return ret;
196ed7a0490SPiotr Azarewicz 
197ed7a0490SPiotr Azarewicz 	if (val > UINT16_MAX)
198ed7a0490SPiotr Azarewicz 		return -ERANGE;
199ed7a0490SPiotr Azarewicz 
200ed7a0490SPiotr Azarewicz 	*value = val;
201ed7a0490SPiotr Azarewicz 	return 0;
202ed7a0490SPiotr Azarewicz }
203ed7a0490SPiotr Azarewicz 
204ed7a0490SPiotr Azarewicz int
205ed7a0490SPiotr Azarewicz parser_read_uint8(uint8_t *value, const char *p)
206ed7a0490SPiotr Azarewicz {
207ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
208ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
209ed7a0490SPiotr Azarewicz 
210ed7a0490SPiotr Azarewicz 	if (ret < 0)
211ed7a0490SPiotr Azarewicz 		return ret;
212ed7a0490SPiotr Azarewicz 
213ed7a0490SPiotr Azarewicz 	if (val > UINT8_MAX)
214ed7a0490SPiotr Azarewicz 		return -ERANGE;
215ed7a0490SPiotr Azarewicz 
216ed7a0490SPiotr Azarewicz 	*value = val;
217ed7a0490SPiotr Azarewicz 	return 0;
218ed7a0490SPiotr Azarewicz }
219ed7a0490SPiotr Azarewicz 
220ed7a0490SPiotr Azarewicz int
221ed7a0490SPiotr Azarewicz parser_read_uint8_hex(uint8_t *value, const char *p)
222ed7a0490SPiotr Azarewicz {
223ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
224ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
225ed7a0490SPiotr Azarewicz 
226ed7a0490SPiotr Azarewicz 	if (ret < 0)
227ed7a0490SPiotr Azarewicz 		return ret;
228ed7a0490SPiotr Azarewicz 
229ed7a0490SPiotr Azarewicz 	if (val > UINT8_MAX)
230ed7a0490SPiotr Azarewicz 		return -ERANGE;
231ed7a0490SPiotr Azarewicz 
232ed7a0490SPiotr Azarewicz 	*value = val;
233ed7a0490SPiotr Azarewicz 	return 0;
234ed7a0490SPiotr Azarewicz }
235ed7a0490SPiotr Azarewicz 
236ed7a0490SPiotr Azarewicz int
237ed7a0490SPiotr Azarewicz parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
238ed7a0490SPiotr Azarewicz {
239ed7a0490SPiotr Azarewicz 	uint32_t i;
240ed7a0490SPiotr Azarewicz 
241ed7a0490SPiotr Azarewicz 	if ((string == NULL) ||
242ed7a0490SPiotr Azarewicz 		(tokens == NULL) ||
243ed7a0490SPiotr Azarewicz 		(*n_tokens < 1))
244ed7a0490SPiotr Azarewicz 		return -EINVAL;
245ed7a0490SPiotr Azarewicz 
246ed7a0490SPiotr Azarewicz 	for (i = 0; i < *n_tokens; i++) {
247ed7a0490SPiotr Azarewicz 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
248ed7a0490SPiotr Azarewicz 		if (tokens[i] == NULL)
249ed7a0490SPiotr Azarewicz 			break;
250ed7a0490SPiotr Azarewicz 	}
251ed7a0490SPiotr Azarewicz 
252ed7a0490SPiotr Azarewicz 	if ((i == *n_tokens) &&
253ed7a0490SPiotr Azarewicz 		(NULL != strtok_r(string, PARSE_DELIMITER, &string)))
254ed7a0490SPiotr Azarewicz 		return -E2BIG;
255ed7a0490SPiotr Azarewicz 
256ed7a0490SPiotr Azarewicz 	*n_tokens = i;
257ed7a0490SPiotr Azarewicz 	return 0;
258ed7a0490SPiotr Azarewicz }
259ed7a0490SPiotr Azarewicz 
260ed7a0490SPiotr Azarewicz int
261ed7a0490SPiotr Azarewicz parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
262ed7a0490SPiotr Azarewicz {
263ed7a0490SPiotr Azarewicz 	char *c;
264ed7a0490SPiotr Azarewicz 	uint32_t len, i;
265ed7a0490SPiotr Azarewicz 
266ed7a0490SPiotr Azarewicz 	/* Check input parameters */
267ed7a0490SPiotr Azarewicz 	if ((src == NULL) ||
268ed7a0490SPiotr Azarewicz 		(dst == NULL) ||
269ed7a0490SPiotr Azarewicz 		(size == NULL) ||
270ed7a0490SPiotr Azarewicz 		(*size == 0))
271ed7a0490SPiotr Azarewicz 		return -1;
272ed7a0490SPiotr Azarewicz 
273ed7a0490SPiotr Azarewicz 	len = strlen(src);
274ed7a0490SPiotr Azarewicz 	if (((len & 3) != 0) ||
275ed7a0490SPiotr Azarewicz 		(len > (*size) * 2))
276ed7a0490SPiotr Azarewicz 		return -1;
277ed7a0490SPiotr Azarewicz 	*size = len / 2;
278ed7a0490SPiotr Azarewicz 
279ed7a0490SPiotr Azarewicz 	for (c = src; *c != 0; c++) {
280ed7a0490SPiotr Azarewicz 		if ((((*c) >= '0') && ((*c) <= '9')) ||
281ed7a0490SPiotr Azarewicz 			(((*c) >= 'A') && ((*c) <= 'F')) ||
282ed7a0490SPiotr Azarewicz 			(((*c) >= 'a') && ((*c) <= 'f')))
283ed7a0490SPiotr Azarewicz 			continue;
284ed7a0490SPiotr Azarewicz 
285ed7a0490SPiotr Azarewicz 		return -1;
286ed7a0490SPiotr Azarewicz 	}
287ed7a0490SPiotr Azarewicz 
288ed7a0490SPiotr Azarewicz 	/* Convert chars to bytes */
289ed7a0490SPiotr Azarewicz 	for (i = 0; i < *size; i++)
290ed7a0490SPiotr Azarewicz 		dst[i] = get_hex_val(src[2 * i]) * 16 +
291ed7a0490SPiotr Azarewicz 			get_hex_val(src[2 * i + 1]);
292ed7a0490SPiotr Azarewicz 
293ed7a0490SPiotr Azarewicz 	return 0;
294ed7a0490SPiotr Azarewicz }
295ed7a0490SPiotr Azarewicz 
296ed7a0490SPiotr Azarewicz int
297ed7a0490SPiotr Azarewicz parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
298ed7a0490SPiotr Azarewicz {
299ed7a0490SPiotr Azarewicz 	uint32_t n_max_labels = *n_labels, count = 0;
300ed7a0490SPiotr Azarewicz 
301ed7a0490SPiotr Azarewicz 	/* Check for void list of labels */
302ed7a0490SPiotr Azarewicz 	if (strcmp(string, "<void>") == 0) {
303ed7a0490SPiotr Azarewicz 		*n_labels = 0;
304ed7a0490SPiotr Azarewicz 		return 0;
305ed7a0490SPiotr Azarewicz 	}
306ed7a0490SPiotr Azarewicz 
307ed7a0490SPiotr Azarewicz 	/* At least one label should be present */
308ed7a0490SPiotr Azarewicz 	for ( ; (*string != '\0'); ) {
309ed7a0490SPiotr Azarewicz 		char *next;
310ed7a0490SPiotr Azarewicz 		int value;
311ed7a0490SPiotr Azarewicz 
312ed7a0490SPiotr Azarewicz 		if (count >= n_max_labels)
313ed7a0490SPiotr Azarewicz 			return -1;
314ed7a0490SPiotr Azarewicz 
315ed7a0490SPiotr Azarewicz 		if (count > 0) {
316ed7a0490SPiotr Azarewicz 			if (string[0] != ':')
317ed7a0490SPiotr Azarewicz 				return -1;
318ed7a0490SPiotr Azarewicz 
319ed7a0490SPiotr Azarewicz 			string++;
320ed7a0490SPiotr Azarewicz 		}
321ed7a0490SPiotr Azarewicz 
322ed7a0490SPiotr Azarewicz 		value = strtol(string, &next, 10);
323ed7a0490SPiotr Azarewicz 		if (next == string)
324ed7a0490SPiotr Azarewicz 			return -1;
325ed7a0490SPiotr Azarewicz 		string = next;
326ed7a0490SPiotr Azarewicz 
327ed7a0490SPiotr Azarewicz 		labels[count++] = (uint32_t) value;
328ed7a0490SPiotr Azarewicz 	}
329ed7a0490SPiotr Azarewicz 
330ed7a0490SPiotr Azarewicz 	*n_labels = count;
331ed7a0490SPiotr Azarewicz 	return 0;
332ed7a0490SPiotr Azarewicz }
333ed7a0490SPiotr Azarewicz 
3346d13ea8eSOlivier Matz static struct rte_ether_addr *
335ed7a0490SPiotr Azarewicz my_ether_aton(const char *a)
336ed7a0490SPiotr Azarewicz {
337ed7a0490SPiotr Azarewicz 	int i;
338ed7a0490SPiotr Azarewicz 	char *end;
33935b2d13fSOlivier Matz 	unsigned long o[RTE_ETHER_ADDR_LEN];
3406d13ea8eSOlivier Matz 	static struct rte_ether_addr ether_addr;
341ed7a0490SPiotr Azarewicz 
342ed7a0490SPiotr Azarewicz 	i = 0;
343ed7a0490SPiotr Azarewicz 	do {
344ed7a0490SPiotr Azarewicz 		errno = 0;
345ed7a0490SPiotr Azarewicz 		o[i] = strtoul(a, &end, 16);
346ed7a0490SPiotr Azarewicz 		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
347ed7a0490SPiotr Azarewicz 			return NULL;
348ed7a0490SPiotr Azarewicz 		a = end + 1;
3497efe28bdSPavan Nikhilesh 	} while (++i != RTE_DIM(o) && end[0] != 0);
350ed7a0490SPiotr Azarewicz 
351ed7a0490SPiotr Azarewicz 	/* Junk at the end of line */
352ed7a0490SPiotr Azarewicz 	if (end[0] != 0)
353ed7a0490SPiotr Azarewicz 		return NULL;
354ed7a0490SPiotr Azarewicz 
355ed7a0490SPiotr Azarewicz 	/* Support the format XX:XX:XX:XX:XX:XX */
35635b2d13fSOlivier Matz 	if (i == RTE_ETHER_ADDR_LEN) {
357ed7a0490SPiotr Azarewicz 		while (i-- != 0) {
358ed7a0490SPiotr Azarewicz 			if (o[i] > UINT8_MAX)
359ed7a0490SPiotr Azarewicz 				return NULL;
360ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i] = (uint8_t)o[i];
361ed7a0490SPiotr Azarewicz 		}
362ed7a0490SPiotr Azarewicz 	/* Support the format XXXX:XXXX:XXXX */
36335b2d13fSOlivier Matz 	} else if (i == RTE_ETHER_ADDR_LEN / 2) {
364ed7a0490SPiotr Azarewicz 		while (i-- != 0) {
365ed7a0490SPiotr Azarewicz 			if (o[i] > UINT16_MAX)
366ed7a0490SPiotr Azarewicz 				return NULL;
367ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
368ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
369ed7a0490SPiotr Azarewicz 		}
370ed7a0490SPiotr Azarewicz 	/* unknown format */
371ed7a0490SPiotr Azarewicz 	} else
372ed7a0490SPiotr Azarewicz 		return NULL;
373ed7a0490SPiotr Azarewicz 
3746d13ea8eSOlivier Matz 	return (struct rte_ether_addr *)&ether_addr;
375ed7a0490SPiotr Azarewicz }
376ed7a0490SPiotr Azarewicz 
377ed7a0490SPiotr Azarewicz int
378ed7a0490SPiotr Azarewicz parse_ipv4_addr(const char *token, struct in_addr *ipv4)
379ed7a0490SPiotr Azarewicz {
380ed7a0490SPiotr Azarewicz 	if (strlen(token) >= INET_ADDRSTRLEN)
381ed7a0490SPiotr Azarewicz 		return -EINVAL;
382ed7a0490SPiotr Azarewicz 
38303ef8c1bSIbtisam Tariq 	if (inet_pton(AF_INET, token, ipv4) != 1)
384ed7a0490SPiotr Azarewicz 		return -EINVAL;
385ed7a0490SPiotr Azarewicz 
386ed7a0490SPiotr Azarewicz 	return 0;
387ed7a0490SPiotr Azarewicz }
388ed7a0490SPiotr Azarewicz 
389ed7a0490SPiotr Azarewicz int
390*5ac1abddSRobin Jarry parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6)
391ed7a0490SPiotr Azarewicz {
392ed7a0490SPiotr Azarewicz 	if (strlen(token) >= INET6_ADDRSTRLEN)
393ed7a0490SPiotr Azarewicz 		return -EINVAL;
394ed7a0490SPiotr Azarewicz 
39503ef8c1bSIbtisam Tariq 	if (inet_pton(AF_INET6, token, ipv6) != 1)
396ed7a0490SPiotr Azarewicz 		return -EINVAL;
397ed7a0490SPiotr Azarewicz 
398ed7a0490SPiotr Azarewicz 	return 0;
399ed7a0490SPiotr Azarewicz }
400ed7a0490SPiotr Azarewicz 
401ed7a0490SPiotr Azarewicz int
4026d13ea8eSOlivier Matz parse_mac_addr(const char *token, struct rte_ether_addr *addr)
403ed7a0490SPiotr Azarewicz {
4046d13ea8eSOlivier Matz 	struct rte_ether_addr *tmp;
405ed7a0490SPiotr Azarewicz 
406ed7a0490SPiotr Azarewicz 	tmp = my_ether_aton(token);
407ed7a0490SPiotr Azarewicz 	if (tmp == NULL)
408ed7a0490SPiotr Azarewicz 		return -1;
409ed7a0490SPiotr Azarewicz 
4106d13ea8eSOlivier Matz 	memcpy(addr, tmp, sizeof(struct rte_ether_addr));
411ed7a0490SPiotr Azarewicz 	return 0;
412ed7a0490SPiotr Azarewicz }
413ed7a0490SPiotr Azarewicz 
414ed7a0490SPiotr Azarewicz int
415fbc74e66SJasvinder Singh parse_cpu_core(const char *entry,
416fbc74e66SJasvinder Singh 	struct cpu_core_params *p)
417ed7a0490SPiotr Azarewicz {
418ed7a0490SPiotr Azarewicz 	size_t num_len;
419ed7a0490SPiotr Azarewicz 	char num[8];
420ed7a0490SPiotr Azarewicz 
421ed7a0490SPiotr Azarewicz 	uint32_t s = 0, c = 0, h = 0, val;
422ed7a0490SPiotr Azarewicz 	uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
4232df20a1dSDavid Marchand 	const char *next = rte_str_skip_leading_spaces(entry);
424ed7a0490SPiotr Azarewicz 	char type;
425ed7a0490SPiotr Azarewicz 
426fbc74e66SJasvinder Singh 	if (p == NULL)
427fbc74e66SJasvinder Singh 		return -EINVAL;
428fbc74e66SJasvinder Singh 
429ed7a0490SPiotr Azarewicz 	/* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
430ed7a0490SPiotr Azarewicz 	while (*next != '\0') {
431ed7a0490SPiotr Azarewicz 		/* If everything parsed nothing should left */
432ed7a0490SPiotr Azarewicz 		if (s_parsed && c_parsed && h_parsed)
433ed7a0490SPiotr Azarewicz 			return -EINVAL;
434ed7a0490SPiotr Azarewicz 
435ed7a0490SPiotr Azarewicz 		type = *next;
436ed7a0490SPiotr Azarewicz 		switch (type) {
437ed7a0490SPiotr Azarewicz 		case 's':
438ed7a0490SPiotr Azarewicz 		case 'S':
439ed7a0490SPiotr Azarewicz 			if (s_parsed || c_parsed || h_parsed)
440ed7a0490SPiotr Azarewicz 				return -EINVAL;
441ed7a0490SPiotr Azarewicz 			s_parsed = 1;
442ed7a0490SPiotr Azarewicz 			next++;
443ed7a0490SPiotr Azarewicz 			break;
444ed7a0490SPiotr Azarewicz 		case 'c':
445ed7a0490SPiotr Azarewicz 		case 'C':
446ed7a0490SPiotr Azarewicz 			if (c_parsed || h_parsed)
447ed7a0490SPiotr Azarewicz 				return -EINVAL;
448ed7a0490SPiotr Azarewicz 			c_parsed = 1;
449ed7a0490SPiotr Azarewicz 			next++;
450ed7a0490SPiotr Azarewicz 			break;
451ed7a0490SPiotr Azarewicz 		case 'h':
452ed7a0490SPiotr Azarewicz 		case 'H':
453ed7a0490SPiotr Azarewicz 			if (h_parsed)
454ed7a0490SPiotr Azarewicz 				return -EINVAL;
455ed7a0490SPiotr Azarewicz 			h_parsed = 1;
456ed7a0490SPiotr Azarewicz 			next++;
457ed7a0490SPiotr Azarewicz 			break;
458ed7a0490SPiotr Azarewicz 		default:
459ed7a0490SPiotr Azarewicz 			/* If it start from digit it must be only core id. */
460ed7a0490SPiotr Azarewicz 			if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
461ed7a0490SPiotr Azarewicz 				return -EINVAL;
462ed7a0490SPiotr Azarewicz 
463ed7a0490SPiotr Azarewicz 			type = 'C';
464ed7a0490SPiotr Azarewicz 		}
465ed7a0490SPiotr Azarewicz 
466ed7a0490SPiotr Azarewicz 		for (num_len = 0; *next != '\0'; next++, num_len++) {
467ed7a0490SPiotr Azarewicz 			if (num_len == RTE_DIM(num))
468ed7a0490SPiotr Azarewicz 				return -EINVAL;
469ed7a0490SPiotr Azarewicz 
470ed7a0490SPiotr Azarewicz 			if (!isdigit(*next))
471ed7a0490SPiotr Azarewicz 				break;
472ed7a0490SPiotr Azarewicz 
473ed7a0490SPiotr Azarewicz 			num[num_len] = *next;
474ed7a0490SPiotr Azarewicz 		}
475ed7a0490SPiotr Azarewicz 
476ed7a0490SPiotr Azarewicz 		if (num_len == 0 && type != 'h' && type != 'H')
477ed7a0490SPiotr Azarewicz 			return -EINVAL;
478ed7a0490SPiotr Azarewicz 
479ed7a0490SPiotr Azarewicz 		if (num_len != 0 && (type == 'h' || type == 'H'))
480ed7a0490SPiotr Azarewicz 			return -EINVAL;
481ed7a0490SPiotr Azarewicz 
482ed7a0490SPiotr Azarewicz 		num[num_len] = '\0';
483ed7a0490SPiotr Azarewicz 		val = strtol(num, NULL, 10);
484ed7a0490SPiotr Azarewicz 
485ed7a0490SPiotr Azarewicz 		h = 0;
486ed7a0490SPiotr Azarewicz 		switch (type) {
487ed7a0490SPiotr Azarewicz 		case 's':
488ed7a0490SPiotr Azarewicz 		case 'S':
489ed7a0490SPiotr Azarewicz 			s = val;
490ed7a0490SPiotr Azarewicz 			break;
491ed7a0490SPiotr Azarewicz 		case 'c':
492ed7a0490SPiotr Azarewicz 		case 'C':
493ed7a0490SPiotr Azarewicz 			c = val;
494ed7a0490SPiotr Azarewicz 			break;
495ed7a0490SPiotr Azarewicz 		case 'h':
496ed7a0490SPiotr Azarewicz 		case 'H':
497ed7a0490SPiotr Azarewicz 			h = 1;
498ed7a0490SPiotr Azarewicz 			break;
499ed7a0490SPiotr Azarewicz 		}
500ed7a0490SPiotr Azarewicz 	}
501ed7a0490SPiotr Azarewicz 
502fbc74e66SJasvinder Singh 	p->socket_id = s;
503fbc74e66SJasvinder Singh 	p->core_id = c;
504fbc74e66SJasvinder Singh 	p->thread_id = h;
505ed7a0490SPiotr Azarewicz 	return 0;
506ed7a0490SPiotr Azarewicz }
507