}
}
- 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);
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;
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);
#include <stdbool.h>
#include <syslog.h>
#include <alloca.h>
+#include <inttypes.h>
#include <arpa/inet.h>
#include <net/if.h>
}
+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;
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);