xref: /dpdk/examples/ip_pipeline/parser.c (revision ed7a0490f7e237259ea24d059bf0b8b63e543cbc)
1*ed7a0490SPiotr Azarewicz /*-
2*ed7a0490SPiotr Azarewicz  *   BSD LICENSE
3*ed7a0490SPiotr Azarewicz  *
4*ed7a0490SPiotr Azarewicz  *   Copyright(c) 2016 Intel Corporation. All rights reserved.
5*ed7a0490SPiotr Azarewicz  *   All rights reserved.
6*ed7a0490SPiotr Azarewicz  *
7*ed7a0490SPiotr Azarewicz  *   Redistribution and use in source and binary forms, with or without
8*ed7a0490SPiotr Azarewicz  *   modification, are permitted provided that the following conditions
9*ed7a0490SPiotr Azarewicz  *   are met:
10*ed7a0490SPiotr Azarewicz  *
11*ed7a0490SPiotr Azarewicz  *     * Redistributions of source code must retain the above copyright
12*ed7a0490SPiotr Azarewicz  *       notice, this list of conditions and the following disclaimer.
13*ed7a0490SPiotr Azarewicz  *     * Redistributions in binary form must reproduce the above copyright
14*ed7a0490SPiotr Azarewicz  *       notice, this list of conditions and the following disclaimer in
15*ed7a0490SPiotr Azarewicz  *       the documentation and/or other materials provided with the
16*ed7a0490SPiotr Azarewicz  *       distribution.
17*ed7a0490SPiotr Azarewicz  *     * Neither the name of Intel Corporation nor the names of its
18*ed7a0490SPiotr Azarewicz  *       contributors may be used to endorse or promote products derived
19*ed7a0490SPiotr Azarewicz  *       from this software without specific prior written permission.
20*ed7a0490SPiotr Azarewicz  *
21*ed7a0490SPiotr Azarewicz  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*ed7a0490SPiotr Azarewicz  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*ed7a0490SPiotr Azarewicz  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*ed7a0490SPiotr Azarewicz  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*ed7a0490SPiotr Azarewicz  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*ed7a0490SPiotr Azarewicz  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*ed7a0490SPiotr Azarewicz  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*ed7a0490SPiotr Azarewicz  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*ed7a0490SPiotr Azarewicz  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*ed7a0490SPiotr Azarewicz  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*ed7a0490SPiotr Azarewicz  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*ed7a0490SPiotr Azarewicz  */
33*ed7a0490SPiotr Azarewicz 
34*ed7a0490SPiotr Azarewicz /*
35*ed7a0490SPiotr Azarewicz  * For my_ether_aton() function:
36*ed7a0490SPiotr Azarewicz  *
37*ed7a0490SPiotr Azarewicz  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
38*ed7a0490SPiotr Azarewicz  * All rights reserved.
39*ed7a0490SPiotr Azarewicz  * Redistribution and use in source and binary forms, with or without
40*ed7a0490SPiotr Azarewicz  * modification, are permitted provided that the following conditions are met:
41*ed7a0490SPiotr Azarewicz  *
42*ed7a0490SPiotr Azarewicz  *     * Redistributions of source code must retain the above copyright
43*ed7a0490SPiotr Azarewicz  *       notice, this list of conditions and the following disclaimer.
44*ed7a0490SPiotr Azarewicz  *     * Redistributions in binary form must reproduce the above copyright
45*ed7a0490SPiotr Azarewicz  *       notice, this list of conditions and the following disclaimer in the
46*ed7a0490SPiotr Azarewicz  *       documentation and/or other materials provided with the distribution.
47*ed7a0490SPiotr Azarewicz  *     * Neither the name of the University of California, Berkeley nor the
48*ed7a0490SPiotr Azarewicz  *       names of its contributors may be used to endorse or promote products
49*ed7a0490SPiotr Azarewicz  *       derived from this software without specific prior written permission.
50*ed7a0490SPiotr Azarewicz  *
51*ed7a0490SPiotr Azarewicz  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
52*ed7a0490SPiotr Azarewicz  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53*ed7a0490SPiotr Azarewicz  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54*ed7a0490SPiotr Azarewicz  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
55*ed7a0490SPiotr Azarewicz  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56*ed7a0490SPiotr Azarewicz  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57*ed7a0490SPiotr Azarewicz  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58*ed7a0490SPiotr Azarewicz  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59*ed7a0490SPiotr Azarewicz  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60*ed7a0490SPiotr Azarewicz  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61*ed7a0490SPiotr Azarewicz  */
62*ed7a0490SPiotr Azarewicz 
63*ed7a0490SPiotr Azarewicz /*
64*ed7a0490SPiotr Azarewicz  * For inet_pton4() and inet_pton6() functions:
65*ed7a0490SPiotr Azarewicz  *
66*ed7a0490SPiotr Azarewicz  * Copyright (c) 1996 by Internet Software Consortium.
67*ed7a0490SPiotr Azarewicz  *
68*ed7a0490SPiotr Azarewicz  * Permission to use, copy, modify, and distribute this software for any
69*ed7a0490SPiotr Azarewicz  * purpose with or without fee is hereby granted, provided that the above
70*ed7a0490SPiotr Azarewicz  * copyright notice and this permission notice appear in all copies.
71*ed7a0490SPiotr Azarewicz  *
72*ed7a0490SPiotr Azarewicz  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
73*ed7a0490SPiotr Azarewicz  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
74*ed7a0490SPiotr Azarewicz  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
75*ed7a0490SPiotr Azarewicz  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
76*ed7a0490SPiotr Azarewicz  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
77*ed7a0490SPiotr Azarewicz  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
78*ed7a0490SPiotr Azarewicz  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
79*ed7a0490SPiotr Azarewicz  * SOFTWARE.
80*ed7a0490SPiotr Azarewicz  */
81*ed7a0490SPiotr Azarewicz 
82*ed7a0490SPiotr Azarewicz #include <stdint.h>
83*ed7a0490SPiotr Azarewicz #include <stdlib.h>
84*ed7a0490SPiotr Azarewicz #include <stdio.h>
85*ed7a0490SPiotr Azarewicz #include <ctype.h>
86*ed7a0490SPiotr Azarewicz #include <getopt.h>
87*ed7a0490SPiotr Azarewicz #include <errno.h>
88*ed7a0490SPiotr Azarewicz #include <stdarg.h>
89*ed7a0490SPiotr Azarewicz #include <string.h>
90*ed7a0490SPiotr Azarewicz #include <libgen.h>
91*ed7a0490SPiotr Azarewicz #include <unistd.h>
92*ed7a0490SPiotr Azarewicz #include <sys/wait.h>
93*ed7a0490SPiotr Azarewicz 
94*ed7a0490SPiotr Azarewicz #include <rte_errno.h>
95*ed7a0490SPiotr Azarewicz #include <rte_cfgfile.h>
96*ed7a0490SPiotr Azarewicz #include <rte_string_fns.h>
97*ed7a0490SPiotr Azarewicz 
98*ed7a0490SPiotr Azarewicz #include "app.h"
99*ed7a0490SPiotr Azarewicz #include "parser.h"
100*ed7a0490SPiotr Azarewicz 
101*ed7a0490SPiotr Azarewicz static uint32_t
102*ed7a0490SPiotr Azarewicz get_hex_val(char c)
103*ed7a0490SPiotr Azarewicz {
104*ed7a0490SPiotr Azarewicz 	switch (c) {
105*ed7a0490SPiotr Azarewicz 	case '0': case '1': case '2': case '3': case '4': case '5':
106*ed7a0490SPiotr Azarewicz 	case '6': case '7': case '8': case '9':
107*ed7a0490SPiotr Azarewicz 		return c - '0';
108*ed7a0490SPiotr Azarewicz 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
109*ed7a0490SPiotr Azarewicz 		return c - 'A' + 10;
110*ed7a0490SPiotr Azarewicz 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
111*ed7a0490SPiotr Azarewicz 		return c - 'a' + 10;
112*ed7a0490SPiotr Azarewicz 	default:
113*ed7a0490SPiotr Azarewicz 		return 0;
114*ed7a0490SPiotr Azarewicz 	}
115*ed7a0490SPiotr Azarewicz }
116*ed7a0490SPiotr Azarewicz 
117*ed7a0490SPiotr Azarewicz int
118*ed7a0490SPiotr Azarewicz parser_read_arg_bool(const char *p)
119*ed7a0490SPiotr Azarewicz {
120*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(p);
121*ed7a0490SPiotr Azarewicz 	int result = -EINVAL;
122*ed7a0490SPiotr Azarewicz 
123*ed7a0490SPiotr Azarewicz 	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
124*ed7a0490SPiotr Azarewicz 		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
125*ed7a0490SPiotr Azarewicz 		p += 3;
126*ed7a0490SPiotr Azarewicz 		result = 1;
127*ed7a0490SPiotr Azarewicz 	}
128*ed7a0490SPiotr Azarewicz 
129*ed7a0490SPiotr Azarewicz 	if (((p[0] == 'o') && (p[1] == 'n')) ||
130*ed7a0490SPiotr Azarewicz 		((p[0] == 'O') && (p[1] == 'N'))) {
131*ed7a0490SPiotr Azarewicz 		p += 2;
132*ed7a0490SPiotr Azarewicz 		result = 1;
133*ed7a0490SPiotr Azarewicz 	}
134*ed7a0490SPiotr Azarewicz 
135*ed7a0490SPiotr Azarewicz 	if (((p[0] == 'n') && (p[1] == 'o')) ||
136*ed7a0490SPiotr Azarewicz 		((p[0] == 'N') && (p[1] == 'O'))) {
137*ed7a0490SPiotr Azarewicz 		p += 2;
138*ed7a0490SPiotr Azarewicz 		result = 0;
139*ed7a0490SPiotr Azarewicz 	}
140*ed7a0490SPiotr Azarewicz 
141*ed7a0490SPiotr Azarewicz 	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
142*ed7a0490SPiotr Azarewicz 		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
143*ed7a0490SPiotr Azarewicz 		p += 3;
144*ed7a0490SPiotr Azarewicz 		result = 0;
145*ed7a0490SPiotr Azarewicz 	}
146*ed7a0490SPiotr Azarewicz 
147*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(p);
148*ed7a0490SPiotr Azarewicz 
149*ed7a0490SPiotr Azarewicz 	if (p[0] != '\0')
150*ed7a0490SPiotr Azarewicz 		return -EINVAL;
151*ed7a0490SPiotr Azarewicz 
152*ed7a0490SPiotr Azarewicz 	return result;
153*ed7a0490SPiotr Azarewicz }
154*ed7a0490SPiotr Azarewicz 
155*ed7a0490SPiotr Azarewicz int
156*ed7a0490SPiotr Azarewicz parser_read_uint64(uint64_t *value, const char *p)
157*ed7a0490SPiotr Azarewicz {
158*ed7a0490SPiotr Azarewicz 	char *next;
159*ed7a0490SPiotr Azarewicz 	uint64_t val;
160*ed7a0490SPiotr Azarewicz 
161*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(p);
162*ed7a0490SPiotr Azarewicz 	if (!isdigit(*p))
163*ed7a0490SPiotr Azarewicz 		return -EINVAL;
164*ed7a0490SPiotr Azarewicz 
165*ed7a0490SPiotr Azarewicz 	val = strtoul(p, &next, 10);
166*ed7a0490SPiotr Azarewicz 	if (p == next)
167*ed7a0490SPiotr Azarewicz 		return -EINVAL;
168*ed7a0490SPiotr Azarewicz 
169*ed7a0490SPiotr Azarewicz 	p = next;
170*ed7a0490SPiotr Azarewicz 	switch (*p) {
171*ed7a0490SPiotr Azarewicz 	case 'T':
172*ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
173*ed7a0490SPiotr Azarewicz 		/* fall through */
174*ed7a0490SPiotr Azarewicz 	case 'G':
175*ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
176*ed7a0490SPiotr Azarewicz 		/* fall through */
177*ed7a0490SPiotr Azarewicz 	case 'M':
178*ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
179*ed7a0490SPiotr Azarewicz 		/* fall through */
180*ed7a0490SPiotr Azarewicz 	case 'k':
181*ed7a0490SPiotr Azarewicz 	case 'K':
182*ed7a0490SPiotr Azarewicz 		val *= 1024ULL;
183*ed7a0490SPiotr Azarewicz 		p++;
184*ed7a0490SPiotr Azarewicz 		break;
185*ed7a0490SPiotr Azarewicz 	}
186*ed7a0490SPiotr Azarewicz 
187*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(p);
188*ed7a0490SPiotr Azarewicz 	if (*p != '\0')
189*ed7a0490SPiotr Azarewicz 		return -EINVAL;
190*ed7a0490SPiotr Azarewicz 
191*ed7a0490SPiotr Azarewicz 	*value = val;
192*ed7a0490SPiotr Azarewicz 	return 0;
193*ed7a0490SPiotr Azarewicz }
194*ed7a0490SPiotr Azarewicz 
195*ed7a0490SPiotr Azarewicz int
196*ed7a0490SPiotr Azarewicz parser_read_uint64_hex(uint64_t *value, const char *p)
197*ed7a0490SPiotr Azarewicz {
198*ed7a0490SPiotr Azarewicz 	char *next;
199*ed7a0490SPiotr Azarewicz 	uint64_t val;
200*ed7a0490SPiotr Azarewicz 
201*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(p);
202*ed7a0490SPiotr Azarewicz 
203*ed7a0490SPiotr Azarewicz 	val = strtoul(p, &next, 16);
204*ed7a0490SPiotr Azarewicz 	if (p == next)
205*ed7a0490SPiotr Azarewicz 		return -EINVAL;
206*ed7a0490SPiotr Azarewicz 
207*ed7a0490SPiotr Azarewicz 	p = skip_white_spaces(next);
208*ed7a0490SPiotr Azarewicz 	if (*p != '\0')
209*ed7a0490SPiotr Azarewicz 		return -EINVAL;
210*ed7a0490SPiotr Azarewicz 
211*ed7a0490SPiotr Azarewicz 	*value = val;
212*ed7a0490SPiotr Azarewicz 	return 0;
213*ed7a0490SPiotr Azarewicz }
214*ed7a0490SPiotr Azarewicz 
215*ed7a0490SPiotr Azarewicz int
216*ed7a0490SPiotr Azarewicz parser_read_uint32(uint32_t *value, const char *p)
217*ed7a0490SPiotr Azarewicz {
218*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
219*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
220*ed7a0490SPiotr Azarewicz 
221*ed7a0490SPiotr Azarewicz 	if (ret < 0)
222*ed7a0490SPiotr Azarewicz 		return ret;
223*ed7a0490SPiotr Azarewicz 
224*ed7a0490SPiotr Azarewicz 	if (val > UINT32_MAX)
225*ed7a0490SPiotr Azarewicz 		return -ERANGE;
226*ed7a0490SPiotr Azarewicz 
227*ed7a0490SPiotr Azarewicz 	*value = val;
228*ed7a0490SPiotr Azarewicz 	return 0;
229*ed7a0490SPiotr Azarewicz }
230*ed7a0490SPiotr Azarewicz 
231*ed7a0490SPiotr Azarewicz int
232*ed7a0490SPiotr Azarewicz parser_read_uint32_hex(uint32_t *value, const char *p)
233*ed7a0490SPiotr Azarewicz {
234*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
235*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
236*ed7a0490SPiotr Azarewicz 
237*ed7a0490SPiotr Azarewicz 	if (ret < 0)
238*ed7a0490SPiotr Azarewicz 		return ret;
239*ed7a0490SPiotr Azarewicz 
240*ed7a0490SPiotr Azarewicz 	if (val > UINT32_MAX)
241*ed7a0490SPiotr Azarewicz 		return -ERANGE;
242*ed7a0490SPiotr Azarewicz 
243*ed7a0490SPiotr Azarewicz 	*value = val;
244*ed7a0490SPiotr Azarewicz 	return 0;
245*ed7a0490SPiotr Azarewicz }
246*ed7a0490SPiotr Azarewicz 
247*ed7a0490SPiotr Azarewicz int
248*ed7a0490SPiotr Azarewicz parser_read_uint16(uint16_t *value, const char *p)
249*ed7a0490SPiotr Azarewicz {
250*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
251*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
252*ed7a0490SPiotr Azarewicz 
253*ed7a0490SPiotr Azarewicz 	if (ret < 0)
254*ed7a0490SPiotr Azarewicz 		return ret;
255*ed7a0490SPiotr Azarewicz 
256*ed7a0490SPiotr Azarewicz 	if (val > UINT16_MAX)
257*ed7a0490SPiotr Azarewicz 		return -ERANGE;
258*ed7a0490SPiotr Azarewicz 
259*ed7a0490SPiotr Azarewicz 	*value = val;
260*ed7a0490SPiotr Azarewicz 	return 0;
261*ed7a0490SPiotr Azarewicz }
262*ed7a0490SPiotr Azarewicz 
263*ed7a0490SPiotr Azarewicz int
264*ed7a0490SPiotr Azarewicz parser_read_uint16_hex(uint16_t *value, const char *p)
265*ed7a0490SPiotr Azarewicz {
266*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
267*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
268*ed7a0490SPiotr Azarewicz 
269*ed7a0490SPiotr Azarewicz 	if (ret < 0)
270*ed7a0490SPiotr Azarewicz 		return ret;
271*ed7a0490SPiotr Azarewicz 
272*ed7a0490SPiotr Azarewicz 	if (val > UINT16_MAX)
273*ed7a0490SPiotr Azarewicz 		return -ERANGE;
274*ed7a0490SPiotr Azarewicz 
275*ed7a0490SPiotr Azarewicz 	*value = val;
276*ed7a0490SPiotr Azarewicz 	return 0;
277*ed7a0490SPiotr Azarewicz }
278*ed7a0490SPiotr Azarewicz 
279*ed7a0490SPiotr Azarewicz int
280*ed7a0490SPiotr Azarewicz parser_read_uint8(uint8_t *value, const char *p)
281*ed7a0490SPiotr Azarewicz {
282*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
283*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64(&val, p);
284*ed7a0490SPiotr Azarewicz 
285*ed7a0490SPiotr Azarewicz 	if (ret < 0)
286*ed7a0490SPiotr Azarewicz 		return ret;
287*ed7a0490SPiotr Azarewicz 
288*ed7a0490SPiotr Azarewicz 	if (val > UINT8_MAX)
289*ed7a0490SPiotr Azarewicz 		return -ERANGE;
290*ed7a0490SPiotr Azarewicz 
291*ed7a0490SPiotr Azarewicz 	*value = val;
292*ed7a0490SPiotr Azarewicz 	return 0;
293*ed7a0490SPiotr Azarewicz }
294*ed7a0490SPiotr Azarewicz 
295*ed7a0490SPiotr Azarewicz int
296*ed7a0490SPiotr Azarewicz parser_read_uint8_hex(uint8_t *value, const char *p)
297*ed7a0490SPiotr Azarewicz {
298*ed7a0490SPiotr Azarewicz 	uint64_t val = 0;
299*ed7a0490SPiotr Azarewicz 	int ret = parser_read_uint64_hex(&val, p);
300*ed7a0490SPiotr Azarewicz 
301*ed7a0490SPiotr Azarewicz 	if (ret < 0)
302*ed7a0490SPiotr Azarewicz 		return ret;
303*ed7a0490SPiotr Azarewicz 
304*ed7a0490SPiotr Azarewicz 	if (val > UINT8_MAX)
305*ed7a0490SPiotr Azarewicz 		return -ERANGE;
306*ed7a0490SPiotr Azarewicz 
307*ed7a0490SPiotr Azarewicz 	*value = val;
308*ed7a0490SPiotr Azarewicz 	return 0;
309*ed7a0490SPiotr Azarewicz }
310*ed7a0490SPiotr Azarewicz 
311*ed7a0490SPiotr Azarewicz int
312*ed7a0490SPiotr Azarewicz parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
313*ed7a0490SPiotr Azarewicz {
314*ed7a0490SPiotr Azarewicz 	uint32_t i;
315*ed7a0490SPiotr Azarewicz 
316*ed7a0490SPiotr Azarewicz 	if ((string == NULL) ||
317*ed7a0490SPiotr Azarewicz 		(tokens == NULL) ||
318*ed7a0490SPiotr Azarewicz 		(*n_tokens < 1))
319*ed7a0490SPiotr Azarewicz 		return -EINVAL;
320*ed7a0490SPiotr Azarewicz 
321*ed7a0490SPiotr Azarewicz 	for (i = 0; i < *n_tokens; i++) {
322*ed7a0490SPiotr Azarewicz 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
323*ed7a0490SPiotr Azarewicz 		if (tokens[i] == NULL)
324*ed7a0490SPiotr Azarewicz 			break;
325*ed7a0490SPiotr Azarewicz 	}
326*ed7a0490SPiotr Azarewicz 
327*ed7a0490SPiotr Azarewicz 	if ((i == *n_tokens) &&
328*ed7a0490SPiotr Azarewicz 		(NULL != strtok_r(string, PARSE_DELIMITER, &string)))
329*ed7a0490SPiotr Azarewicz 		return -E2BIG;
330*ed7a0490SPiotr Azarewicz 
331*ed7a0490SPiotr Azarewicz 	*n_tokens = i;
332*ed7a0490SPiotr Azarewicz 	return 0;
333*ed7a0490SPiotr Azarewicz }
334*ed7a0490SPiotr Azarewicz 
335*ed7a0490SPiotr Azarewicz int
336*ed7a0490SPiotr Azarewicz parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
337*ed7a0490SPiotr Azarewicz {
338*ed7a0490SPiotr Azarewicz 	char *c;
339*ed7a0490SPiotr Azarewicz 	uint32_t len, i;
340*ed7a0490SPiotr Azarewicz 
341*ed7a0490SPiotr Azarewicz 	/* Check input parameters */
342*ed7a0490SPiotr Azarewicz 	if ((src == NULL) ||
343*ed7a0490SPiotr Azarewicz 		(dst == NULL) ||
344*ed7a0490SPiotr Azarewicz 		(size == NULL) ||
345*ed7a0490SPiotr Azarewicz 		(*size == 0))
346*ed7a0490SPiotr Azarewicz 		return -1;
347*ed7a0490SPiotr Azarewicz 
348*ed7a0490SPiotr Azarewicz 	len = strlen(src);
349*ed7a0490SPiotr Azarewicz 	if (((len & 3) != 0) ||
350*ed7a0490SPiotr Azarewicz 		(len > (*size) * 2))
351*ed7a0490SPiotr Azarewicz 		return -1;
352*ed7a0490SPiotr Azarewicz 	*size = len / 2;
353*ed7a0490SPiotr Azarewicz 
354*ed7a0490SPiotr Azarewicz 	for (c = src; *c != 0; c++) {
355*ed7a0490SPiotr Azarewicz 		if ((((*c) >= '0') && ((*c) <= '9')) ||
356*ed7a0490SPiotr Azarewicz 			(((*c) >= 'A') && ((*c) <= 'F')) ||
357*ed7a0490SPiotr Azarewicz 			(((*c) >= 'a') && ((*c) <= 'f')))
358*ed7a0490SPiotr Azarewicz 			continue;
359*ed7a0490SPiotr Azarewicz 
360*ed7a0490SPiotr Azarewicz 		return -1;
361*ed7a0490SPiotr Azarewicz 	}
362*ed7a0490SPiotr Azarewicz 
363*ed7a0490SPiotr Azarewicz 	/* Convert chars to bytes */
364*ed7a0490SPiotr Azarewicz 	for (i = 0; i < *size; i++)
365*ed7a0490SPiotr Azarewicz 		dst[i] = get_hex_val(src[2 * i]) * 16 +
366*ed7a0490SPiotr Azarewicz 			get_hex_val(src[2 * i + 1]);
367*ed7a0490SPiotr Azarewicz 
368*ed7a0490SPiotr Azarewicz 	return 0;
369*ed7a0490SPiotr Azarewicz }
370*ed7a0490SPiotr Azarewicz 
371*ed7a0490SPiotr Azarewicz int
372*ed7a0490SPiotr Azarewicz parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
373*ed7a0490SPiotr Azarewicz {
374*ed7a0490SPiotr Azarewicz 	uint32_t n_max_labels = *n_labels, count = 0;
375*ed7a0490SPiotr Azarewicz 
376*ed7a0490SPiotr Azarewicz 	/* Check for void list of labels */
377*ed7a0490SPiotr Azarewicz 	if (strcmp(string, "<void>") == 0) {
378*ed7a0490SPiotr Azarewicz 		*n_labels = 0;
379*ed7a0490SPiotr Azarewicz 		return 0;
380*ed7a0490SPiotr Azarewicz 	}
381*ed7a0490SPiotr Azarewicz 
382*ed7a0490SPiotr Azarewicz 	/* At least one label should be present */
383*ed7a0490SPiotr Azarewicz 	for ( ; (*string != '\0'); ) {
384*ed7a0490SPiotr Azarewicz 		char *next;
385*ed7a0490SPiotr Azarewicz 		int value;
386*ed7a0490SPiotr Azarewicz 
387*ed7a0490SPiotr Azarewicz 		if (count >= n_max_labels)
388*ed7a0490SPiotr Azarewicz 			return -1;
389*ed7a0490SPiotr Azarewicz 
390*ed7a0490SPiotr Azarewicz 		if (count > 0) {
391*ed7a0490SPiotr Azarewicz 			if (string[0] != ':')
392*ed7a0490SPiotr Azarewicz 				return -1;
393*ed7a0490SPiotr Azarewicz 
394*ed7a0490SPiotr Azarewicz 			string++;
395*ed7a0490SPiotr Azarewicz 		}
396*ed7a0490SPiotr Azarewicz 
397*ed7a0490SPiotr Azarewicz 		value = strtol(string, &next, 10);
398*ed7a0490SPiotr Azarewicz 		if (next == string)
399*ed7a0490SPiotr Azarewicz 			return -1;
400*ed7a0490SPiotr Azarewicz 		string = next;
401*ed7a0490SPiotr Azarewicz 
402*ed7a0490SPiotr Azarewicz 		labels[count++] = (uint32_t) value;
403*ed7a0490SPiotr Azarewicz 	}
404*ed7a0490SPiotr Azarewicz 
405*ed7a0490SPiotr Azarewicz 	*n_labels = count;
406*ed7a0490SPiotr Azarewicz 	return 0;
407*ed7a0490SPiotr Azarewicz }
408*ed7a0490SPiotr Azarewicz 
409*ed7a0490SPiotr Azarewicz #define INADDRSZ 4
410*ed7a0490SPiotr Azarewicz #define IN6ADDRSZ 16
411*ed7a0490SPiotr Azarewicz 
412*ed7a0490SPiotr Azarewicz /* int
413*ed7a0490SPiotr Azarewicz  * inet_pton4(src, dst)
414*ed7a0490SPiotr Azarewicz  *      like inet_aton() but without all the hexadecimal and shorthand.
415*ed7a0490SPiotr Azarewicz  * return:
416*ed7a0490SPiotr Azarewicz  *      1 if `src' is a valid dotted quad, else 0.
417*ed7a0490SPiotr Azarewicz  * notice:
418*ed7a0490SPiotr Azarewicz  *      does not touch `dst' unless it's returning 1.
419*ed7a0490SPiotr Azarewicz  * author:
420*ed7a0490SPiotr Azarewicz  *      Paul Vixie, 1996.
421*ed7a0490SPiotr Azarewicz  */
422*ed7a0490SPiotr Azarewicz static int
423*ed7a0490SPiotr Azarewicz inet_pton4(const char *src, unsigned char *dst)
424*ed7a0490SPiotr Azarewicz {
425*ed7a0490SPiotr Azarewicz 	static const char digits[] = "0123456789";
426*ed7a0490SPiotr Azarewicz 	int saw_digit, octets, ch;
427*ed7a0490SPiotr Azarewicz 	unsigned char tmp[INADDRSZ], *tp;
428*ed7a0490SPiotr Azarewicz 
429*ed7a0490SPiotr Azarewicz 	saw_digit = 0;
430*ed7a0490SPiotr Azarewicz 	octets = 0;
431*ed7a0490SPiotr Azarewicz 	*(tp = tmp) = 0;
432*ed7a0490SPiotr Azarewicz 	while ((ch = *src++) != '\0') {
433*ed7a0490SPiotr Azarewicz 		const char *pch;
434*ed7a0490SPiotr Azarewicz 
435*ed7a0490SPiotr Azarewicz 		pch = strchr(digits, ch);
436*ed7a0490SPiotr Azarewicz 		if (pch != NULL) {
437*ed7a0490SPiotr Azarewicz 			unsigned int new = *tp * 10 + (pch - digits);
438*ed7a0490SPiotr Azarewicz 
439*ed7a0490SPiotr Azarewicz 			if (new > 255)
440*ed7a0490SPiotr Azarewicz 				return 0;
441*ed7a0490SPiotr Azarewicz 			if (!saw_digit) {
442*ed7a0490SPiotr Azarewicz 				if (++octets > 4)
443*ed7a0490SPiotr Azarewicz 					return 0;
444*ed7a0490SPiotr Azarewicz 				saw_digit = 1;
445*ed7a0490SPiotr Azarewicz 			}
446*ed7a0490SPiotr Azarewicz 			*tp = (unsigned char)new;
447*ed7a0490SPiotr Azarewicz 		} else if (ch == '.' && saw_digit) {
448*ed7a0490SPiotr Azarewicz 			if (octets == 4)
449*ed7a0490SPiotr Azarewicz 				return 0;
450*ed7a0490SPiotr Azarewicz 			*++tp = 0;
451*ed7a0490SPiotr Azarewicz 			saw_digit = 0;
452*ed7a0490SPiotr Azarewicz 		} else
453*ed7a0490SPiotr Azarewicz 			return 0;
454*ed7a0490SPiotr Azarewicz 	}
455*ed7a0490SPiotr Azarewicz 	if (octets < 4)
456*ed7a0490SPiotr Azarewicz 		return 0;
457*ed7a0490SPiotr Azarewicz 
458*ed7a0490SPiotr Azarewicz 	memcpy(dst, tmp, INADDRSZ);
459*ed7a0490SPiotr Azarewicz 	return 1;
460*ed7a0490SPiotr Azarewicz }
461*ed7a0490SPiotr Azarewicz 
462*ed7a0490SPiotr Azarewicz /* int
463*ed7a0490SPiotr Azarewicz  * inet_pton6(src, dst)
464*ed7a0490SPiotr Azarewicz  *      convert presentation level address to network order binary form.
465*ed7a0490SPiotr Azarewicz  * return:
466*ed7a0490SPiotr Azarewicz  *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
467*ed7a0490SPiotr Azarewicz  * notice:
468*ed7a0490SPiotr Azarewicz  *      (1) does not touch `dst' unless it's returning 1.
469*ed7a0490SPiotr Azarewicz  *      (2) :: in a full address is silently ignored.
470*ed7a0490SPiotr Azarewicz  * credit:
471*ed7a0490SPiotr Azarewicz  *      inspired by Mark Andrews.
472*ed7a0490SPiotr Azarewicz  * author:
473*ed7a0490SPiotr Azarewicz  *      Paul Vixie, 1996.
474*ed7a0490SPiotr Azarewicz  */
475*ed7a0490SPiotr Azarewicz static int
476*ed7a0490SPiotr Azarewicz inet_pton6(const char *src, unsigned char *dst)
477*ed7a0490SPiotr Azarewicz {
478*ed7a0490SPiotr Azarewicz 	static const char xdigits_l[] = "0123456789abcdef",
479*ed7a0490SPiotr Azarewicz 		xdigits_u[] = "0123456789ABCDEF";
480*ed7a0490SPiotr Azarewicz 	unsigned char tmp[IN6ADDRSZ], *tp = 0, *endp = 0, *colonp = 0;
481*ed7a0490SPiotr Azarewicz 	const char *xdigits = 0, *curtok = 0;
482*ed7a0490SPiotr Azarewicz 	int ch = 0, saw_xdigit = 0, count_xdigit = 0;
483*ed7a0490SPiotr Azarewicz 	unsigned int val = 0;
484*ed7a0490SPiotr Azarewicz 	unsigned dbloct_count = 0;
485*ed7a0490SPiotr Azarewicz 
486*ed7a0490SPiotr Azarewicz 	memset((tp = tmp), '\0', IN6ADDRSZ);
487*ed7a0490SPiotr Azarewicz 	endp = tp + IN6ADDRSZ;
488*ed7a0490SPiotr Azarewicz 	colonp = NULL;
489*ed7a0490SPiotr Azarewicz 	/* Leading :: requires some special handling. */
490*ed7a0490SPiotr Azarewicz 	if (*src == ':')
491*ed7a0490SPiotr Azarewicz 		if (*++src != ':')
492*ed7a0490SPiotr Azarewicz 			return 0;
493*ed7a0490SPiotr Azarewicz 	curtok = src;
494*ed7a0490SPiotr Azarewicz 	saw_xdigit = count_xdigit = 0;
495*ed7a0490SPiotr Azarewicz 	val = 0;
496*ed7a0490SPiotr Azarewicz 
497*ed7a0490SPiotr Azarewicz 	while ((ch = *src++) != '\0') {
498*ed7a0490SPiotr Azarewicz 		const char *pch;
499*ed7a0490SPiotr Azarewicz 
500*ed7a0490SPiotr Azarewicz 		pch = strchr((xdigits = xdigits_l), ch);
501*ed7a0490SPiotr Azarewicz 		if (pch == NULL)
502*ed7a0490SPiotr Azarewicz 			pch = strchr((xdigits = xdigits_u), ch);
503*ed7a0490SPiotr Azarewicz 		if (pch != NULL) {
504*ed7a0490SPiotr Azarewicz 			if (count_xdigit >= 4)
505*ed7a0490SPiotr Azarewicz 				return 0;
506*ed7a0490SPiotr Azarewicz 			val <<= 4;
507*ed7a0490SPiotr Azarewicz 			val |= (pch - xdigits);
508*ed7a0490SPiotr Azarewicz 			if (val > 0xffff)
509*ed7a0490SPiotr Azarewicz 				return 0;
510*ed7a0490SPiotr Azarewicz 			saw_xdigit = 1;
511*ed7a0490SPiotr Azarewicz 			count_xdigit++;
512*ed7a0490SPiotr Azarewicz 			continue;
513*ed7a0490SPiotr Azarewicz 		}
514*ed7a0490SPiotr Azarewicz 		if (ch == ':') {
515*ed7a0490SPiotr Azarewicz 			curtok = src;
516*ed7a0490SPiotr Azarewicz 			if (!saw_xdigit) {
517*ed7a0490SPiotr Azarewicz 				if (colonp)
518*ed7a0490SPiotr Azarewicz 					return 0;
519*ed7a0490SPiotr Azarewicz 				colonp = tp;
520*ed7a0490SPiotr Azarewicz 				continue;
521*ed7a0490SPiotr Azarewicz 			} else if (*src == '\0') {
522*ed7a0490SPiotr Azarewicz 				return 0;
523*ed7a0490SPiotr Azarewicz 			}
524*ed7a0490SPiotr Azarewicz 			if (tp + sizeof(int16_t) > endp)
525*ed7a0490SPiotr Azarewicz 				return 0;
526*ed7a0490SPiotr Azarewicz 			*tp++ = (unsigned char) ((val >> 8) & 0xff);
527*ed7a0490SPiotr Azarewicz 			*tp++ = (unsigned char) (val & 0xff);
528*ed7a0490SPiotr Azarewicz 			saw_xdigit = 0;
529*ed7a0490SPiotr Azarewicz 			count_xdigit = 0;
530*ed7a0490SPiotr Azarewicz 			val = 0;
531*ed7a0490SPiotr Azarewicz 			dbloct_count++;
532*ed7a0490SPiotr Azarewicz 			continue;
533*ed7a0490SPiotr Azarewicz 		}
534*ed7a0490SPiotr Azarewicz 		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
535*ed7a0490SPiotr Azarewicz 		    inet_pton4(curtok, tp) > 0) {
536*ed7a0490SPiotr Azarewicz 			tp += INADDRSZ;
537*ed7a0490SPiotr Azarewicz 			saw_xdigit = 0;
538*ed7a0490SPiotr Azarewicz 			dbloct_count += 2;
539*ed7a0490SPiotr Azarewicz 			break;  /* '\0' was seen by inet_pton4(). */
540*ed7a0490SPiotr Azarewicz 		}
541*ed7a0490SPiotr Azarewicz 		return 0;
542*ed7a0490SPiotr Azarewicz 	}
543*ed7a0490SPiotr Azarewicz 	if (saw_xdigit) {
544*ed7a0490SPiotr Azarewicz 		if (tp + sizeof(int16_t) > endp)
545*ed7a0490SPiotr Azarewicz 			return 0;
546*ed7a0490SPiotr Azarewicz 		*tp++ = (unsigned char) ((val >> 8) & 0xff);
547*ed7a0490SPiotr Azarewicz 		*tp++ = (unsigned char) (val & 0xff);
548*ed7a0490SPiotr Azarewicz 		dbloct_count++;
549*ed7a0490SPiotr Azarewicz 	}
550*ed7a0490SPiotr Azarewicz 	if (colonp != NULL) {
551*ed7a0490SPiotr Azarewicz 		/* if we already have 8 double octets, having a colon means error */
552*ed7a0490SPiotr Azarewicz 		if (dbloct_count == 8)
553*ed7a0490SPiotr Azarewicz 			return 0;
554*ed7a0490SPiotr Azarewicz 
555*ed7a0490SPiotr Azarewicz 		/*
556*ed7a0490SPiotr Azarewicz 		 * Since some memmove()'s erroneously fail to handle
557*ed7a0490SPiotr Azarewicz 		 * overlapping regions, we'll do the shift by hand.
558*ed7a0490SPiotr Azarewicz 		 */
559*ed7a0490SPiotr Azarewicz 		const int n = tp - colonp;
560*ed7a0490SPiotr Azarewicz 		int i;
561*ed7a0490SPiotr Azarewicz 
562*ed7a0490SPiotr Azarewicz 		for (i = 1; i <= n; i++) {
563*ed7a0490SPiotr Azarewicz 			endp[-i] = colonp[n - i];
564*ed7a0490SPiotr Azarewicz 			colonp[n - i] = 0;
565*ed7a0490SPiotr Azarewicz 		}
566*ed7a0490SPiotr Azarewicz 		tp = endp;
567*ed7a0490SPiotr Azarewicz 	}
568*ed7a0490SPiotr Azarewicz 	if (tp != endp)
569*ed7a0490SPiotr Azarewicz 		return 0;
570*ed7a0490SPiotr Azarewicz 	memcpy(dst, tmp, IN6ADDRSZ);
571*ed7a0490SPiotr Azarewicz 	return 1;
572*ed7a0490SPiotr Azarewicz }
573*ed7a0490SPiotr Azarewicz 
574*ed7a0490SPiotr Azarewicz static struct ether_addr *
575*ed7a0490SPiotr Azarewicz my_ether_aton(const char *a)
576*ed7a0490SPiotr Azarewicz {
577*ed7a0490SPiotr Azarewicz 	int i;
578*ed7a0490SPiotr Azarewicz 	char *end;
579*ed7a0490SPiotr Azarewicz 	unsigned long o[ETHER_ADDR_LEN];
580*ed7a0490SPiotr Azarewicz 	static struct ether_addr ether_addr;
581*ed7a0490SPiotr Azarewicz 
582*ed7a0490SPiotr Azarewicz 	i = 0;
583*ed7a0490SPiotr Azarewicz 	do {
584*ed7a0490SPiotr Azarewicz 		errno = 0;
585*ed7a0490SPiotr Azarewicz 		o[i] = strtoul(a, &end, 16);
586*ed7a0490SPiotr Azarewicz 		if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
587*ed7a0490SPiotr Azarewicz 			return NULL;
588*ed7a0490SPiotr Azarewicz 		a = end + 1;
589*ed7a0490SPiotr Azarewicz 	} while (++i != sizeof(o) / sizeof(o[0]) && end[0] != 0);
590*ed7a0490SPiotr Azarewicz 
591*ed7a0490SPiotr Azarewicz 	/* Junk at the end of line */
592*ed7a0490SPiotr Azarewicz 	if (end[0] != 0)
593*ed7a0490SPiotr Azarewicz 		return NULL;
594*ed7a0490SPiotr Azarewicz 
595*ed7a0490SPiotr Azarewicz 	/* Support the format XX:XX:XX:XX:XX:XX */
596*ed7a0490SPiotr Azarewicz 	if (i == ETHER_ADDR_LEN) {
597*ed7a0490SPiotr Azarewicz 		while (i-- != 0) {
598*ed7a0490SPiotr Azarewicz 			if (o[i] > UINT8_MAX)
599*ed7a0490SPiotr Azarewicz 				return NULL;
600*ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i] = (uint8_t)o[i];
601*ed7a0490SPiotr Azarewicz 		}
602*ed7a0490SPiotr Azarewicz 	/* Support the format XXXX:XXXX:XXXX */
603*ed7a0490SPiotr Azarewicz 	} else if (i == ETHER_ADDR_LEN / 2) {
604*ed7a0490SPiotr Azarewicz 		while (i-- != 0) {
605*ed7a0490SPiotr Azarewicz 			if (o[i] > UINT16_MAX)
606*ed7a0490SPiotr Azarewicz 				return NULL;
607*ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
608*ed7a0490SPiotr Azarewicz 			ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
609*ed7a0490SPiotr Azarewicz 		}
610*ed7a0490SPiotr Azarewicz 	/* unknown format */
611*ed7a0490SPiotr Azarewicz 	} else
612*ed7a0490SPiotr Azarewicz 		return NULL;
613*ed7a0490SPiotr Azarewicz 
614*ed7a0490SPiotr Azarewicz 	return (struct ether_addr *)&ether_addr;
615*ed7a0490SPiotr Azarewicz }
616*ed7a0490SPiotr Azarewicz 
617*ed7a0490SPiotr Azarewicz int
618*ed7a0490SPiotr Azarewicz parse_ipv4_addr(const char *token, struct in_addr *ipv4)
619*ed7a0490SPiotr Azarewicz {
620*ed7a0490SPiotr Azarewicz 	if (strlen(token) >= INET_ADDRSTRLEN)
621*ed7a0490SPiotr Azarewicz 		return -EINVAL;
622*ed7a0490SPiotr Azarewicz 
623*ed7a0490SPiotr Azarewicz 	if (inet_pton4(token, (unsigned char *)ipv4) != 1)
624*ed7a0490SPiotr Azarewicz 		return -EINVAL;
625*ed7a0490SPiotr Azarewicz 
626*ed7a0490SPiotr Azarewicz 	return 0;
627*ed7a0490SPiotr Azarewicz }
628*ed7a0490SPiotr Azarewicz 
629*ed7a0490SPiotr Azarewicz int
630*ed7a0490SPiotr Azarewicz parse_ipv6_addr(const char *token, struct in6_addr *ipv6)
631*ed7a0490SPiotr Azarewicz {
632*ed7a0490SPiotr Azarewicz 	if (strlen(token) >= INET6_ADDRSTRLEN)
633*ed7a0490SPiotr Azarewicz 		return -EINVAL;
634*ed7a0490SPiotr Azarewicz 
635*ed7a0490SPiotr Azarewicz 	if (inet_pton6(token, (unsigned char *)ipv6) != 1)
636*ed7a0490SPiotr Azarewicz 		return -EINVAL;
637*ed7a0490SPiotr Azarewicz 
638*ed7a0490SPiotr Azarewicz 	return 0;
639*ed7a0490SPiotr Azarewicz }
640*ed7a0490SPiotr Azarewicz 
641*ed7a0490SPiotr Azarewicz int
642*ed7a0490SPiotr Azarewicz parse_mac_addr(const char *token, struct ether_addr *addr)
643*ed7a0490SPiotr Azarewicz {
644*ed7a0490SPiotr Azarewicz 	struct ether_addr *tmp;
645*ed7a0490SPiotr Azarewicz 
646*ed7a0490SPiotr Azarewicz 	tmp = my_ether_aton(token);
647*ed7a0490SPiotr Azarewicz 	if (tmp == NULL)
648*ed7a0490SPiotr Azarewicz 		return -1;
649*ed7a0490SPiotr Azarewicz 
650*ed7a0490SPiotr Azarewicz 	memcpy(addr, tmp, sizeof(struct ether_addr));
651*ed7a0490SPiotr Azarewicz 	return 0;
652*ed7a0490SPiotr Azarewicz }
653*ed7a0490SPiotr Azarewicz 
654*ed7a0490SPiotr Azarewicz int
655*ed7a0490SPiotr Azarewicz parse_pipeline_core(uint32_t *socket,
656*ed7a0490SPiotr Azarewicz 	uint32_t *core,
657*ed7a0490SPiotr Azarewicz 	uint32_t *ht,
658*ed7a0490SPiotr Azarewicz 	const char *entry)
659*ed7a0490SPiotr Azarewicz {
660*ed7a0490SPiotr Azarewicz 	size_t num_len;
661*ed7a0490SPiotr Azarewicz 	char num[8];
662*ed7a0490SPiotr Azarewicz 
663*ed7a0490SPiotr Azarewicz 	uint32_t s = 0, c = 0, h = 0, val;
664*ed7a0490SPiotr Azarewicz 	uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
665*ed7a0490SPiotr Azarewicz 	const char *next = skip_white_spaces(entry);
666*ed7a0490SPiotr Azarewicz 	char type;
667*ed7a0490SPiotr Azarewicz 
668*ed7a0490SPiotr Azarewicz 	/* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
669*ed7a0490SPiotr Azarewicz 	while (*next != '\0') {
670*ed7a0490SPiotr Azarewicz 		/* If everything parsed nothing should left */
671*ed7a0490SPiotr Azarewicz 		if (s_parsed && c_parsed && h_parsed)
672*ed7a0490SPiotr Azarewicz 			return -EINVAL;
673*ed7a0490SPiotr Azarewicz 
674*ed7a0490SPiotr Azarewicz 		type = *next;
675*ed7a0490SPiotr Azarewicz 		switch (type) {
676*ed7a0490SPiotr Azarewicz 		case 's':
677*ed7a0490SPiotr Azarewicz 		case 'S':
678*ed7a0490SPiotr Azarewicz 			if (s_parsed || c_parsed || h_parsed)
679*ed7a0490SPiotr Azarewicz 				return -EINVAL;
680*ed7a0490SPiotr Azarewicz 			s_parsed = 1;
681*ed7a0490SPiotr Azarewicz 			next++;
682*ed7a0490SPiotr Azarewicz 			break;
683*ed7a0490SPiotr Azarewicz 		case 'c':
684*ed7a0490SPiotr Azarewicz 		case 'C':
685*ed7a0490SPiotr Azarewicz 			if (c_parsed || h_parsed)
686*ed7a0490SPiotr Azarewicz 				return -EINVAL;
687*ed7a0490SPiotr Azarewicz 			c_parsed = 1;
688*ed7a0490SPiotr Azarewicz 			next++;
689*ed7a0490SPiotr Azarewicz 			break;
690*ed7a0490SPiotr Azarewicz 		case 'h':
691*ed7a0490SPiotr Azarewicz 		case 'H':
692*ed7a0490SPiotr Azarewicz 			if (h_parsed)
693*ed7a0490SPiotr Azarewicz 				return -EINVAL;
694*ed7a0490SPiotr Azarewicz 			h_parsed = 1;
695*ed7a0490SPiotr Azarewicz 			next++;
696*ed7a0490SPiotr Azarewicz 			break;
697*ed7a0490SPiotr Azarewicz 		default:
698*ed7a0490SPiotr Azarewicz 			/* If it start from digit it must be only core id. */
699*ed7a0490SPiotr Azarewicz 			if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
700*ed7a0490SPiotr Azarewicz 				return -EINVAL;
701*ed7a0490SPiotr Azarewicz 
702*ed7a0490SPiotr Azarewicz 			type = 'C';
703*ed7a0490SPiotr Azarewicz 		}
704*ed7a0490SPiotr Azarewicz 
705*ed7a0490SPiotr Azarewicz 		for (num_len = 0; *next != '\0'; next++, num_len++) {
706*ed7a0490SPiotr Azarewicz 			if (num_len == RTE_DIM(num))
707*ed7a0490SPiotr Azarewicz 				return -EINVAL;
708*ed7a0490SPiotr Azarewicz 
709*ed7a0490SPiotr Azarewicz 			if (!isdigit(*next))
710*ed7a0490SPiotr Azarewicz 				break;
711*ed7a0490SPiotr Azarewicz 
712*ed7a0490SPiotr Azarewicz 			num[num_len] = *next;
713*ed7a0490SPiotr Azarewicz 		}
714*ed7a0490SPiotr Azarewicz 
715*ed7a0490SPiotr Azarewicz 		if (num_len == 0 && type != 'h' && type != 'H')
716*ed7a0490SPiotr Azarewicz 			return -EINVAL;
717*ed7a0490SPiotr Azarewicz 
718*ed7a0490SPiotr Azarewicz 		if (num_len != 0 && (type == 'h' || type == 'H'))
719*ed7a0490SPiotr Azarewicz 			return -EINVAL;
720*ed7a0490SPiotr Azarewicz 
721*ed7a0490SPiotr Azarewicz 		num[num_len] = '\0';
722*ed7a0490SPiotr Azarewicz 		val = strtol(num, NULL, 10);
723*ed7a0490SPiotr Azarewicz 
724*ed7a0490SPiotr Azarewicz 		h = 0;
725*ed7a0490SPiotr Azarewicz 		switch (type) {
726*ed7a0490SPiotr Azarewicz 		case 's':
727*ed7a0490SPiotr Azarewicz 		case 'S':
728*ed7a0490SPiotr Azarewicz 			s = val;
729*ed7a0490SPiotr Azarewicz 			break;
730*ed7a0490SPiotr Azarewicz 		case 'c':
731*ed7a0490SPiotr Azarewicz 		case 'C':
732*ed7a0490SPiotr Azarewicz 			c = val;
733*ed7a0490SPiotr Azarewicz 			break;
734*ed7a0490SPiotr Azarewicz 		case 'h':
735*ed7a0490SPiotr Azarewicz 		case 'H':
736*ed7a0490SPiotr Azarewicz 			h = 1;
737*ed7a0490SPiotr Azarewicz 			break;
738*ed7a0490SPiotr Azarewicz 		}
739*ed7a0490SPiotr Azarewicz 	}
740*ed7a0490SPiotr Azarewicz 
741*ed7a0490SPiotr Azarewicz 	*socket = s;
742*ed7a0490SPiotr Azarewicz 	*core = c;
743*ed7a0490SPiotr Azarewicz 	*ht = h;
744*ed7a0490SPiotr Azarewicz 	return 0;
745*ed7a0490SPiotr Azarewicz }
746