]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-server: add support to send next server and filename option for PXE boot...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Feb 2022 17:32:58 +0000 (02:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Feb 2022 17:32:58 +0000 (02:32 +0900)
src/libsystemd-network/dhcp-server-internal.h
src/libsystemd-network/sd-dhcp-server.c
src/systemd/sd-dhcp-client.h
src/systemd/sd-dhcp-server.h

index 51510b9d22e61964b5c8395f3742ea95c9576776..bb41ad2c3dcaa79b9a641aaafd758a8fa25c67c3 100644 (file)
@@ -65,6 +65,8 @@ struct sd_dhcp_server {
         char *timezone;
 
         DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
+        struct in_addr next_server;
+        char *filename;
 
         OrderedSet *extra_options;
         OrderedSet *vendor_options;
index 81dc4ff95049d2bde0291e138cc0706452ae8e0c..1636b838e14bb7abd7dbaddbd53d4dd7e72c9f6c 100644 (file)
@@ -21,6 +21,7 @@
 #include "siphash24.h"
 #include "string-util.h"
 #include "unaligned.h"
+#include "utf8.h"
 
 #define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
 #define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
@@ -162,6 +163,7 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
 
         sd_event_unref(server->event);
 
+        free(server->filename);
         free(server->timezone);
 
         for (sd_dhcp_lease_server_type_t i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
@@ -270,6 +272,26 @@ sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
         return server->event;
 }
 
+int sd_dhcp_server_set_next_server(sd_dhcp_server *server, const struct in_addr *next_server) {
+        assert_return(server, -EINVAL);
+
+        if (next_server)
+                server->next_server = *next_server;
+        else
+                server->next_server = (struct in_addr) {};
+
+        return 0;
+}
+
+int sd_dhcp_server_set_filename(sd_dhcp_server *server, const char *filename) {
+        assert_return(server, -EINVAL);
+
+        if (filename && !ascii_is_valid(filename))
+                return -EINVAL;
+
+        return free_and_strdup(&server->filename, filename);
+}
+
 int sd_dhcp_server_stop(sd_dhcp_server *server) {
         bool running;
 
@@ -539,6 +561,7 @@ static int server_send_offer_or_ack(
                 return r;
 
         packet->dhcp.yiaddr = address;
+        packet->dhcp.siaddr = server->next_server.s_addr;
 
         lease_time = htobe32(req->lifetime);
         r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
@@ -562,6 +585,22 @@ static int server_send_offer_or_ack(
                         return r;
         }
 
+        if (server->filename) {
+                /* The pxelinux magic option is marked as deprecated, but let's append it for older
+                 * implementations. */
+                r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                                       SD_DHCP_OPTION_PXELINUX_MAGIC, 4,
+                                       (const uint8_t[]) { 0xf1, 0x00, 0x74, 0x7e });
+                if (r < 0)
+                        return r;
+
+                r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                                       SD_DHCP_OPTION_CONFIGURATION_FILE,
+                                       strlen(server->filename), server->filename);
+                if (r < 0)
+                        return r;
+        }
+
         if (type == DHCP_ACK) {
                 static const uint8_t option_map[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
                         [SD_DHCP_LEASE_DNS] = SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
index 4af4b45f2d4cf4829ea2d9409e63b7e9098b0ad4..78d68addf45152a213095bb8b6c270fb992ae401 100644 (file)
@@ -97,6 +97,10 @@ enum {
         SD_DHCP_OPTION_SIP_SERVER                     = 120,
         SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE         = 121,
         SD_DHCP_OPTION_MUD_URL                        = 161,
+        SD_DHCP_OPTION_PXELINUX_MAGIC                 = 208, /* deprecated */
+        SD_DHCP_OPTION_CONFIGURATION_FILE             = 209,
+        SD_DHCP_OPTION_PATH_PREFIX                    = 210,
+        SD_DHCP_OPTION_REBOOT_TIME                    = 211,
         SD_DHCP_OPTION_6RD                            = 212,
         SD_DHCP_OPTION_PRIVATE_BASE                   = 224,
         /* Windows 10 option to send when Anonymize=true */
index 59ef27e1dcdb3a04247aefbddd3de41fa7f021f1..af7c3b68f3efbae63d28fb96e2797247d46cea31 100644 (file)
@@ -58,6 +58,8 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
 
 int sd_dhcp_server_configure_pool(sd_dhcp_server *server, const struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size);
 
+int sd_dhcp_server_set_next_server(sd_dhcp_server *server, const struct in_addr *next_server);
+int sd_dhcp_server_set_filename(sd_dhcp_server *server, const char *filename);
 int sd_dhcp_server_set_bind_to_interface(sd_dhcp_server *server, int enabled);
 int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
 int sd_dhcp_server_set_router(sd_dhcp_server *server, const struct in_addr *address);