aboutsummaryrefslogtreecommitdiffstats
path: root/src/bpfswitch/usrc/str_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bpfswitch/usrc/str_utils.c')
-rw-r--r--src/bpfswitch/usrc/str_utils.c159
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]);
+}