diff options
| author | Roy Marples <roy@marples.name> | 2018-04-17 11:36:32 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2018-04-17 11:36:32 +0100 |
| commit | 86214d2958b9fccbf4e99c73c937fc7e1498f29f (patch) | |
| tree | 6003e89f52c8b4346cafebb79eedf08a75c657b9 | |
| parent | cd3ab837c5449d6638eae9bd686dee513a47b677 (diff) | |
| download | dhcpcd-86214d2958b9fccbf4e99c73c937fc7e1498f29f.tar.xz | |
DHCPv6: Transpose DHCP userclass option into DHCPv6
| -rw-r--r-- | src/dhcp6.c | 46 | ||||
| -rw-r--r-- | src/dhcp6.h | 1 |
2 files changed, 47 insertions, 0 deletions
diff --git a/src/dhcp6.c b/src/dhcp6.c index 89f71d79..e03b156c 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -194,6 +194,48 @@ dhcp6_printoptions(const struct dhcpcd_ctx *ctx, } static size_t +dhcp6_makeuser(void *data, const struct interface *ifp) +{ + const struct if_options *ifo = ifp->options; + struct dhcp6_option o; + uint8_t *p; + const uint8_t *up, *ue; + uint16_t ulen, unlen; + size_t olen; + + /* Convert the DHCPv4 user class option to DHCPv6 */ + up = ifo->userclass; + ulen = *up++; + if (ulen == 0) + return 0; + + p = data; + olen = 0; + if (p != NULL) + p += sizeof(o); + + ue = up + ulen; + for (; up < ue; up += ulen) { + ulen = *up++; + olen += sizeof(ulen) + ulen; + if (data == NULL) + continue; + unlen = htons(ulen); + memcpy(p, &unlen, sizeof(unlen)); + p += sizeof(unlen); + memcpy(p, up, ulen); + p += ulen; + } + if (data != NULL) { + o.code = htons(D6_OPTION_USER_CLASS); + o.len = htons(olen); + memcpy(data, &o, sizeof(o)); + } + + return sizeof(o) + olen; +} + +static size_t dhcp6_makevendor(void *data, const struct interface *ifp) { const struct if_options *ifo; @@ -677,6 +719,8 @@ dhcp6_makemessage(struct interface *ifp) len += sizeof(*state->send); len += sizeof(o) + ifp->ctx->duid_len; len += sizeof(o) + sizeof(uint16_t); /* elapsed */ + if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS)) + len += dhcp6_makeuser(NULL, ifp); if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS)) len += dhcp6_makevendor(NULL, ifp); @@ -844,6 +888,8 @@ dhcp6_makemessage(struct interface *ifp) si_len = 0; COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len)); + if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS)) + p += dhcp6_makeuser(p, ifp); if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS)) p += dhcp6_makevendor(p, ifp); diff --git a/src/dhcp6.h b/src/dhcp6.h index 50b7c9e8..f9f8c403 100644 --- a/src/dhcp6.h +++ b/src/dhcp6.h @@ -67,6 +67,7 @@ #define D6_OPTION_UNICAST 12 #define D6_OPTION_STATUS_CODE 13 #define D6_OPTION_RAPID_COMMIT 14 +#define D6_OPTION_USER_CLASS 15 #define D6_OPTION_VENDOR_CLASS 16 #define D6_OPTION_VENDOR_OPTS 17 #define D6_OPTION_INTERFACE_ID 18 |
