]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-server: also append specified additional options and vendor specific option...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 4 Mar 2021 08:51:25 +0000 (17:51 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 5 Mar 2021 02:34:32 +0000 (11:34 +0900)
Fixes #15780.

src/libsystemd-network/sd-dhcp-server.c

index d0e249b104b9cdedb0c495b456b10c9486090392..2b1384cff085ae78785ebd63a92289debf1b1029 100644 (file)
@@ -425,66 +425,23 @@ static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret,
         return 0;
 }
 
-static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
-                             be32_t address) {
-        _cleanup_free_ DHCPPacket *packet = NULL;
-        size_t offset;
-        be32_t lease_time;
-        int r;
-
-        r = server_message_init(server, &packet, DHCP_OFFER, &offset, req);
-        if (r < 0)
-                return r;
-
-        packet->dhcp.yiaddr = address;
-
-        lease_time = htobe32(req->lifetime);
-        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
-                               SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4,
-                               &lease_time);
-        if (r < 0)
-                return r;
-
-        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
-                               SD_DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
-        if (r < 0)
-                return r;
-
-        if (server->emit_router) {
-                r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
-                                       SD_DHCP_OPTION_ROUTER, 4, &server->address);
-                if (r < 0)
-                        return r;
-        }
-
-        r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-static int server_send_ack(
+static int server_send_offer_or_ack(
                 sd_dhcp_server *server,
                 DHCPRequest *req,
-                be32_t address) {
-
-        static const uint8_t option_map[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
-                [SD_DHCP_LEASE_DNS] = SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
-                [SD_DHCP_LEASE_NTP] = SD_DHCP_OPTION_NTP_SERVER,
-                [SD_DHCP_LEASE_SIP] = SD_DHCP_OPTION_SIP_SERVER,
-                [SD_DHCP_LEASE_POP3] = SD_DHCP_OPTION_POP3_SERVER,
-                [SD_DHCP_LEASE_SMTP] = SD_DHCP_OPTION_SMTP_SERVER,
-                [SD_DHCP_LEASE_LPR] = SD_DHCP_OPTION_LPR_SERVER,
-        };
+                be32_t address,
+                uint8_t type) {
 
         _cleanup_free_ DHCPPacket *packet = NULL;
-        be32_t lease_time;
         sd_dhcp_option *j;
+        be32_t lease_time;
         size_t offset;
         int r;
 
-        r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
+        assert(server);
+        assert(req);
+        assert(IN_SET(type, DHCP_OFFER, DHCP_ACK));
+
+        r = server_message_init(server, &packet, type, &offset, req);
         if (r < 0)
                 return r;
 
@@ -509,27 +466,38 @@ static int server_send_ack(
                         return r;
         }
 
-        for (sd_dhcp_lease_server_type_t k = 0; k < _SD_DHCP_LEASE_SERVER_TYPE_MAX; k++) {
-
-                if (server->servers[k].size <= 0)
-                        continue;
-
-                r = dhcp_option_append(
-                                &packet->dhcp, req->max_optlen, &offset, 0,
-                                option_map[k],
-                                sizeof(struct in_addr) * server->servers[k].size, server->servers[k].addr);
-                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,
+                        [SD_DHCP_LEASE_NTP] = SD_DHCP_OPTION_NTP_SERVER,
+                        [SD_DHCP_LEASE_SIP] = SD_DHCP_OPTION_SIP_SERVER,
+                        [SD_DHCP_LEASE_POP3] = SD_DHCP_OPTION_POP3_SERVER,
+                        [SD_DHCP_LEASE_SMTP] = SD_DHCP_OPTION_SMTP_SERVER,
+                        [SD_DHCP_LEASE_LPR] = SD_DHCP_OPTION_LPR_SERVER,
+                };
+
+                for (sd_dhcp_lease_server_type_t k = 0; k < _SD_DHCP_LEASE_SERVER_TYPE_MAX; k++) {
+                        if (server->servers[k].size <= 0)
+                                continue;
+
+                        r = dhcp_option_append(
+                                        &packet->dhcp, req->max_optlen, &offset, 0,
+                                        option_map[k],
+                                        sizeof(struct in_addr) * server->servers[k].size,
+                                        server->servers[k].addr);
+                        if (r < 0)
+                                return r;
+                }
 
 
-        if (server->timezone) {
-                r = dhcp_option_append(
-                                &packet->dhcp, req->max_optlen, &offset, 0,
-                                SD_DHCP_OPTION_NEW_TZDB_TIMEZONE,
-                                strlen(server->timezone), server->timezone);
-                if (r < 0)
-                        return r;
+                if (server->timezone) {
+                        r = dhcp_option_append(
+                                        &packet->dhcp, req->max_optlen, &offset, 0,
+                                        SD_DHCP_OPTION_NEW_TZDB_TIMEZONE,
+                                        strlen(server->timezone), server->timezone);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         ORDERED_SET_FOREACH(j, server->extra_options) {
@@ -548,7 +516,7 @@ static int server_send_ack(
                         return r;
         }
 
-        r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
+        r = dhcp_server_send_packet(server, req, packet, type, offset);
         if (r < 0)
                 return r;
 
@@ -783,7 +751,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
                         /* no free addresses left */
                         return 0;
 
-                r = server_send_offer(server, req, address);
+                r = server_send_offer_or_ack(server, req, address, DHCP_OFFER);
                 if (r < 0)
                         /* this only fails on critical errors */
                         return log_dhcp_server_errno(server, r, "Could not send offer: %m");
@@ -886,7 +854,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
 
                         lease->expiration = req->lifetime * USEC_PER_SEC + time_now;
 
-                        r = server_send_ack(server, req, address);
+                        r = server_send_offer_or_ack(server, req, address, DHCP_ACK);
                         if (r < 0) {
                                 /* this only fails on critical errors */
                                 log_dhcp_server_errno(server, r, "Could not send ack: %m");