/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
  Copyright © 2013 Intel Corporation. All rights reserved.
***/

#include <net/if_arp.h>
#include <sys/ioctl.h>

#include "sd-dhcp-server.h"
#include "sd-id128.h"

#include "alloc-util.h"
#include "dhcp-internal.h"
#include "dhcp-server-internal.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "io-util.h"
#include "network-common.h"
#include "ordered-set.h"
#include "siphash24.h"
#include "string-util.h"
#include "unaligned.h"

#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)

static DHCPLease *dhcp_lease_free(DHCPLease *lease) {
        if (!lease)
                return NULL;

        free(lease->client_id.data);
        return mfree(lease);
}

DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPLease*, dhcp_lease_free);

/* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
 * the whole pool must fit into the subnet, and may not contain the first (any) nor last (broadcast) address
 * moreover, the server's own address may be in the pool, and is in that case reserved in order not to
 * accidentally hand it out */
int sd_dhcp_server_configure_pool(
                sd_dhcp_server *server,
                const struct in_addr *address,
                unsigned char prefixlen,
                uint32_t offset,
                uint32_t size) {

        struct in_addr netmask_addr;
        be32_t netmask;
        uint32_t server_off, broadcast_off, size_max;

        assert_return(server, -EINVAL);
        assert_return(address, -EINVAL);
        assert_return(address->s_addr != INADDR_ANY, -EINVAL);
        assert_return(prefixlen <= 32, -ERANGE);

        assert_se(in4_addr_prefixlen_to_netmask(&netmask_addr, prefixlen));
        netmask = netmask_addr.s_addr;

        server_off = be32toh(address->s_addr & ~netmask);
        broadcast_off = be32toh(~netmask);

        /* the server address cannot be the subnet address */
        assert_return(server_off != 0, -ERANGE);

        /* nor the broadcast address */
        assert_return(server_off != broadcast_off, -ERANGE);

        /* 0 offset means we should set a default, we skip the first (subnet) address
           and take the next one */
        if (offset == 0)
                offset = 1;

        size_max = (broadcast_off + 1) /* the number of addresses in the subnet */
                   - offset /* exclude the addresses before the offset */
                   - 1; /* exclude the last (broadcast) address */

        /* The pool must contain at least one address */
        assert_return(size_max >= 1, -ERANGE);

        if (size != 0)
                assert_return(size <= size_max, -ERANGE);
        else
                size = size_max;

        if (server->address != address->s_addr || server->netmask != netmask || server->pool_size != size || server->pool_offset != offset) {

                free(server->bound_leases);
                server->bound_leases = new0(DHCPLease*, size);
                if (!server->bound_leases)
                        return -ENOMEM;

                server->pool_offset = offset;
                server->pool_size = size;

                server->address = address->s_addr;
                server->netmask = netmask;
                server->subnet = address->s_addr & netmask;

                if (server_off >= offset && server_off - offset < size)
                        server->bound_leases[server_off - offset] = &server->invalid_lease;

                /* Drop any leases associated with the old address range */
                hashmap_clear(server->leases_by_client_id);

                if (server->callback)
                        server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
        }

        return 0;
}

int sd_dhcp_server_is_running(sd_dhcp_server *server) {
        assert_return(server, false);

        return !!server->receive_message;
}

int sd_dhcp_server_is_in_relay_mode(sd_dhcp_server *server) {
        assert_return(server, -EINVAL);

        return in4_addr_is_set(&server->relay_target);
}

void client_id_hash_func(const DHCPClientId *id, struct siphash *state) {
        assert(id);
        assert(id->length);
        assert(id->data);

        siphash24_compress(&id->length, sizeof(id->length), state);
        siphash24_compress(id->data, id->length, state);
}

int client_id_compare_func(const DHCPClientId *a, const DHCPClientId *b) {
        int r;

        assert(!a->length || a->data);
        assert(!b->length || b->data);

        r = CMP(a->length, b->length);
        if (r != 0)
                return r;

        return memcmp(a->data, b->data, a->length);
}

DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(dhcp_lease_hash_ops, DHCPClientId, client_id_hash_func, client_id_compare_func,
                                              DHCPLease, dhcp_lease_free);

static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
        assert(server);

        log_dhcp_server(server, "UNREF");

        sd_dhcp_server_stop(server);

        sd_event_unref(server->event);

        free(server->timezone);

        for (sd_dhcp_lease_server_type_t i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
                free(server->servers[i].addr);

        hashmap_free(server->leases_by_client_id);
        hashmap_free(server->static_leases_by_client_id);

        ordered_set_free(server->extra_options);
        ordered_set_free(server->vendor_options);

        free(server->agent_circuit_id);
        free(server->agent_remote_id);

        free(server->bound_leases);

        free(server->ifname);
        return mfree(server);
}

DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_server, sd_dhcp_server, dhcp_server_free);

int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
        _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;

        assert_return(ret, -EINVAL);
        assert_return(ifindex > 0, -EINVAL);

        server = new(sd_dhcp_server, 1);
        if (!server)
                return -ENOMEM;

        *server = (sd_dhcp_server) {
                .n_ref = 1,
                .fd_raw = -1,
                .fd = -1,
                .fd_broadcast = -1,
                .address = htobe32(INADDR_ANY),
                .netmask = htobe32(INADDR_ANY),
                .ifindex = ifindex,
                .bind_to_interface = true,
                .default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC),
                .max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC),
        };

        server->leases_by_client_id = hashmap_new(&dhcp_lease_hash_ops);
        if (!server->leases_by_client_id)
                return -ENOMEM;
        server->static_leases_by_client_id = hashmap_new(&dhcp_lease_hash_ops);
        if (!server->static_leases_by_client_id)
                return -ENOMEM;

        *ret = TAKE_PTR(server);

        return 0;
}

