From: Steven Barth Date: Sun, 25 May 2014 12:14:52 +0000 (+0200) Subject: Add support for raw DHCPv6 attributes X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=87b974a21add279ce7f7be31f7b22f7ea97949c3;p=oweals%2Fodhcpd.git Add support for raw DHCPv6 attributes --- diff --git a/src/config.c b/src/config.c index 4cde431..6dd52bb 100644 --- a/src/config.c +++ b/src/config.c @@ -32,6 +32,7 @@ enum { IFACE_ATTR_NDP, IFACE_ATTR_DNS, IFACE_ATTR_DOMAIN, + IFACE_ATTR_DHCPV6_RAW, IFACE_ATTR_RA_DEFAULT, IFACE_ATTR_RA_MANAGEMENT, IFACE_ATTR_RA_OFFLINK, @@ -61,6 +62,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_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 }, [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 }, @@ -149,6 +151,7 @@ static void clean_interface(struct interface *iface) free(iface->upstream); free(iface->static_ndp); free(iface->dhcpv4_dns); + free(iface->dhcpv6_raw); memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); } @@ -454,6 +457,12 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr } } + 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); + odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c)); + } + if ((c = tb[IFACE_ATTR_RA_DEFAULT])) iface->default_router = blobmsg_get_u32(c); diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 55b9ea9..37dc3f5 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -124,8 +124,8 @@ static void handle_nested_message(uint8_t *data, size_t len, uint8_t *odata; dhcpv6_for_each_option(hdr->options, data + len, otype, olen, odata) { if (otype == DHCPV6_OPT_RELAY_MSG) { - iov[8].iov_base = odata + olen; - iov[8].iov_len = (((uint8_t*)iov[0].iov_base) + iov[0].iov_len) + iov[9].iov_base = odata + olen; + iov[9].iov_len = (((uint8_t*)iov[0].iov_base) + iov[0].iov_len) - (odata + olen); handle_nested_message(odata, olen, opts, end, iov); return; @@ -262,6 +262,7 @@ static void handle_client_request(void *addr, void *data, size_t len, {search_domain, search_len}, {pdbuf, 0}, {&cerid, 0}, + {iface->dhcpv6_raw, iface->dhcpv6_raw_len}, {NULL, 0}}; uint8_t *opts = (uint8_t*)&hdr[1], *opts_end = (uint8_t*)data + len; diff --git a/src/odhcpd.h b/src/odhcpd.h index cf34938..6b90831 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -123,6 +123,8 @@ struct interface { // Managed PD char dhcpv6_pd_manager[128]; struct in6_addr dhcpv6_pd_cer; + void *dhcpv6_raw; + size_t dhcpv6_raw_len; // Services enum odhcpd_mode ra;