Make filtering customizable
authorSteven Barth <steven@midlink.org>
Fri, 30 May 2014 14:59:53 +0000 (16:59 +0200)
committerSteven Barth <steven@midlink.org>
Fri, 30 May 2014 14:59:53 +0000 (16:59 +0200)
src/config.c
src/dhcpv4.c
src/dhcpv6.c
src/odhcpd.h

index 6dd52bba70b6bdb7ade2fadb59c465f5cf6e14d8..db5ca3b1772f04d4318e5e81f5cd757e1483be7b 100644 (file)
@@ -32,6 +32,7 @@ enum {
        IFACE_ATTR_NDP,
        IFACE_ATTR_DNS,
        IFACE_ATTR_DOMAIN,
+       IFACE_ATTR_FILTER_CLASS,
        IFACE_ATTR_DHCPV6_RAW,
        IFACE_ATTR_RA_DEFAULT,
        IFACE_ATTR_RA_MANAGEMENT,
@@ -62,6 +63,7 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
        [IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY },
        [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY },
+       [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING },
        [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING },
@@ -152,6 +154,7 @@ static void clean_interface(struct interface *iface)
        free(iface->static_ndp);
        free(iface->dhcpv4_dns);
        free(iface->dhcpv6_raw);
+       free(iface->filter_class);
        memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra));
 }
 
@@ -457,6 +460,11 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
                }
        }
 
+       if ((c = tb[IFACE_ATTR_FILTER_CLASS])) {
+               iface->filter_class = realloc(iface->filter_class, blobmsg_data_len(c) + 1);
+               memcpy(iface->filter_class, blobmsg_get_string(c), blobmsg_data_len(c) + 1);
+       }
+
        if ((c = tb[IFACE_ATTR_DHCPV6_RAW])) {
                iface->dhcpv6_raw_len = blobmsg_data_len(c) / 2;
                iface->dhcpv6_raw = realloc(iface->dhcpv6_raw, iface->dhcpv6_raw_len);
index b8e0c95d8efcb27a175868043f632d844243f6b3..628efcdc335f5a30f8c6526abdccc2b747d0c2fa 100644 (file)
@@ -37,7 +37,6 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
 static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
                enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr,
                const char *hostname);
-static const char *excluded_class = "HOMENET";
 
 // Create socket and register events
 int init_dhcpv4(void)
@@ -294,11 +293,11 @@ static void handle_dhcpv4(void *addr, void *data, size_t len,
                } else if (opt->type == DHCPV4_OPT_SERVERID && opt->len == 4) {
                        if (memcmp(opt->data, &ifaddr.sin_addr, 4))
                                return;
-               } else if (opt->type == DHCPV4_OPT_USER_CLASS) {
+               } else if (iface->filter_class && opt->type == DHCPV4_OPT_USER_CLASS) {
                        uint8_t *c = opt->data, *cend = &opt->data[opt->len];
                        for (; c < cend && &c[*c] < cend; c = &c[1 + *c]) {
-                               size_t elen = strlen(excluded_class);
-                               if (*c == elen && !memcmp(&c[1], excluded_class, elen))
+                               size_t elen = strlen(iface->filter_class);
+                               if (*c == elen && !memcmp(&c[1], iface->filter_class, elen))
                                        return; // Ignore from homenet
                        }
                }
index 37dc3f5057a1b5f9d3d8ae3a3c61ae58a8c08328..aaefa5e4126764f30cf0636a7c94bcfad08c4688 100644 (file)
@@ -22,8 +22,6 @@
 #include "odhcpd.h"
 #include "dhcpv6.h"
 
-static const char *excluded_class = "HOMENET";
-
 
 static void relay_client_request(struct sockaddr_in6 *source,
                const void *data, size_t len, struct interface *iface);
@@ -293,11 +291,11 @@ static void handle_client_request(void *addr, void *data, size_t len,
                        if (olen != ntohs(dest.serverid_length) ||
                                        memcmp(odata, &dest.duid_type, olen))
                                return; // Not for us
-               } else if (otype == DHCPV6_OPT_USER_CLASS) {
+               } else if (iface->filter_class && otype == DHCPV6_OPT_USER_CLASS) {
                        uint8_t *c = odata, *cend = &odata[olen];
                        for (; &c[2] <= cend && &c[2 + (c[0] << 8) + c[1]] <= cend; c = &c[2 + (c[0] << 8) + c[1]]) {
-                               size_t elen = strlen(excluded_class);
-                               if (((((size_t)c[0]) << 8) | c[1]) == elen && !memcmp(&c[2], excluded_class, elen))
+                               size_t elen = strlen(iface->filter_class);
+                               if (((((size_t)c[0]) << 8) | c[1]) == elen && !memcmp(&c[2], iface->filter_class, elen))
                                        return; // Ignore from homenet
                        }
                } else if (otype == DHCPV6_OPT_IA_PD) {
index 64ffca2801999bd1c3e1a8b98e650ae383c3b218..dfaec9b2bc99edcbc2dc9cca205f61f1f6ac431a 100644 (file)
@@ -165,6 +165,8 @@ struct interface {
 
        char *upstream;
        size_t upstream_len;
+
+       char *filter_class;
 };
 
 extern struct list_head interfaces;