}
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
- uint16_t len;
- uint8_t *ia_hdr;
- size_t iaid_offset, ia_buflen, ia_addrlen = 0;
+ size_t ia_buflen, ia_addrlen = 0;
+ struct ia_na ia_na;
+ struct ia_ta ia_ta;
DHCP6Address *addr;
+ uint8_t *ia_hdr;
+ uint16_t len;
+ void *p;
int r;
assert_return(buf, -EINVAL);
assert_return(buflen, -EINVAL);
assert_return(ia, -EINVAL);
+ /* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
+
switch (ia->type) {
case SD_DHCP6_OPTION_IA_NA:
len = DHCP6_OPTION_IA_NA_LEN;
- iaid_offset = offsetof(DHCP6IA, ia_na);
+ ia_na = (struct ia_na) {
+ .id = ia->ia_na.id,
+ };
+ p = &ia_na;
break;
case SD_DHCP6_OPTION_IA_TA:
len = DHCP6_OPTION_IA_TA_LEN;
- iaid_offset = offsetof(DHCP6IA, ia_ta);
+ ia_ta = (struct ia_ta) {
+ .id = ia->ia_ta.id,
+ };
+ p = &ia_ta;
break;
default:
*buf += offsetof(DHCP6Option, data);
*buflen -= offsetof(DHCP6Option, data);
- memcpy(*buf, (char*) ia + iaid_offset, len);
+ memcpy(*buf, p, len);
*buf += len;
*buflen -= len;
LIST_FOREACH(addresses, addr, ia->addresses) {
- r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR,
- sizeof(addr->iaaddr));
+ struct iaaddr a = {
+ .address = addr->iaaddr.address,
+ };
+
+ r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
if (r < 0)
return r;
- memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr));
+ memcpy(*buf, &a, sizeof(struct iaaddr));
- *buf += sizeof(addr->iaaddr);
- *buflen -= sizeof(addr->iaaddr);
+ *buf += sizeof(struct iaaddr);
+ *buflen -= sizeof(struct iaaddr);
- ia_addrlen += offsetof(DHCP6Option, data) + sizeof(addr->iaaddr);
+ ia_addrlen += offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
}
- r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
- if (r < 0)
- return r;
-
- return 0;
+ return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
}
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
assert_se(optlen == 40);
assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
- val = htobe32(80);
+ /* T1 and T2 should not be set. */
+ val = 0;
assert_se(!memcmp(optval + 4, &val, sizeof(val)));
-
- val = htobe32(120);
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
+ /* Then, this should refuse all addresses. */
assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
break;
found_elapsed_time);
sd_dhcp6_lease_reset_address_iter(lease);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
- <_valid) >= 0);
- assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
- assert_se(lt_pref == 150);
- assert_se(lt_valid == 180);
-
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref,
- <_valid) == -ENOMSG);
+ assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENOMSG);
return 0;
}