int sd_dhcp_server_set_ifname(sd_dhcp_server *server, const char *ifname) {
        assert_return(server, -EINVAL);
        assert_return(ifname, -EINVAL);

        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
                return -EINVAL;

        return free_and_strdup(&server->ifname, ifname);
}

const char *sd_dhcp_server_get_ifname(sd_dhcp_server *server) {
        if (!server)
                return NULL;

        return get_ifname(server->ifindex, &server->ifname);
}

int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event, int64_t priority) {
        int r;

        assert_return(server, -EINVAL);
        assert_return(!server->event, -EBUSY);

        if (event)
                server->event = sd_event_ref(event);
        else {
                r = sd_event_default(&server->event);
                if (r < 0)
                        return r;
        }

        server->event_priority = priority;

        return 0;
}

int sd_dhcp_server_detach_event(sd_dhcp_server *server) {
        assert_return(server, -EINVAL);

        server->event = sd_event_unref(server->event);

        return 0;
}

sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
        assert_return(server, NULL);

        return server->event;
}

int sd_dhcp_server_stop(sd_dhcp_server *server) {
        if (!server)
                return 0;

        server->receive_message = sd_event_source_disable_unref(server->receive_message);
        server->receive_broadcast = sd_event_source_disable_unref(server->receive_broadcast);

        server->fd_raw = safe_close(server->fd_raw);
        server->fd = safe_close(server->fd);
        server->fd_broadcast = safe_close(server->fd_broadcast);

        log_dhcp_server(server, "STOPPED");

        return 0;
}

static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
                                        DHCPPacket *packet, size_t len) {
        union sockaddr_union link = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_protocol = htobe16(ETH_P_IP),
                .ll.sll_ifindex = server->ifindex,
                .ll.sll_halen = ETH_ALEN,
        };

        assert(server);
        assert(server->ifindex > 0);
        assert(server->address);
        assert(packet);
        assert(len > sizeof(DHCPPacket));

        memcpy(&link.ll.sll_addr, &packet->dhcp.chaddr, ETH_ALEN);

        if (len > UINT16_MAX)
                return -EOVERFLOW;

        dhcp_packet_append_ip_headers(packet, server->address, DHCP_PORT_SERVER,
                                      packet->dhcp.yiaddr,
                                      DHCP_PORT_CLIENT, len, -1);

        return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
}

static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
                                uint16_t destination_port,
                                DHCPMessage *message, size_t len) {
        union sockaddr_union dest = {
                .in.sin_family = AF_INET,
                .in.sin_port = htobe16(destination_port),
                .in.sin_addr.s_addr = destination,
        };
        struct iovec iov = {
                .iov_base = message,
                .iov_len = len,
        };
        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {};
        struct msghdr msg = {
                .msg_name = &dest,
                .msg_namelen = sizeof(dest.in),
                .msg_iov = &iov,
                .msg_iovlen = 1,
        };
        struct cmsghdr *cmsg;
        struct in_pktinfo *pktinfo;

        assert(server);
        assert(server->fd >= 0);
        assert(message);
        assert(len > sizeof(DHCPMessage));

        if (server->bind_to_interface) {
                msg.msg_control = &control;
                msg.msg_controllen = sizeof(control);

                cmsg = CMSG_FIRSTHDR(&msg);
                assert(cmsg);

                cmsg->cmsg_level = IPPROTO_IP;
                cmsg->cmsg_type = IP_PKTINFO;
                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));

                /* we attach source interface and address info to the message
                   rather than binding the socket. This will be mostly useful
                   when we gain support for arbitrary number of server addresses
                 */
                pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg);
                assert(pktinfo);

                pktinfo->ipi_ifindex = server->ifindex;
                pktinfo->ipi_spec_dst.s_addr = server->address;
        }

        if (sendmsg(server->fd, &msg, 0) < 0)
                return -errno;

        return 0;
}

static bool requested_broadcast(DHCPMessage *message) {
        assert(message);
        return message->flags & htobe16(0x8000);
}

static int dhcp_server_send(sd_dhcp_server *server, be32_t destination, uint16_t destination_port,
                            DHCPPacket *packet, size_t optoffset, bool l2_broadcast) {
        if (destination != INADDR_ANY)
                return dhcp_server_send_udp(server, destination,
                                            destination_port, &packet->dhcp,
                                            sizeof(DHCPMessage) + optoffset);
        else if (l2_broadcast)
                return dhcp_server_send_udp(server, INADDR_BROADCAST,
                                            destination_port, &packet->dhcp,
                                            sizeof(DHCPMessage) + optoffset);
        else
                /* we cannot send UDP packet to specific MAC address when the
                   address is not yet configured, so must fall back to raw
                   packets */
                return dhcp_server_send_unicast_raw(server, packet,
                                                    sizeof(DHCPPacket) + optoffset);
}

