summaryrefslogtreecommitdiffhomepage
path: root/src/dhcpv6.c
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2020-10-26 22:52:27 +0100
committerHans Dedecker <dedeckeh@gmail.com>2020-10-31 21:13:56 +0100
commit57009197f6cbd9d79c919bcd3150c41a0f57c9b3 (patch)
tree64d12ffcf4a188018469ff6d6bce6e3c17db2c48 /src/dhcpv6.c
parente4f4e620488cbda1c2e93316f952fc4454746d76 (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>
Diffstat (limited to 'src/dhcpv6.c')
-rw-r--r--src/dhcpv6.c25
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: