diff options
Diffstat (limited to 'src/bpfswitch/usrc/str_utils.c')
-rw-r--r-- | src/bpfswitch/usrc/str_utils.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/bpfswitch/usrc/str_utils.c b/src/bpfswitch/usrc/str_utils.c new file mode 100644 index 00000000..8650cdfb --- /dev/null +++ b/src/bpfswitch/usrc/str_utils.c @@ -0,0 +1,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]); +} |