diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2020-10-26 22:52:27 +0100 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2020-10-31 21:13:56 +0100 |
commit | 57009197f6cbd9d79c919bcd3150c41a0f57c9b3 (patch) | |
tree | 64d12ffcf4a188018469ff6d6bce6e3c17db2c48 | |
parent | e4f4e620488cbda1c2e93316f952fc4454746d76 (diff) |
dhcpv6: add explicit dhcpv4o6 server address
Include the All_DHCP_Relay_Agents_and_Servers multicast address
in the option explicitly. It shouldn't be needed according
to RFC 7341 section 7.2 but ISC dhclient logs an error otherwise:
dhcp4-o-dhcp6-server: expecting at least 16 bytes; got 0
Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
-rw-r--r-- | src/dhcpv6.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/dhcpv6.c b/src/dhcpv6.c index cc068a3..00628cd 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -397,10 +397,12 @@ static void handle_client_request(void *addr, void *data, size_t len, } search = {htons(DHCPV6_OPT_DNS_DOMAIN), htons(search_len)}; - struct __attribute__((packed)) { + struct __attribute__((packed)) dhcpv4o6_server { uint16_t type; uint16_t len; - } dhcpv4o6_server = {htons(DHCPV6_OPT_4O6_SERVER), 0}; + struct in6_addr addr; + } dhcpv4o6_server = {htons(DHCPV6_OPT_4O6_SERVER), htons(sizeof(struct in6_addr)), + IN6ADDR_ANY_INIT}; struct dhcpv6_cer_id cerid = { #ifdef EXT_CER_ID @@ -505,11 +507,28 @@ static void handle_client_request(void *addr, void *data, size_t len, } else if (otype == DHCPV6_OPT_ORO) { for (int i=0; i < olen/2; i++) { uint16_t option = ntohs(((uint16_t *)odata)[i]); + switch (option) { #ifdef DHCPV4_SUPPORT case DHCPV6_OPT_4O6_SERVER: - if (iface->dhcpv4) + if (iface->dhcpv4) { + /* According to RFC 7341, 7.2. DHCP 4o6 Server Address Option Format: + * This option may also carry no IPv6 addresses, which instructs the + * client to use the All_DHCP_Relay_Agents_and_Servers multicast address + * as the destination address. + * + * The ISC dhclient logs a missing IPv6 address as an error but seems to + * work anyway: + * dhcp4-o-dhcp6-server: expecting at least 16 bytes; got 0 + * + * Include the All_DHCP_Relay_Agents_and_Servers multicast address + * to make it explicit which address to use. */ + struct dhcpv4o6_server *server = iov[IOV_DHCPV4O6_SERVER].iov_base; + + inet_pton(AF_INET6, ALL_DHCPV6_RELAYS, &server->addr); + iov[IOV_DHCPV4O6_SERVER].iov_len = sizeof(dhcpv4o6_server); + } break; #endif /* DHCPV4_SUPPORT */ default: |