int dhcp_server_send_packet(sd_dhcp_server *server,
                            DHCPRequest *req, DHCPPacket *packet,
                            int type, size_t optoffset) {
        be32_t destination = INADDR_ANY;
        uint16_t destination_port = DHCP_PORT_CLIENT;
        int r;

        assert(server);
        assert(req);
        assert(req->max_optlen);
        assert(req->message);
        assert(optoffset <= req->max_optlen);
        assert(packet);

        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
                               SD_DHCP_OPTION_SERVER_IDENTIFIER,
                               4, &server->address);
        if (r < 0)
                return r;

        if (req->agent_info_option) {
                size_t opt_full_length = *(req->agent_info_option + 1) + 2;
                /* there must be space left for SD_DHCP_OPTION_END */
                if (optoffset + opt_full_length < req->max_optlen) {
                        memcpy(packet->dhcp.options + optoffset, req->agent_info_option, opt_full_length);
                        optoffset += opt_full_length;
                }
        }

        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
                               SD_DHCP_OPTION_END, 0, NULL);
        if (r < 0)
                return r;

        /* RFC 2131 Section 4.1

           If the ’giaddr’ field in a DHCP message from a client is non-zero,
           the server sends any return messages to the ’DHCP server’ port on the
           BOOTP relay agent whose address appears in ’giaddr’. If the ’giaddr’
           field is zero and the ’ciaddr’ field is nonzero, then the server
           unicasts DHCPOFFER and DHCPACK messages to the address in ’ciaddr’.
           If ’giaddr’ is zero and ’ciaddr’ is zero, and the broadcast bit is
           set, then the server broadcasts DHCPOFFER and DHCPACK messages to
           0xffffffff. If the broadcast bit is not set and ’giaddr’ is zero and
           ’ciaddr’ is zero, then the server unicasts DHCPOFFER and DHCPACK
           messages to the client’s hardware address and ’yiaddr’ address. In
           all cases, when ’giaddr’ is zero, the server broadcasts any DHCPNAK
           messages to 0xffffffff.

           Section 4.3.2

           If ’giaddr’ is set in the DHCPREQUEST message, the client is on a
           different subnet. The server MUST set the broadcast bit in the
           DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
           client, because the client may not have a correct network address
           or subnet mask, and the client may not be answering ARP requests.
         */
        if (req->message->giaddr) {
                destination = req->message->giaddr;
                destination_port = DHCP_PORT_SERVER;
                if (type == DHCP_NAK)
                        packet->dhcp.flags = htobe16(0x8000);
        } else if (req->message->ciaddr && type != DHCP_NAK)
                destination = req->message->ciaddr;

        bool l2_broadcast = requested_broadcast(req->message) || type == DHCP_NAK;
        return dhcp_server_send(server, destination, destination_port, packet, optoffset, l2_broadcast);
}

static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret,
                               uint8_t type, size_t *_optoffset,
                               DHCPRequest *req) {
        _cleanup_free_ DHCPPacket *packet = NULL;
        size_t optoffset = 0;
        int r;

        assert(server);
        assert(ret);
        assert(_optoffset);
        assert(IN_SET(type, DHCP_OFFER, DHCP_ACK, DHCP_NAK));

        packet = malloc0(sizeof(DHCPPacket) + req->max_optlen);
        if (!packet)
                return -ENOMEM;

        r = dhcp_message_init(&packet->dhcp, BOOTREPLY,
                              be32toh(req->message->xid), type, ARPHRD_ETHER,
                              req->max_optlen, &optoffset);
        if (r < 0)
                return r;

        packet->dhcp.flags = req->message->flags;
        packet->dhcp.giaddr = req->message->giaddr;
        memcpy(&packet->dhcp.chaddr, &req->message->chaddr, ETH_ALEN);

        *_optoffset = optoffset;
        *ret = TAKE_PTR(packet);

        return 0;
}

static int server_send_offer_or_ack(
                sd_dhcp_server *server,
                DHCPRequest *req,
                be32_t address,
                uint8_t type) {

        _cleanup_free_ DHCPPacket *packet = NULL;
        sd_dhcp_option *j;
        be32_t lease_time;
        size_t offset;
        int r;

        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;

        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;
        }

        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;
                }
        }

        ORDERED_SET_FOREACH(j, server->extra_options) {
                r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
                                       j->option, j->length, j->data);
                if (r < 0)
                        return r;
        }

        if (!ordered_set_isempty(server->vendor_options)) {
                r = dhcp_option_append(
                                &packet->dhcp, req->max_optlen, &offset, 0,
                                SD_DHCP_OPTION_VENDOR_SPECIFIC,
                                ordered_set_size(server->vendor_options), server->vendor_options);
                if (r < 0)
                        return r;
        }

        r = dhcp_server_send_packet(server, req, packet, type, offset);
        if (r < 0)
                return r;

        return 0;
}

static int server_send_nak_or_ignore(sd_dhcp_server *server, bool init_reboot, DHCPRequest *req) {
        _cleanup_free_ DHCPPacket *packet = NULL;
        size_t offset;
        int r;

        /* When a request is refused, RFC 2131, section 4.3.2 mentioned we should send NAK when the
         * client is in INITREBOOT. If the client is in other state, there is nothing mentioned in the
         * RFC whether we should send NAK or not. Hence, let's silently ignore the request. */

        if (!init_reboot)
                return 0;

        r = server_message_init(server, &packet, DHCP_NAK, &offset, req);
        if (r < 0)
                return log_dhcp_server_errno(server, r, "Failed to create NAK message: %m");

        r = dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
        if (r < 0)
                return log_dhcp_server_errno(server, r, "Could not send NAK message: %m");

        log_dhcp_server(server, "NAK (0x%x)", be32toh(req->message->xid));
        return DHCP_NAK;
}

