summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/sd-dhcp-server.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-01-02 22:06:42 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-01-03 07:20:31 +0100
commit95c48613f4820bde38594272265a94fba74abe77 (patch)
tree35cbb40ee2650cc39a81b4c8e28690da78c499bd /src/libsystemd-network/sd-dhcp-server.c
parentfundamental: prefer byte swap builtins over byte swapping manually (diff)
downloadsystemd-95c48613f4820bde38594272265a94fba74abe77.tar.xz
systemd-95c48613f4820bde38594272265a94fba74abe77.zip
sd-dhcp-server: use sd_dhcp_client_id
Diffstat (limited to 'src/libsystemd-network/sd-dhcp-server.c')
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c143
1 files changed, 44 insertions, 99 deletions
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 7eaca0bb71..7ece30cf7b 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -40,7 +40,6 @@ DHCPLease *dhcp_lease_free(DHCPLease *lease) {
hashmap_remove_value(lease->server->static_leases_by_client_id, &lease->client_id, lease);
}
- free(lease->client_id.data);
free(lease->hostname);
return mfree(lease);
}
@@ -127,33 +126,9 @@ int sd_dhcp_server_is_in_relay_mode(sd_dhcp_server *server) {
return in4_addr_is_set(&server->relay_target);
}
-void client_id_hash_func(const DHCPClientId *id, struct siphash *state) {
- assert(id);
- assert(id->length > 0);
- assert(id->data);
-
- siphash24_compress_typesafe(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 > 0);
- assert(a->data);
- assert(b->length > 0);
- assert(b->data);
-
- r = CMP(a->length, b->length);
- if (r != 0)
- return r;
-
- return memcmp(a->data, b->data, a->length);
-}
-
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
dhcp_lease_hash_ops,
- DHCPClientId,
+ sd_dhcp_client_id,
client_id_hash_func,
client_id_compare_func,
DHCPLease,
@@ -786,16 +761,8 @@ static int parse_request(uint8_t code, uint8_t len, const void *option, void *us
break;
case SD_DHCP_OPTION_CLIENT_IDENTIFIER:
- if (len >= 2) {
- uint8_t *data;
-
- data = memdup(option, len);
- if (!data)
- return -ENOMEM;
-
- free_and_replace(req->client_id.data, data);
- req->client_id.length = len;
- }
+ if (client_id_size_is_valid(len))
+ (void) sd_dhcp_client_id_set_raw(&req->client_id, option, len);
break;
case SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE:
@@ -833,7 +800,6 @@ static DHCPRequest* dhcp_request_free(DHCPRequest *req) {
if (!req)
return NULL;
- free(req->client_id.data);
free(req->hostname);
return mfree(req);
}
@@ -841,6 +807,8 @@ static DHCPRequest* dhcp_request_free(DHCPRequest *req) {
DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);
static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMessage *message) {
+ int r;
+
assert(req);
assert(message);
@@ -850,39 +818,39 @@ static int ensure_sane_request(sd_dhcp_server *server, DHCPRequest *req, DHCPMes
return -EBADMSG;
/* set client id based on MAC address if client did not send an explicit one */
- if (!req->client_id.data) {
- uint8_t *data;
-
- if (message->hlen == 0)
+ if (!sd_dhcp_client_id_is_set(&req->client_id)) {
+ if (!client_id_data_size_is_valid(message->hlen))
return -EBADMSG;
- data = new0(uint8_t, message->hlen + 1);
- if (!data)
- return -ENOMEM;
-
- data[0] = 0x01;
- memcpy(data + 1, message->chaddr, message->hlen);
-
- req->client_id.length = message->hlen + 1;
- req->client_id.data = data;
+ r = sd_dhcp_client_id_set(&req->client_id, /* type = */ 1, message->chaddr, message->hlen);
+ if (r < 0)
+ return r;
}
if (message->hlen == 0 || memeqzero(message->chaddr, message->hlen)) {
+ uint8_t type;
+ const void *data;
+ size_t size;
+
/* See RFC2131 section 4.1.1.
* hlen and chaddr may not be set for non-ethernet interface.
* Let's try to retrieve it from the client ID. */
- if (!req->client_id.data)
+ if (!sd_dhcp_client_id_is_set(&req->client_id))
return -EBADMSG;
- if (req->client_id.length <= 1 || req->client_id.length > sizeof(message->chaddr) + 1)
+ r = sd_dhcp_client_id_get(&req->client_id, &type, &data, &size);
+ if (r < 0)
+ return r;
+
+ if (type != 1)
return -EBADMSG;
- if (req->client_id.data[0] != 0x01)
+ if (size > sizeof(message->chaddr))
return -EBADMSG;
- message->hlen = req->client_id.length - 1;
- memcpy(message->chaddr, req->client_id.data + 1, message->hlen);
+ memcpy(message->chaddr, data, size);
+ message->hlen = size;
}
if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
@@ -1032,15 +1000,12 @@ static int prepare_new_lease(DHCPLease **ret_lease, be32_t address, DHCPRequest
*lease = (DHCPLease) {
.address = address,
- .client_id.length = req->client_id.length,
+ .client_id = req->client_id,
.htype = req->message->htype,
.hlen = req->message->hlen,
.gateway = req->message->giaddr,
.expiration = expiration,
};
- lease->client_id.data = memdup(req->client_id.data, req->client_id.length);
- if (!lease->client_id.data)
- return -ENOMEM;
memcpy(lease->chaddr, req->message->chaddr, req->message->hlen);
@@ -1135,38 +1100,25 @@ 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) {
+static DHCPLease* server_get_static_lease(sd_dhcp_server *server, const DHCPRequest *req) {
DHCPLease *static_lease;
- _cleanup_free_ uint8_t *data = NULL;
+ sd_dhcp_client_id client_id;
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;
- }
+ if (static_lease)
+ return static_lease;
/* 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,
- });
+ if (!client_id_data_size_is_valid(req->message->hlen))
+ return NULL;
- *ret = static_lease;
+ if (sd_dhcp_client_id_set(&client_id, /* type = */ 1, req->message->chaddr, req->message->hlen) < 0)
+ return NULL;
- return 0;
+ return hashmap_get(server->static_leases_by_client_id, &client_id);
}
#define HASH_KEY SD_ID128_MAKE(0d,1d,fe,bd,f1,24,bd,b3,47,f1,dd,6e,73,21,93,30)
@@ -1202,9 +1154,7 @@ 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);
- r = server_get_static_lease(server, req, &static_lease);
- if (r < 0)
- return r;
+ static_lease = server_get_static_lease(server, req);
switch (type) {
@@ -1741,28 +1691,26 @@ int sd_dhcp_server_set_relay_agent_information(
int sd_dhcp_server_set_static_lease(
sd_dhcp_server *server,
const struct in_addr *address,
- uint8_t *client_id,
+ uint8_t *client_id_raw,
size_t client_id_size) {
_cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL;
+ sd_dhcp_client_id client_id;
int r;
assert_return(server, -EINVAL);
- assert_return(client_id, -EINVAL);
- assert_return(client_id_size > 0, -EINVAL);
+ assert_return(client_id_raw, -EINVAL);
+ assert_return(client_id_size_is_valid(client_id_size), -EINVAL);
assert_return(!sd_dhcp_server_is_running(server), -EBUSY);
+ r = sd_dhcp_client_id_set_raw(&client_id, client_id_raw, client_id_size);
+ if (r < 0)
+ return r;
+
/* 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) {
- DHCPClientId c;
-
- c = (DHCPClientId) {
- .length = client_id_size,
- .data = client_id,
- };
-
- dhcp_lease_free(hashmap_get(server->static_leases_by_client_id, &c));
+ dhcp_lease_free(hashmap_get(server->static_leases_by_client_id, &client_id));
return 0;
}
@@ -1772,11 +1720,8 @@ int sd_dhcp_server_set_static_lease(
*lease = (DHCPLease) {
.address = address->s_addr,
- .client_id.length = client_id_size,
+ .client_id = client_id,
};
- lease->client_id.data = memdup(client_id, client_id_size);
- if (!lease->client_id.data)
- return -ENOMEM;
lease->server = server; /* This must be set just before hashmap_put(). */