struct sd_dhcp6_lease {
unsigned n_ref;
+ uint8_t *clientid;
+ size_t clientid_len;
uint8_t *serverid;
size_t serverid_len;
uint8_t preference;
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);
uint32_t lt_t1 = UINT32_MAX, lt_t2 = UINT32_MAX;
usec_t irt = IRT_DEFAULT;
- bool clientid = false;
int r;
assert(client);
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;
}
}
- 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)
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;
if (!lease)
return NULL;
+ free(lease->clientid);
free(lease->serverid);
dhcp6_lease_free_ia(&lease->ia);
dhcp6_lease_free_ia(&lease->pd);