aboutsummaryrefslogtreecommitdiffstats
path: root/src/bpfswitch/usrc/str_utils.c
blob: 8650cdfb63b09d77df8a1d1ea8a28f6ca7b29e79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// SPDX-License-Identifier: GPL-2.0
/*
 * String conversion and parsing functions.
 *
 * David Ahern <dsahern@gmail.com>
 */
#include <linux/if_ether.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>

#include "str_utils.h"

static int str_to_int_base(const char *str, int min, int max, int *value, int base)
{
	int number;
	char *end;

	errno = 0;
	number = (int) strtol(str, &end, base);

	if ( ((*end == '\0') || (*end == '\n')) && (end != str) &&
	    (errno != ERANGE) && (min <= number) && (number <= max)) {
		*value = number;
		return 0;
	}

	return -1;
}

int str_to_int(const char *str, int min, int max, int *value)
{
	return str_to_int_base(str, min, max, value, 0);
}

int str_to_ushort(const char *str, unsigned short *us)
{
	int i;

	if (str_to_int(str, 0, 0xFFFF, &i) != 0)
		return -1;

	*us = (unsigned short) (i);

	return 0;
}

int str_to_ulong_base(const char *str, unsigned long *ul, int base)
{
	char *end;

	*ul= strtoul(str, &end, base);
	if (*end != '\0')
		return -1;

	return 0;
}

int str_to_ulong(const char *str, unsigned long *ul)
{
	return str_to_ulong_base(str, ul, 0);
}

int str_to_ullong(const char *str, unsigned long long *ul)
{
	char *end;

	*ul= strtoull(str, &end, 0);
	if (*end != '\0') 
		return -1;

	return 0;
}

int str_to_mac(const char *str, unsigned char *mac)
{
	int rc = -1, m, i;
	char *s = strdup(str), *p, *d, tmp[3];

	if (!s)
		return -1;

	p = s;
	tmp[2] = '\0';
	for (i = 0; i < ETH_ALEN; ++i) {
		if (*p == '\0')
			goto out;

		d = strchr(p, ':');
		if (d) {
			*d = '\0';
			if (strlen(p) > 2)
				goto out;

			strcpy(tmp, p);
			p = d + 1;
		} else {
			strncpy(tmp, p, 2);
			p += 2;
		}
		
		if (str_to_int_base(tmp, 0, 0xFF, &m, 16) != 0)
			goto out;

		mac[i] = m;
	}

	if (*p == '\0')
		rc = 0;
out:
	free(s);

	return rc;
}

int get_ifidx(const char *arg)
{
	int idx;

	idx = if_nametoindex(arg);
	if (!idx)
		idx = strtoul(arg, NULL, 0);

	return idx;
}

/* find parameters in a string -- based on Harbison and Steele, p. 291 */
int parsestr(char *str, char *delims, char *fields[], int nmax)
{
	int n;

	if (!str || (*str == '\0'))
		return 0;

	n = 0;
	fields[0] = strtok(str, delims);
	while ((fields[n] != (char *) NULL) && (n < (nmax-1))) {
		++n;
		fields[n] = strtok(NULL, delims);
	}

	if ((n == (nmax - 1)) && (fields[n] != (char *) NULL))
		++n;

	return n;
}

void print_mac(const __u8 *mac, bool reverse)
{
	if (reverse)
		printf("%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
		       mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
	else
		printf("%.02x:%.02x:%.02x:%.02x:%.02x:%.02x",
		       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}