odhcpd: add a helper function for addr6/prefix parsing
authorDavid Härdeman <[email protected]>
Sat, 10 Feb 2024 02:02:28 +0000 (03:02 +0100)
committerdedeckeh <[email protected]>
Mon, 30 Dec 2024 19:44:26 +0000 (20:44 +0100)
Which allows a couple of variations of the same code to be removed...
the helper function also won't modify the input string.

Signed-off-by: David Härdeman <[email protected]>
src/config.c
src/dhcpv6-ia.c
src/odhcpd.c
src/odhcpd.h

index 78dd0a2865fde4f09a60c4d692811dd6272ad4d2..e816f4b3e3499ca4f4126c5c309588cd4f863b78 100644 (file)
@@ -1314,23 +1314,10 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
                }
        }
 
-       if ((c = tb[IFACE_ATTR_RA_PREF64])) {
-               const char *str = blobmsg_get_string(c);
-               char *astr = malloc(strlen(str) + 1);
-               char *delim;
-               int l;
-
-               if (!astr || !strcpy(astr, str) ||
-                               (delim = strchr(astr, '/')) == NULL || (*(delim++) = 0) ||
-                               sscanf(delim, "%i", &l) == 0 || l > 128 ||
-                               inet_pton(AF_INET6, astr, &iface->pref64_addr) == 0)
-                       iface->pref64_length = 0;
-               else
-                       iface->pref64_length = l;
-
-               if (astr)
-                       free(astr);
-       }
+       if ((c = tb[IFACE_ATTR_RA_PREF64]))
+               odhcpd_parse_addr6_prefix(blobmsg_get_string(c),
+                                         &iface->pref64_addr,
+                                         &iface->pref64_length);
 
        if ((c = tb[IFACE_ATTR_RA_PREFERENCE])) {
                const char *prio = blobmsg_get_string(c);
@@ -1361,23 +1348,10 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
        if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE]))
                iface->external = blobmsg_get_bool(c);
 
-       if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) {
-               const char *str = blobmsg_get_string(c);
-               char *astr = malloc(strlen(str) + 1);
-               char *delim;
-               int l;
-
-               if (!astr || !strcpy(astr, str) ||
-                               (delim = strchr(astr, '/')) == NULL || (*(delim++) = 0) ||
-                               sscanf(delim, "%i", &l) == 0 || l > 128 ||
-                               inet_pton(AF_INET6, astr, &iface->pio_filter_addr) == 0)
-                       iface->pio_filter_length = 0;
-               else
-                       iface->pio_filter_length = l;
-
-               if (astr)
-                       free(astr);
-       }
+       if ((c = tb[IFACE_ATTR_PREFIX_FILTER]))
+               odhcpd_parse_addr6_prefix(blobmsg_get_string(c),
+                                         &iface->pio_filter_addr,
+                                         &iface->pio_filter_length);
 
        if (overwrite && (c = tb[IFACE_ATTR_NTP])) {
                struct blob_attr *cur;
index dde224d9808164ae6755df50f5c391522fa6b0ac..b4ed9a059f2495886c48f59b81892094e412f9e8 100644 (file)
@@ -666,15 +666,17 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new)
 
                char *saveptr;
                for (char *line = strtok_r(data, "\n", &saveptr); line; line = strtok_r(NULL, "\n", &saveptr)) {
-                       c->managed = realloc(c->managed, (c->managed_size + 1) * sizeof(*c->managed));
-                       struct odhcpd_ipaddr *n = &c->managed[c->managed_size];
+                       struct odhcpd_ipaddr *n;
+                       char *saveptr2, *x;
 
-                       char *saveptr2, *x = strtok_r(line, "/", &saveptr2);
-                       if (!x || inet_pton(AF_INET6, x, &n->addr) < 1)
+                       n = realloc(c->managed, (c->managed_size + 1) * sizeof(*c->managed));
+                       if (!n)
                                continue;
+                       c->managed = n;
+                       n = &c->managed[c->managed_size];
 
-                       x = strtok_r(NULL, ",", &saveptr2);
-                       if (sscanf(x, "%hhu", &n->prefix) < 1)
+                       x = strtok_r(line, ",", &saveptr2);
+                       if (odhcpd_parse_addr6_prefix(x, &n->addr.in6, &n->prefix))
                                continue;
 
                        x = strtok_r(NULL, ",", &saveptr2);
index 0849b4343577bc1ba6856eb642e5f7fe23e8b8c8..7b6420ce75725fbb78cde79d9fc90775bda537ed 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdbool.h>
 #include <syslog.h>
 #include <alloca.h>
+#include <inttypes.h>
 
 #include <arpa/inet.h>
 #include <net/if.h>
@@ -539,6 +540,39 @@ void odhcpd_bmemcpy(void *av, const void *bv, size_t bits)
 }
 
 
+int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix)
+{
+       size_t len;
+       char *delim;
+
+       *prefix = 0;
+       if (!str)
+               return -1;
+
+       len = strlen(str);
+
+       char buf[len + 1];
+       memcpy(buf, str, len);
+       buf[len] = '\0';
+
+       delim = memchr(buf, '/', len);
+       if (!delim)
+               return -1;
+
+       *(delim++) = '\0';
+
+       if (inet_pton(AF_INET6, buf, addr) != 1)
+               return -1;
+
+       if (sscanf(delim, "%" SCNu8, prefix) != 1 || *prefix > 128) {
+               *prefix = 0;
+               return -1;
+       }
+
+       return 0;
+}
+
+
 int odhcpd_netmask2bitlen(bool inet6, void *mask)
 {
        int bits;
index 4d589f8e2e177001fa1f7826957f480d2794e971..61fb64c54a0f89f2e88c2e563838011560dff829 100644 (file)
@@ -453,6 +453,7 @@ const char *odhcpd_print_mac(const uint8_t *mac, const size_t len);
 int odhcpd_bmemcmp(const void *av, const void *bv, size_t bits);
 void odhcpd_bmemcpy(void *av, const void *bv, size_t bits);
 
+int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix);
 int odhcpd_netmask2bitlen(bool v6, void *mask);
 bool odhcpd_bitlen2netmask(bool v6, unsigned int bits, void *mask);
 bool odhcpd_valid_hostname(const char *name);