static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
                                  be32_t gateway, const uint8_t chaddr[]) {
        _cleanup_free_ DHCPPacket *packet = NULL;
        size_t optoffset = 0;
        int r;

        assert(server);
        assert(address != INADDR_ANY);
        assert(chaddr);

        packet = malloc0(sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE);
        if (!packet)
                return -ENOMEM;

        r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0,
                              DHCP_FORCERENEW, ARPHRD_ETHER,
                              DHCP_MIN_OPTIONS_SIZE, &optoffset);
        if (r < 0)
                return r;

        r = dhcp_option_append(&packet->dhcp, DHCP_MIN_OPTIONS_SIZE,
                               &optoffset, 0, SD_DHCP_OPTION_END, 0, NULL);
        if (r < 0)
                return r;

        memcpy(&packet->dhcp.chaddr, chaddr, ETH_ALEN);

        r = dhcp_server_send_udp(server, address, DHCP_PORT_CLIENT,
                                 &packet->dhcp,
                                 sizeof(DHCPMessage) + optoffset);
        if (r < 0)
                return r;

        return 0;
}

static int parse_request(uint8_t code, uint8_t len, const void *option, void *userdata) {
        DHCPRequest *req = userdata;

        assert(req);

        switch(code) {
        case SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
                if (len == 4)
                        req->lifetime = unaligned_read_be32(option);

                break;
        case SD_DHCP_OPTION_REQUESTED_IP_ADDRESS:
                if (len == 4)
                        memcpy(&req->requested_ip, option, sizeof(be32_t));

                break;
        case SD_DHCP_OPTION_SERVER_IDENTIFIER:
                if (len == 4)
                        memcpy(&req->server_id, option, sizeof(be32_t));

                break;
        case SD_DHCP_OPTION_CLIENT_IDENTIFIER:
                if (len >= 2) {
                        uint8_t *data;

                        data = memdup(option, len);
                        if (!data)
                                return -ENOMEM;

                        free(req->client_id.data);
                        req->client_id.data = data;
                        req->client_id.length = len;
                }

                break;
        case SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE:

                if (len == 2 && unaligned_read_be16(option) >= sizeof(DHCPPacket))
                        req->max_optlen = unaligned_read_be16(option) - sizeof(DHCPPacket);

                break;
        case SD_DHCP_OPTION_RELAY_AGENT_INFORMATION:
                req->agent_info_option = (uint8_t*)option - 2;

                break;
        }

        return 0;
}

static DHCPRequest* dhcp_request_free(DHCPRequest *req) {
        if (!req)
                return NULL;

        free(req->client_id.data);
        return mfree(req);
}

DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);

static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
        assert(req);
        assert(message);

        req->message = message;

        /* set client id based on MAC address if client did not send an explicit
           one */
        if (!req->client_id.data) {
                void *data;

                data = malloc0(ETH_ALEN + 1);
                if (!data)
                        return -ENOMEM;

                ((uint8_t*) data)[0] = 0x01;
                memcpy((uint8_t*) data + 1, &message->chaddr, ETH_ALEN);

                req->client_id.length = ETH_ALEN + 1;
                req->client_id.data = data;
        }

        if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
                req->max_optlen = DHCP_MIN_OPTIONS_SIZE;

        if (req->lifetime <= 0)
                req->lifetime = MAX(1ULL, server->default_lease_time);

        if (server->max_lease_time > 0 && req->lifetime > server->max_lease_time)
                req->lifetime = server->max_lease_time;

        return 0;
}

static int get_pool_offset(sd_dhcp_server *server, be32_t requested_ip) {
        assert(server);

        if (!server->pool_size)
                return -EINVAL;

        if (be32toh(requested_ip) < (be32toh(server->subnet) | server->pool_offset) ||
            be32toh(requested_ip) >= (be32toh(server->subnet) | (server->pool_offset + server->pool_size)))
                return -ERANGE;

        return be32toh(requested_ip & ~server->netmask) - server->pool_offset;
}

static int append_agent_information_option(sd_dhcp_server *server, DHCPMessage *message, size_t opt_length, size_t size) {
        int r;
        size_t offset;

        assert(server);
        assert(message);

        r = dhcp_option_find_option(message->options, opt_length, SD_DHCP_OPTION_END, &offset);
        if (r < 0)
                return r;

        r = dhcp_option_append(message, size, &offset, 0, SD_DHCP_OPTION_RELAY_AGENT_INFORMATION, 0, server);
        if (r < 0)
                return r;

        r = dhcp_option_append(message, size, &offset, 0, SD_DHCP_OPTION_END, 0, NULL);
        if (r < 0)
                return r;
        return offset;
}

