From: Yu Watanabe Date: Thu, 4 Mar 2021 08:51:25 +0000 (+0900) Subject: dhcp-server: also append specified additional options and vendor specific option... X-Git-Tag: v248-rc3~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=986c0edfcb9f69160658fd8a88cb72f0d7d208d3;p=thirdparty%2Fsystemd.git dhcp-server: also append specified additional options and vendor specific option on DHCP_OFFER Fixes #15780. --- diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index d0e249b104b..2b1384cff08 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -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");