1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2014-2015 Intel Corporation. All rights reserved.
8 #include "alloc-util.h"
9 #include "dhcp6-lease-internal.h"
10 #include "dhcp6-protocol.h"
14 int dhcp6_lease_ia_rebind_expire(const DHCP6IA
*ia
, uint32_t *expire
) {
16 uint32_t valid
= 0, t
;
18 assert_return(ia
, -EINVAL
);
19 assert_return(expire
, -EINVAL
);
21 LIST_FOREACH(addresses
, addr
, ia
->addresses
) {
22 t
= be32toh(addr
->iaaddr
.lifetime_valid
);
27 t
= be32toh(ia
->ia_na
.lifetime_t2
);
36 DHCP6IA
*dhcp6_lease_free_ia(DHCP6IA
*ia
) {
37 DHCP6Address
*address
;
42 while (ia
->addresses
) {
43 address
= ia
->addresses
;
45 LIST_REMOVE(addresses
, ia
->addresses
, address
);
53 int dhcp6_lease_set_serverid(sd_dhcp6_lease
*lease
, const uint8_t *id
,
57 assert_return(lease
, -EINVAL
);
58 assert_return(id
, -EINVAL
);
60 serverid
= memdup(id
, len
);
64 free_and_replace(lease
->serverid
, serverid
);
65 lease
->serverid_len
= len
;
70 int dhcp6_lease_get_serverid(sd_dhcp6_lease
*lease
, uint8_t **id
, size_t *len
) {
71 assert_return(lease
, -EINVAL
);
77 *id
= lease
->serverid
;
79 *len
= lease
->serverid_len
;
84 int dhcp6_lease_set_preference(sd_dhcp6_lease
*lease
, uint8_t preference
) {
85 assert_return(lease
, -EINVAL
);
87 lease
->preference
= preference
;
92 int dhcp6_lease_get_preference(sd_dhcp6_lease
*lease
, uint8_t *preference
) {
93 assert_return(preference
, -EINVAL
);
98 *preference
= lease
->preference
;
103 int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease
*lease
) {
104 assert_return(lease
, -EINVAL
);
106 lease
->rapid_commit
= true;
111 int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease
*lease
, bool *rapid_commit
) {
112 assert_return(lease
, -EINVAL
);
113 assert_return(rapid_commit
, -EINVAL
);
115 *rapid_commit
= lease
->rapid_commit
;
120 int dhcp6_lease_get_iaid(sd_dhcp6_lease
*lease
, be32_t
*iaid
) {
121 assert_return(lease
, -EINVAL
);
122 assert_return(iaid
, -EINVAL
);
124 *iaid
= lease
->ia
.ia_na
.id
;
129 int dhcp6_lease_get_pd_iaid(sd_dhcp6_lease
*lease
, be32_t
*iaid
) {
130 assert_return(lease
, -EINVAL
);
131 assert_return(iaid
, -EINVAL
);
133 *iaid
= lease
->pd
.ia_pd
.id
;
138 int sd_dhcp6_lease_get_address(sd_dhcp6_lease
*lease
, struct in6_addr
*addr
,
139 uint32_t *lifetime_preferred
,
140 uint32_t *lifetime_valid
) {
141 assert_return(lease
, -EINVAL
);
142 assert_return(addr
, -EINVAL
);
143 assert_return(lifetime_preferred
, -EINVAL
);
144 assert_return(lifetime_valid
, -EINVAL
);
146 if (!lease
->addr_iter
)
149 memcpy(addr
, &lease
->addr_iter
->iaaddr
.address
,
150 sizeof(struct in6_addr
));
151 *lifetime_preferred
=
152 be32toh(lease
->addr_iter
->iaaddr
.lifetime_preferred
);
153 *lifetime_valid
= be32toh(lease
->addr_iter
->iaaddr
.lifetime_valid
);
155 lease
->addr_iter
= lease
->addr_iter
->addresses_next
;
160 void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease
*lease
) {
162 lease
->addr_iter
= lease
->ia
.addresses
;
165 int sd_dhcp6_lease_get_pd(sd_dhcp6_lease
*lease
, struct in6_addr
*prefix
,
167 uint32_t *lifetime_preferred
,
168 uint32_t *lifetime_valid
) {
169 assert_return(lease
, -EINVAL
);
170 assert_return(prefix
, -EINVAL
);
171 assert_return(prefix_len
, -EINVAL
);
172 assert_return(lifetime_preferred
, -EINVAL
);
173 assert_return(lifetime_valid
, -EINVAL
);
175 if (!lease
->prefix_iter
)
178 memcpy(prefix
, &lease
->prefix_iter
->iapdprefix
.address
,
179 sizeof(struct in6_addr
));
180 *prefix_len
= lease
->prefix_iter
->iapdprefix
.prefixlen
;
181 *lifetime_preferred
=
182 be32toh(lease
->prefix_iter
->iapdprefix
.lifetime_preferred
);
184 be32toh(lease
->prefix_iter
->iapdprefix
.lifetime_valid
);
186 lease
->prefix_iter
= lease
->prefix_iter
->addresses_next
;
191 void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease
*lease
) {
193 lease
->prefix_iter
= lease
->pd
.addresses
;
196 int dhcp6_lease_set_dns(sd_dhcp6_lease
*lease
, uint8_t *optval
, size_t optlen
) {
199 assert_return(lease
, -EINVAL
);
200 assert_return(optval
, -EINVAL
);
205 r
= dhcp6_option_parse_ip6addrs(optval
, optlen
, &lease
->dns
,
210 lease
->dns_count
= r
;
215 int sd_dhcp6_lease_get_dns(sd_dhcp6_lease
*lease
, const struct in6_addr
**addrs
) {
216 assert_return(lease
, -EINVAL
);
217 assert_return(addrs
, -EINVAL
);
219 if (lease
->dns_count
) {
221 return lease
->dns_count
;
227 int dhcp6_lease_set_domains(sd_dhcp6_lease
*lease
, uint8_t *optval
,
232 assert_return(lease
, -EINVAL
);
233 assert_return(optval
, -EINVAL
);
238 r
= dhcp6_option_parse_domainname_list(optval
, optlen
, &domains
);
242 strv_free_and_replace(lease
->domains
, domains
);
243 lease
->domains_count
= r
;
248 int sd_dhcp6_lease_get_domains(sd_dhcp6_lease
*lease
, char ***domains
) {
249 assert_return(lease
, -EINVAL
);
250 assert_return(domains
, -EINVAL
);
252 if (lease
->domains_count
) {
253 *domains
= lease
->domains
;
254 return lease
->domains_count
;
260 int dhcp6_lease_set_ntp(sd_dhcp6_lease
*lease
, uint8_t *optval
, size_t optlen
) {
266 assert_return(lease
, -EINVAL
);
267 assert_return(optval
, -EINVAL
);
269 lease
->ntp
= mfree(lease
->ntp
);
270 lease
->ntp_count
= 0;
272 while ((r
= dhcp6_option_parse(&optval
, &optlen
, &subopt
, &sublen
,
278 case DHCP6_NTP_SUBOPTION_SRV_ADDR
:
279 case DHCP6_NTP_SUBOPTION_MC_ADDR
:
283 s
= dhcp6_option_parse_ip6addrs(subval
, sublen
,
289 lease
->ntp_count
= s
;
293 case DHCP6_NTP_SUBOPTION_SRV_FQDN
:
294 r
= dhcp6_option_parse_domainname_list(subval
, sublen
,
299 strv_free_and_replace(lease
->ntp_fqdn
, servers
);
300 lease
->ntp_fqdn_count
= r
;
312 int dhcp6_lease_set_sntp(sd_dhcp6_lease
*lease
, uint8_t *optval
, size_t optlen
) {
315 assert_return(lease
, -EINVAL
);
316 assert_return(optval
, -EINVAL
);
321 if (lease
->ntp
|| lease
->ntp_fqdn
)
324 /* Using deprecated SNTP information */
326 r
= dhcp6_option_parse_ip6addrs(optval
, optlen
, &lease
->ntp
,
331 lease
->ntp_count
= r
;
336 int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease
*lease
,
337 const struct in6_addr
**addrs
) {
338 assert_return(lease
, -EINVAL
);
339 assert_return(addrs
, -EINVAL
);
341 if (lease
->ntp_count
) {
343 return lease
->ntp_count
;
349 int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease
*lease
, char ***ntp_fqdn
) {
350 assert_return(lease
, -EINVAL
);
351 assert_return(ntp_fqdn
, -EINVAL
);
353 if (lease
->ntp_fqdn_count
) {
354 *ntp_fqdn
= lease
->ntp_fqdn
;
355 return lease
->ntp_fqdn_count
;
361 int dhcp6_lease_set_fqdn(sd_dhcp6_lease
*lease
, const uint8_t *optval
,
366 assert_return(lease
, -EINVAL
);
367 assert_return(optval
, -EINVAL
);
372 /* Ignore the flags field, it doesn't carry any useful
373 information for clients. */
374 r
= dhcp6_option_parse_domainname(optval
+ 1, optlen
- 1, &fqdn
);
378 return free_and_replace(lease
->fqdn
, fqdn
);
381 int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease
*lease
, const char **fqdn
) {
382 assert_return(lease
, -EINVAL
);
383 assert_return(fqdn
, -EINVAL
);
393 static sd_dhcp6_lease
*dhcp6_lease_free(sd_dhcp6_lease
*lease
) {
396 free(lease
->serverid
);
397 dhcp6_lease_free_ia(&lease
->ia
);
398 dhcp6_lease_free_ia(&lease
->pd
);
403 lease
->domains
= strv_free(lease
->domains
);
407 lease
->ntp_fqdn
= strv_free(lease
->ntp_fqdn
);
411 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_lease
, sd_dhcp6_lease
, dhcp6_lease_free
);
413 int dhcp6_lease_new(sd_dhcp6_lease
**ret
) {
414 sd_dhcp6_lease
*lease
;
416 lease
= new0(sd_dhcp6_lease
, 1);
422 LIST_HEAD_INIT(lease
->ia
.addresses
);