static int dhcp_server_relay_message(sd_dhcp_server *server, DHCPMessage *message, size_t opt_length, size_t buflen) {
        _cleanup_free_ DHCPPacket *packet = NULL;
        int r;

        assert(server);
        assert(message);
        assert(sd_dhcp_server_is_in_relay_mode(server));

        if (message->op == BOOTREQUEST) {
                log_dhcp_server(server, "(relay agent) BOOTREQUEST (0x%x)", be32toh(message->xid));
                if (message->hops >= 16)
                        return -ETIME;
                message->hops++;

                /* https://tools.ietf.org/html/rfc1542#section-4.1.1 */
                if (message->giaddr == 0)
                        message->giaddr = server->address;

                if (server->agent_circuit_id || server->agent_remote_id) {
                        r = append_agent_information_option(server, message, opt_length, buflen - sizeof(DHCPMessage));
                        if (r < 0)
                                return log_dhcp_server_errno(server, r, "could not append relay option: %m");
                        opt_length = r;
                }

                return dhcp_server_send_udp(server, server->relay_target.s_addr, DHCP_PORT_SERVER, message, sizeof(DHCPMessage) + opt_length);
        } else if (message->op == BOOTREPLY) {
                log_dhcp_server(server, "(relay agent) BOOTREPLY (0x%x)", be32toh(message->xid));
                if (message->giaddr != server->address)
                        return log_dhcp_server_errno(server, SYNTHETIC_ERRNO(EBADMSG),
                                                     "(relay agent) BOOTREPLY giaddr mismatch, discarding");

                int message_type = dhcp_option_parse(message, sizeof(DHCPMessage) + opt_length, NULL, NULL, NULL);
                if (message_type < 0)
                        return message_type;

                packet = malloc0(sizeof(DHCPPacket) + opt_length);
                if (!packet)
                        return -ENOMEM;
                memcpy(&packet->dhcp, message, sizeof(DHCPMessage) + opt_length);

                r = dhcp_option_remove_option(packet->dhcp.options, opt_length, SD_DHCP_OPTION_RELAY_AGENT_INFORMATION);
                if (r > 0)
                        opt_length = r;

                bool l2_broadcast = requested_broadcast(message) || message_type == DHCP_NAK;
                const be32_t destination = message_type == DHCP_NAK ? INADDR_ANY : message->ciaddr;
                return dhcp_server_send(server, destination, DHCP_PORT_CLIENT, packet, opt_length, l2_broadcast);
        }
        return -EBADMSG;
}

static int prepare_new_lease(
                DHCPLease **ret_lease,
                be32_t address,
                const DHCPClientId *client_id,
                const uint8_t chaddr[static ETH_ALEN],
                be32_t gateway,
                usec_t expiration) {

        _cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL;

        lease = new(DHCPLease, 1);
        if (!lease)
                return -ENOMEM;

        *lease = (DHCPLease) {
                .address = address,
                .client_id.length = client_id->length,
                .gateway = gateway,
                .expiration = expiration,
        };
        lease->client_id.data = memdup(client_id->data, client_id->length);
        if (!lease->client_id.data)
                return -ENOMEM;

        memcpy(&lease->chaddr, chaddr, ETH_ALEN);

        *ret_lease = TAKE_PTR(lease);

        return 0;
}

static bool static_leases_have_address(sd_dhcp_server *server, be32_t address) {
        DHCPLease *s;

        assert(server);

        HASHMAP_FOREACH(s, server->static_leases_by_client_id)
                if (s->address == address)
                        return true;

        return false;
}

#define HASH_KEY SD_ID128_MAKE(0d,1d,fe,bd,f1,24,bd,b3,47,f1,dd,6e,73,21,93,30)

