diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-02 22:06:42 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-03 07:20:31 +0100 |
commit | 95c48613f4820bde38594272265a94fba74abe77 (patch) | |
tree | 35cbb40ee2650cc39a81b4c8e28690da78c499bd /src/libsystemd-network/sd-dhcp-server.c | |
parent | fundamental: prefer byte swap builtins over byte swapping manually (diff) | |
download | systemd-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.c | 143 |
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(). */ |