return 0;
}
+static bool dhcp_request_contains(DHCPRequest *req, uint8_t option) {
+ assert(req);
+
+ if (!req->parameter_request_list)
+ return false;
+
+ return memchr(req->parameter_request_list, option, req->parameter_request_list_len);
+}
+
static int dhcp_server_send_unicast_raw(
sd_dhcp_server *server,
uint8_t hlen,
return r;
}
+ /* RFC 8925 section 3.3. DHCPv4 Server Behavior
+ * The server MUST NOT include the IPv6-Only Preferred option in the DHCPOFFER or DHCPACK message if
+ * the option was not present in the Parameter Request List sent by the client. */
+ if (dhcp_request_contains(req, SD_DHCP_OPTION_IPV6_ONLY_PREFERRED) &&
+ server->ipv6_only_preferred_usec > 0) {
+ be32_t sec = usec_to_be32_sec(server->ipv6_only_preferred_usec);
+
+ r = dhcp_option_append(
+ &packet->dhcp, req->max_optlen, &offset, 0,
+ SD_DHCP_OPTION_IPV6_ONLY_PREFERRED,
+ sizeof(sec), &sec);
+ if (r < 0)
+ return r;
+ }
+
ORDERED_SET_FOREACH(j, server->extra_options) {
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
j->option, j->length, j->data);
return 0;
}
+ break;
+ case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
+ req->parameter_request_list = option;
+ req->parameter_request_list_len = len;
break;
}
return 0;
}
+int sd_dhcp_server_set_ipv6_only_preferred_usec(sd_dhcp_server *server, uint64_t t) {
+ assert_return(server, -EINVAL);
+
+ /* When 0 is set, disables the IPv6 only mode. */
+
+ /* Refuse too short timespan unless test mode is enabled. */
+ if (t > 0 && t < MIN_V6ONLY_WAIT_USEC && !network_test_mode_enabled())
+ return -EINVAL;
+
+ server->ipv6_only_preferred_usec = t;
+ return 0;
+}
+
int sd_dhcp_server_set_servers(
sd_dhcp_server *server,
sd_dhcp_lease_server_type_t what,