int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, size_t length) {
        _cleanup_(dhcp_request_freep) DHCPRequest *req = NULL;
        _cleanup_free_ char *error_message = NULL;
        DHCPLease *existing_lease, *static_lease;
        int type, r;

        assert(server);
        assert(message);

        if (message->op != BOOTREQUEST ||
            message->htype != ARPHRD_ETHER ||
            message->hlen != ETHER_ADDR_LEN)
                return 0;

        req = new0(DHCPRequest, 1);
        if (!req)
                return -ENOMEM;

        type = dhcp_option_parse(message, length, parse_request, req, &error_message);
        if (type < 0)
                return 0;

        r = ensure_sane_request(server, req, message);
        if (r < 0)
                /* this only fails on critical errors */
                return r;

        existing_lease = hashmap_get(server->leases_by_client_id, &req->client_id);
        static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);

        switch(type) {

        case DHCP_DISCOVER: {
                be32_t address = INADDR_ANY;
                unsigned i;

                log_dhcp_server(server, "DISCOVER (0x%x)", be32toh(req->message->xid));

                if (!server->pool_size)
                        /* no pool allocated */
                        return 0;

                /* for now pick a random free address from the pool */
                if (static_lease)
                        address = static_lease->address;
                else if (existing_lease)
                        address = existing_lease->address;
                else {
                        struct siphash state;
                        uint64_t hash;
                        uint32_t next_offer;

                        /* even with no persistence of leases, we try to offer the same client
                           the same IP address. we do this by using the hash of the client id
                           as the offset into the pool of leases when finding the next free one */

                        siphash24_init(&state, HASH_KEY.bytes);
                        client_id_hash_func(&req->client_id, &state);
                        hash = htole64(siphash24_finalize(&state));
                        next_offer = hash % server->pool_size;

                        for (i = 0; i < server->pool_size; i++) {
                                if (!server->bound_leases[next_offer]) {
                                        be32_t tmp = server->subnet | htobe32(server->pool_offset + next_offer);
                                        if (!static_leases_have_address(server, tmp)) {
                                                address = tmp;
                                                break;
                                        }
                                }

                                next_offer = (next_offer + 1) % server->pool_size;
                        }
                }

                if (address == INADDR_ANY)
                        /* no free addresses left */
                        return 0;

                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");

                log_dhcp_server(server, "OFFER (0x%x)", be32toh(req->message->xid));
                return DHCP_OFFER;
        }
        case DHCP_DECLINE:
                log_dhcp_server(server, "DECLINE (0x%x): %s", be32toh(req->message->xid), strna(error_message));

                /* TODO: make sure we don't offer this address again */

                return 1;

        case DHCP_REQUEST: {
                be32_t address;
                bool init_reboot = false;
                int pool_offset;

                /* see RFC 2131, section 4.3.2 */

                if (req->server_id) {
                        log_dhcp_server(server, "REQUEST (selecting) (0x%x)",
                                        be32toh(req->message->xid));

                        /* SELECTING */
                        if (req->server_id != server->address)
                                /* client did not pick us */
                                return 0;

                        if (req->message->ciaddr)
                                /* this MUST be zero */
                                return 0;

                        if (!req->requested_ip)
                                /* this must be filled in with the yiaddr
                                   from the chosen OFFER */
                                return 0;

                        address = req->requested_ip;
                } else if (req->requested_ip) {
                        log_dhcp_server(server, "REQUEST (init-reboot) (0x%x)",
                                        be32toh(req->message->xid));

                        /* INIT-REBOOT */
                        if (req->message->ciaddr)
                                /* this MUST be zero */
                                return 0;

                        /* TODO: check more carefully if IP is correct */
                        address = req->requested_ip;
                        init_reboot = true;
                } else {
                        log_dhcp_server(server, "REQUEST (rebinding/renewing) (0x%x)",
                                        be32toh(req->message->xid));

                        /* REBINDING / RENEWING */
                        if (!req->message->ciaddr)
                                /* this MUST be filled in with clients IP address */
                                return 0;

                        address = req->message->ciaddr;
                }

                pool_offset = get_pool_offset(server, address);

                /* verify that the requested address is from the pool, and either
                   owned by the current client or free */
                if (pool_offset >= 0 && static_lease) {
                        _unused_ _cleanup_(dhcp_lease_freep) DHCPLease *old_lease = NULL;
                        _cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL;
                        usec_t time_now, expiration;

                        r = sd_event_now(server->event, clock_boottime_or_monotonic(), &time_now);
                        if (r < 0)
                                return r;

                        expiration = usec_add(req->lifetime * USEC_PER_SEC, time_now);

                        r = prepare_new_lease(&lease, static_lease->address, &req->client_id,
                                              req->message->chaddr, req->message->giaddr, expiration);
                        if (r < 0)
                                return r;

                        r = server_send_offer_or_ack(server, req, address, DHCP_ACK);
                        if (r < 0)
                                /* this only fails on critical errors */
                                return log_dhcp_server_errno(server, r, "Could not send ack: %m");

                        log_dhcp_server(server, "ACK (0x%x)", be32toh(req->message->xid));

                        server->bound_leases[pool_offset] = lease;

                        old_lease = hashmap_remove(server->leases_by_client_id, &lease->client_id);
                        r = hashmap_put(server->leases_by_client_id, &lease->client_id, lease);
                        if (r < 0)
                                return log_dhcp_server_errno(server, r, "Could not save lease: %m");
                        TAKE_PTR(lease);

                        if (server->callback)
                                server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);

                        return DHCP_ACK;

                } else if (pool_offset >= 0 && server->bound_leases[pool_offset] == existing_lease) {
                        _cleanup_(dhcp_lease_freep) DHCPLease *new_lease = NULL;
                        usec_t time_now, expiration;
                        DHCPLease *lease;

                        r = sd_event_now(server->event, clock_boottime_or_monotonic(), &time_now);
                        if (r < 0)
                                return r;

                        expiration = usec_add(req->lifetime * USEC_PER_SEC, time_now);

                        if (!existing_lease) {
                                r = prepare_new_lease(&new_lease, address, &req->client_id,
                                                      req->message->chaddr, req->message->giaddr, expiration);
                                if (r < 0)
                                        return r;

                                lease = new_lease;
                        } else {
                                existing_lease->expiration = expiration;
                                lease = existing_lease;
                        }

                        r = server_send_offer_or_ack(server, req, address, DHCP_ACK);
                        if (r < 0)
                                /* this only fails on critical errors */
                                return log_dhcp_server_errno(server, r, "Could not send ack: %m");

                        log_dhcp_server(server, "ACK (0x%x)", be32toh(req->message->xid));

                        server->bound_leases[pool_offset] = lease;
                        r = hashmap_put(server->leases_by_client_id, &lease->client_id, lease);
                        if (r < 0)
                                return log_dhcp_server_errno(server, r, "Could not save lease: %m");
                        TAKE_PTR(new_lease);

                        if (server->callback)
                                server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);

                        return DHCP_ACK;
                }

                return server_send_nak_or_ignore(server, init_reboot, req);
        }

        case DHCP_RELEASE: {
                int pool_offset;

                log_dhcp_server(server, "RELEASE (0x%x)",
                                be32toh(req->message->xid));

                if (!existing_lease)
                        return 0;

                if (existing_lease->address != req->message->ciaddr)
                        return 0;

                pool_offset = get_pool_offset(server, req->message->ciaddr);
                if (pool_offset < 0)
                        return 0;

                if (server->bound_leases[pool_offset] == existing_lease) {
                        server->bound_leases[pool_offset] = NULL;
                        hashmap_remove(server->leases_by_client_id, &existing_lease->client_id);
                        dhcp_lease_free(existing_lease);

                        if (server->callback)
                                server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
                }

                return 0;
        }}

        return 0;
}

static size_t relay_agent_information_length(const char* agent_circuit_id, const char* agent_remote_id) {
        size_t sum = 0;
        if (agent_circuit_id)
                sum += 2 + strlen(agent_circuit_id);
        if (agent_remote_id)
                sum += 2 + strlen(agent_remote_id);
        return sum;
}

