From: Yu Watanabe Date: Mon, 1 Nov 2021 05:19:16 +0000 (+0900) Subject: sd-dhcp6-client: introduce dhcp6_lease_{get,set}_clientid() X-Git-Tag: v250-rc1~372^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e79b4b85344cc9095853348052a29334ebc1dfa9;p=thirdparty%2Fsystemd.git sd-dhcp6-client: introduce dhcp6_lease_{get,set}_clientid() --- diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index 88c1c0e9b55..4b73e0cfe05 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -14,6 +14,8 @@ struct sd_dhcp6_lease { unsigned n_ref; + uint8_t *clientid; + size_t clientid_len; uint8_t *serverid; size_t serverid_len; uint8_t preference; @@ -41,6 +43,8 @@ struct sd_dhcp6_lease { int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire); DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia); +int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); +int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len); int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len); int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 6562ebd21c5..f8d7367ec3c 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1134,7 +1134,6 @@ static int client_parse_message( uint32_t lt_t1 = UINT32_MAX, lt_t2 = UINT32_MAX; usec_t irt = IRT_DEFAULT; - bool clientid = false; int r; assert(client); @@ -1154,16 +1153,13 @@ static int client_parse_message( switch (optcode) { case SD_DHCP6_OPTION_CLIENTID: - if (clientid) + if (dhcp6_lease_get_clientid(lease, NULL, NULL) >= 0) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple client IDs", dhcp6_message_type_to_string(message->type)); - if (optlen != client->duid_len || - memcmp(&client->duid, optval, optlen) != 0) - return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s DUID does not match", - dhcp6_message_type_to_string(message->type)); - - clientid = true; + r = dhcp6_lease_set_clientid(lease, optval, optlen); + if (r < 0) + return r; break; @@ -1308,10 +1304,17 @@ static int client_parse_message( } } - if (!clientid) + uint8_t *clientid; + size_t clientid_len; + if (dhcp6_lease_get_clientid(lease, &clientid, &clientid_len) < 0) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s message does not contain client ID. Ignoring.", dhcp6_message_type_to_string(message->type)); + if (clientid_len != client->duid_len || + memcmp(clientid, &client->duid, clientid_len) != 0) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "The client ID in %s message does not match. Ignoring.", + dhcp6_message_type_to_string(message->type)); + if (client->state != DHCP6_STATE_INFORMATION_REQUEST) { r = dhcp6_lease_get_serverid(lease, NULL, NULL); if (r < 0) diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index ba46e09919b..22fb77c19e1 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -71,6 +71,37 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) { return NULL; } +int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) { + uint8_t *clientid; + + assert_return(lease, -EINVAL); + assert_return(id, -EINVAL); + assert_return(len > 0, -EINVAL); + + clientid = memdup(id, len); + if (!clientid) + return -ENOMEM; + + free_and_replace(lease->clientid, clientid); + lease->clientid_len = len; + + return 0; +} + +int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) { + assert_return(lease, -EINVAL); + + if (!lease->clientid) + return -ENODATA; + + if (ret_id) + *ret_id = lease->clientid; + if (ret_len) + *ret_len = lease->clientid_len; + + return 0; +} + int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) { uint8_t *serverid; @@ -367,6 +398,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) { if (!lease) return NULL; + free(lease->clientid); free(lease->serverid); dhcp6_lease_free_ia(&lease->ia); dhcp6_lease_free_ia(&lease->pd);