From 171140e90b6a6a8e0c9e8e12dc5cbd4cbe972bef Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Sat, 10 Feb 2024 03:02:28 +0100 Subject: [PATCH] odhcpd: add a helper function for addr6/prefix parsing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/config.c | 42 ++++++++---------------------------------- src/dhcpv6-ia.c | 14 ++++++++------ src/odhcpd.c | 34 ++++++++++++++++++++++++++++++++++ src/odhcpd.h | 1 + 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/config.c b/src/config.c index 78dd0a2..e816f4b 100644 --- a/src/config.c +++ b/src/config.c @@ -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; diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index dde224d..b4ed9a0 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -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); diff --git a/src/odhcpd.c b/src/odhcpd.c index 0849b43..7b6420c 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/src/odhcpd.h b/src/odhcpd.h index 4d589f8..61fb64c 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -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); -- 2.30.2