static int server_receive_message(sd_event_source *s, int fd,
                                  uint32_t revents, void *userdata) {
        _cleanup_free_ DHCPMessage *message = NULL;
        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control;
        sd_dhcp_server *server = userdata;
        struct iovec iov = {};
        struct msghdr msg = {
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_control = &control,
                .msg_controllen = sizeof(control),
        };
        struct cmsghdr *cmsg;
        ssize_t datagram_size, len;
        int r;

        assert(server);

        datagram_size = next_datagram_size_fd(fd);
        if (datagram_size < 0)
                return datagram_size;

        size_t buflen = datagram_size;
        if (sd_dhcp_server_is_in_relay_mode(server))
                /* Preallocate the additional size for DHCP Relay Agent Information Option if needed */
                buflen += relay_agent_information_length(server->agent_circuit_id, server->agent_remote_id) + 2;

        message = malloc(buflen);
        if (!message)
                return -ENOMEM;

        iov = IOVEC_MAKE(message, datagram_size);

        len = recvmsg_safe(fd, &msg, 0);
        if (IN_SET(len, -EAGAIN, -EINTR))
                return 0;
        if (len < 0)
                return len;
        if ((size_t) len < sizeof(DHCPMessage))
                return 0;

        CMSG_FOREACH(cmsg, &msg) {
                if (cmsg->cmsg_level == IPPROTO_IP &&
                    cmsg->cmsg_type == IP_PKTINFO &&
                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct in_pktinfo))) {
                        struct in_pktinfo *info = (struct in_pktinfo*)CMSG_DATA(cmsg);

                        /* TODO figure out if this can be done as a filter on
                         * the socket, like for IPv6 */
                        if (server->ifindex != info->ipi_ifindex)
                                return 0;

                        break;
                }
        }

        if (sd_dhcp_server_is_in_relay_mode(server)) {
                r = dhcp_server_relay_message(server, message, len - sizeof(DHCPMessage), buflen);
                if (r < 0)
                        log_dhcp_server_errno(server, r, "Couldn't relay message: %m");
        } else {
                r = dhcp_server_handle_message(server, message, (size_t) len);
                if (r < 0)
                        log_dhcp_server_errno(server, r, "Couldn't process incoming message: %m");
        }
        return 0;
}

int sd_dhcp_server_start(sd_dhcp_server *server) {
        int r;

        assert_return(server, -EINVAL);
        assert_return(server->event, -EINVAL);

        if (sd_dhcp_server_is_running(server))
                return 0;

        assert_return(!server->receive_message, -EBUSY);
        assert_return(server->fd_raw < 0, -EBUSY);
        assert_return(server->fd < 0, -EBUSY);
        assert_return(server->address != htobe32(INADDR_ANY), -EUNATCH);

        r = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
        if (r < 0) {
                r = -errno;
                goto on_error;
        }
        server->fd_raw = r;

        if (server->bind_to_interface)
                r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER, -1);
        else
                r = dhcp_network_bind_udp_socket(0, server->address, DHCP_PORT_SERVER, -1);
        if (r < 0)
                goto on_error;
        server->fd = r;

        r = sd_event_add_io(server->event, &server->receive_message,
                            server->fd, EPOLLIN,
                            server_receive_message, server);
        if (r < 0)
                goto on_error;

        r = sd_event_source_set_priority(server->receive_message,
                                         server->event_priority);
        if (r < 0)
                goto on_error;

        if (!server->bind_to_interface) {
                r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_BROADCAST, DHCP_PORT_SERVER, -1);
                if (r < 0)
                        goto on_error;

                server->fd_broadcast = r;

                r = sd_event_add_io(server->event, &server->receive_broadcast,
                                    server->fd_broadcast, EPOLLIN,
                                    server_receive_message, server);
                if (r < 0)
                        goto on_error;

                r = sd_event_source_set_priority(server->receive_broadcast,
                                                 server->event_priority);
                if (r < 0)
                        goto on_error;
        }

        log_dhcp_server(server, "STARTED");

        return 0;

on_error:
    sd_dhcp_server_stop(server);
    return r;
}

int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
        int r = 0;

        assert_return(server, -EINVAL);
        assert(server->bound_leases);

        for (uint32_t i = 0; i < server->pool_size; i++) {
                DHCPLease *lease = server->bound_leases[i];

                if (!lease || lease == &server->invalid_lease)
                        continue;

                r = server_send_forcerenew(server, lease->address,
                                           lease->gateway,
                                           lease->chaddr);
                if (r < 0)
                        return r;

                log_dhcp_server(server, "FORCERENEW");
        }

        return r;
}

int sd_dhcp_server_set_bind_to_interface(sd_dhcp_server *server, int enabled) {
        assert_return(server, -EINVAL);
        assert_return(!sd_dhcp_server_is_running(server), -EBUSY);

        if (!!enabled == server->bind_to_interface)
                return 0;

        server->bind_to_interface = enabled;

        return 1;
}

int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *tz) {
        int r;

        assert_return(server, -EINVAL);
        assert_return(timezone_is_valid(tz, LOG_DEBUG), -EINVAL);

        if (streq_ptr(tz, server->timezone))
                return 0;

        r = free_and_strdup(&server->timezone, tz);
        if (r < 0)
                return r;

        return 1;
}

int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t) {
        assert_return(server, -EINVAL);

        if (t == server->max_lease_time)
                return 0;

        server->max_lease_time = t;
        return 1;
}

