summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/sd-dhcp-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network/sd-dhcp-server.c')
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 05c0cddfd0..55290ee0f1 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -1061,6 +1061,40 @@ static bool address_available(sd_dhcp_server *server, be32_t address) {
return true;
}
+static int server_get_static_lease(sd_dhcp_server *server, const DHCPRequest *req, DHCPLease **ret) {
+ DHCPLease *static_lease;
+ _cleanup_free_ uint8_t *data = NULL;
+
+ assert(server);
+ assert(req);
+ assert(ret);
+
+ static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);
+ if (static_lease) {
+ *ret = static_lease;
+ return 0;
+ }
+
+ /* when no lease is found based on the client id fall back to chaddr */
+ data = new(uint8_t, req->message->hlen + 1);
+ if (!data)
+ return -ENOMEM;
+
+ /* set client id type to 1: Ethernet Link-Layer (RFC 2132) */
+ data[0] = 0x01;
+ memcpy(data + 1, req->message->chaddr, req->message->hlen);
+
+ static_lease = hashmap_get(server->static_leases_by_client_id,
+ &(DHCPClientId) {
+ .length = req->message->hlen + 1,
+ .data = data,
+ });
+
+ *ret = static_lease;
+
+ return 0;
+}
+
#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) {
@@ -1092,7 +1126,9 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
return r;
existing_lease = hashmap_get(server->bound_leases_by_client_id, &req->client_id);
- static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);
+ r = server_get_static_lease(server, req, &static_lease);
+ if (r < 0)
+ return r;
switch (type) {