int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
        assert_return(server, -EINVAL);

        if (t == server->default_lease_time)
                return 0;

        server->default_lease_time = t;
        return 1;
}

int sd_dhcp_server_set_servers(
                sd_dhcp_server *server,
                sd_dhcp_lease_server_type_t what,
                const struct in_addr addresses[],
                size_t n_addresses) {

        struct in_addr *c = NULL;

        assert_return(server, -EINVAL);
        assert_return(addresses || n_addresses == 0, -EINVAL);
        assert_return(what >= 0, -EINVAL);
        assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL);

        if (server->servers[what].size == n_addresses &&
            memcmp(server->servers[what].addr, addresses, sizeof(struct in_addr) * n_addresses) == 0)
                return 0;

        if (n_addresses > 0) {
                c = newdup(struct in_addr, addresses, n_addresses);
                if (!c)
                        return -ENOMEM;
        }

        free(server->servers[what].addr);
        server->servers[what].addr = c;
        server->servers[what].size = n_addresses;
        return 1;
}

int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_DNS, dns, n);
}
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_NTP, ntp, n);
}
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SIP, sip, n);
}
int sd_dhcp_server_set_pop3(sd_dhcp_server *server, const struct in_addr pop3[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_POP3, pop3, n);
}
int sd_dhcp_server_set_smtp(sd_dhcp_server *server, const struct in_addr smtp[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP, smtp, n);
}
int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], size_t n) {
        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_LPR, lpr, n);
}

int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
        assert_return(server, -EINVAL);

        if (enabled == server->emit_router)
                return 0;

        server->emit_router = enabled;

        return 1;
}

int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v) {
        int r;

        assert_return(server, -EINVAL);
        assert_return(v, -EINVAL);

        r = ordered_set_ensure_put(&server->extra_options, &dhcp_option_hash_ops, v);
        if (r < 0)
                return r;

        sd_dhcp_option_ref(v);
        return 0;
}

int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v) {
        int r;

        assert_return(server, -EINVAL);
        assert_return(v, -EINVAL);

        r = ordered_set_ensure_put(&server->vendor_options, &dhcp_option_hash_ops, v);
        if (r < 0)
                return r;

        sd_dhcp_option_ref(v);

        return 1;
}

int sd_dhcp_server_set_callback(sd_dhcp_server *server, sd_dhcp_server_callback_t cb, void *userdata) {
        assert_return(server, -EINVAL);

        server->callback = cb;
        server->callback_userdata = userdata;

        return 0;
}

int sd_dhcp_server_set_relay_target(sd_dhcp_server *server, const struct in_addr *address) {
        assert_return(server, -EINVAL);
        assert_return(!sd_dhcp_server_is_running(server), -EBUSY);

        if (memcmp(address, &server->relay_target, sizeof(struct in_addr)) == 0)
                return 0;

        server->relay_target = *address;
        return 1;
}

int sd_dhcp_server_set_relay_agent_information(
                sd_dhcp_server *server,
                const char *agent_circuit_id,
                const char *agent_remote_id) {
        _cleanup_free_ char *circuit_id_dup = NULL, *remote_id_dup = NULL;

        assert_return(server, -EINVAL);

        if (relay_agent_information_length(agent_circuit_id, agent_remote_id) > UINT8_MAX)
                return -ENOBUFS;

        if (agent_circuit_id) {
                circuit_id_dup = strdup(agent_circuit_id);
                if (!circuit_id_dup)
                        return -ENOMEM;
        }

        if (agent_remote_id) {
                remote_id_dup = strdup(agent_remote_id);
                if (!remote_id_dup)
                        return -ENOMEM;
        }

        free_and_replace(server->agent_circuit_id, circuit_id_dup);
        free_and_replace(server->agent_remote_id, remote_id_dup);
        return 0;
}

int sd_dhcp_server_set_static_lease(
                sd_dhcp_server *server,
                const struct in_addr *address,
                uint8_t *client_id,
                size_t client_id_size) {

        _unused_ _cleanup_(dhcp_lease_freep) DHCPLease *old = NULL;
        _cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL;
        DHCPClientId c;
        int r;

        assert_return(server, -EINVAL);
        assert_return(client_id, -EINVAL);
        assert_return(client_id_size == ETH_ALEN + 1, -EINVAL);
        assert_return(!sd_dhcp_server_is_running(server), -EBUSY);

        /* Static lease with an empty or omitted address is a valid entry,
        * the server removes any static lease with the specified mac address. */
        if (!address || address->s_addr == 0) {
                _cleanup_free_ void *data = NULL;

                data = memdup(client_id, client_id_size);
                if (!data)
                        return -ENOMEM;

                c = (DHCPClientId) {
                        .length = client_id_size,
                        .data = data,
                };

                old = hashmap_remove(server->static_leases_by_client_id, &c);
                return 0;
        }

        if (static_leases_have_address(server, address->s_addr))
                return -EEXIST;

        lease = new(DHCPLease, 1);
        if (!lease)
                return -ENOMEM;

        *lease = (DHCPLease) {
                .address = address->s_addr,
                .client_id.length = client_id_size,
                .gateway = 0,
                .expiration = 0,
        };
        lease->client_id.data = memdup(client_id, client_id_size);
        if (!lease->client_id.data)
                return -ENOMEM;

        r = hashmap_ensure_put(&server->static_leases_by_client_id, &dhcp_lease_hash_ops, &lease->client_id, lease);
        if (r < 0)
                return r;

        TAKE_PTR(lease);
        return 0;
}
