]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp6-lease.c
sd-dhcp6: drop unused functions
[thirdparty/systemd.git] / src / libsystemd-network / sd-dhcp6-lease.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3 Copyright © 2014-2015 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <errno.h>
7
8 #include "alloc-util.h"
9 #include "dhcp6-lease-internal.h"
10 #include "dhcp6-protocol.h"
11 #include "strv.h"
12 #include "util.h"
13
14 int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret) {
15 assert_return(lease, -EINVAL);
16 assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP);
17 assert_return(clock_supported(clock), -EOPNOTSUPP);
18 assert_return(ret, -EINVAL);
19
20 if (!triple_timestamp_is_set(&lease->timestamp))
21 return -ENODATA;
22
23 *ret = triple_timestamp_by_clock(&lease->timestamp, clock);
24 return 0;
25 }
26
27 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
28 DHCP6Address *addr;
29 uint32_t valid = 0, t;
30
31 assert_return(ia, -EINVAL);
32 assert_return(expire, -EINVAL);
33
34 LIST_FOREACH(addresses, addr, ia->addresses) {
35 t = be32toh(addr->iaaddr.lifetime_valid);
36 if (valid < t)
37 valid = t;
38 }
39
40 t = be32toh(ia->ia_na.lifetime_t2);
41 if (t > valid)
42 return -EINVAL;
43
44 *expire = valid - t;
45
46 return 0;
47 }
48
49 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
50 DHCP6Address *address;
51
52 if (!ia)
53 return NULL;
54
55 while (ia->addresses) {
56 address = ia->addresses;
57
58 LIST_REMOVE(addresses, ia->addresses, address);
59
60 free(address);
61 }
62
63 return NULL;
64 }
65
66 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
67 size_t len) {
68 uint8_t *serverid;
69
70 assert_return(lease, -EINVAL);
71 assert_return(id, -EINVAL);
72
73 serverid = memdup(id, len);
74 if (!serverid)
75 return -ENOMEM;
76
77 free_and_replace(lease->serverid, serverid);
78 lease->serverid_len = len;
79
80 return 0;
81 }
82
83 int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
84 assert_return(lease, -EINVAL);
85
86 if (!lease->serverid)
87 return -ENOMSG;
88
89 if (id)
90 *id = lease->serverid;
91 if (len)
92 *len = lease->serverid_len;
93
94 return 0;
95 }
96
97 int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
98 assert_return(lease, -EINVAL);
99
100 lease->preference = preference;
101
102 return 0;
103 }
104
105 int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
106 assert_return(preference, -EINVAL);
107
108 if (!lease)
109 return -EINVAL;
110
111 *preference = lease->preference;
112
113 return 0;
114 }
115
116 int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
117 assert_return(lease, -EINVAL);
118
119 lease->rapid_commit = true;
120
121 return 0;
122 }
123
124 int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
125 assert_return(lease, -EINVAL);
126 assert_return(rapid_commit, -EINVAL);
127
128 *rapid_commit = lease->rapid_commit;
129
130 return 0;
131 }
132
133 int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
134 uint32_t *lifetime_preferred,
135 uint32_t *lifetime_valid) {
136 assert_return(lease, -EINVAL);
137 assert_return(addr, -EINVAL);
138 assert_return(lifetime_preferred, -EINVAL);
139 assert_return(lifetime_valid, -EINVAL);
140
141 if (!lease->addr_iter)
142 return -ENOMSG;
143
144 memcpy(addr, &lease->addr_iter->iaaddr.address,
145 sizeof(struct in6_addr));
146 *lifetime_preferred =
147 be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
148 *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);
149
150 lease->addr_iter = lease->addr_iter->addresses_next;
151
152 return 0;
153 }
154
155 void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
156 if (lease)
157 lease->addr_iter = lease->ia.addresses;
158 }
159
160 int sd_dhcp6_lease_get_pd(sd_dhcp6_lease *lease, struct in6_addr *prefix,
161 uint8_t *prefix_len,
162 uint32_t *lifetime_preferred,
163 uint32_t *lifetime_valid) {
164 assert_return(lease, -EINVAL);
165 assert_return(prefix, -EINVAL);
166 assert_return(prefix_len, -EINVAL);
167 assert_return(lifetime_preferred, -EINVAL);
168 assert_return(lifetime_valid, -EINVAL);
169
170 if (!lease->prefix_iter)
171 return -ENOMSG;
172
173 memcpy(prefix, &lease->prefix_iter->iapdprefix.address,
174 sizeof(struct in6_addr));
175 *prefix_len = lease->prefix_iter->iapdprefix.prefixlen;
176 *lifetime_preferred =
177 be32toh(lease->prefix_iter->iapdprefix.lifetime_preferred);
178 *lifetime_valid =
179 be32toh(lease->prefix_iter->iapdprefix.lifetime_valid);
180
181 lease->prefix_iter = lease->prefix_iter->addresses_next;
182
183 return 0;
184 }
185
186 void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) {
187 if (lease)
188 lease->prefix_iter = lease->pd.addresses;
189 }
190
191 int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
192 assert_return(lease, -EINVAL);
193 assert_return(optval, -EINVAL);
194
195 if (optlen == 0)
196 return 0;
197
198 return dhcp6_option_parse_addresses(optval, optlen, &lease->dns, &lease->dns_count);
199 }
200
201 int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
202 assert_return(lease, -EINVAL);
203 assert_return(ret, -EINVAL);
204
205 if (!lease->dns)
206 return -ENOENT;
207
208 *ret = lease->dns;
209 return lease->dns_count;
210 }
211
212 int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
213 _cleanup_strv_free_ char **domains = NULL;
214 int r;
215
216 assert_return(lease, -EINVAL);
217 assert_return(optval, -EINVAL);
218
219 if (optlen == 0)
220 return 0;
221
222 r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
223 if (r < 0)
224 return r;
225
226 return strv_extend_strv(&lease->domains, domains, true);
227 }
228
229 int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret) {
230 assert_return(lease, -EINVAL);
231 assert_return(ret, -EINVAL);
232
233 if (!lease->domains)
234 return -ENOENT;
235
236 *ret = lease->domains;
237 return strv_length(lease->domains);
238 }
239
240 int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
241 int r;
242
243 assert_return(lease, -EINVAL);
244 assert_return(optval, -EINVAL);
245
246 for (size_t offset = 0; offset < optlen;) {
247 const uint8_t *subval;
248 size_t sublen;
249 uint16_t subopt;
250
251 r = dhcp6_option_parse(optval, optlen, &offset, &subopt, &sublen, &subval);
252 if (r < 0)
253 return r;
254
255 switch(subopt) {
256 case DHCP6_NTP_SUBOPTION_SRV_ADDR:
257 case DHCP6_NTP_SUBOPTION_MC_ADDR:
258 if (sublen != 16)
259 return 0;
260
261 r = dhcp6_option_parse_addresses(subval, sublen, &lease->ntp, &lease->ntp_count);
262 if (r < 0)
263 return r;
264
265 break;
266
267 case DHCP6_NTP_SUBOPTION_SRV_FQDN: {
268 _cleanup_free_ char *server = NULL;
269
270 r = dhcp6_option_parse_domainname(subval, sublen, &server);
271 if (r < 0)
272 return r;
273
274 if (strv_contains(lease->ntp_fqdn, server))
275 continue;
276
277 r = strv_consume(&lease->ntp_fqdn, TAKE_PTR(server));
278 if (r < 0)
279 return r;
280
281 break;
282 }}
283 }
284
285 return 0;
286 }
287
288 int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
289 assert_return(lease, -EINVAL);
290 assert_return(optval, -EINVAL);
291
292 if (optlen == 0)
293 return 0;
294
295 /* SNTP option is defined in RFC4075, and deprecated by RFC5908. */
296 return dhcp6_option_parse_addresses(optval, optlen, &lease->sntp, &lease->sntp_count);
297 }
298
299 int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
300 assert_return(lease, -EINVAL);
301 assert_return(ret, -EINVAL);
302
303 if (lease->ntp) {
304 *ret = lease->ntp;
305 return lease->ntp_count;
306 }
307
308 if (lease->sntp && !lease->ntp_fqdn) {
309 /* Fallback to the deprecated SNTP option. */
310 *ret = lease->sntp;
311 return lease->sntp_count;
312 }
313
314 return -ENOENT;
315 }
316
317 int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
318 assert_return(lease, -EINVAL);
319 assert_return(ret, -EINVAL);
320
321 if (!lease->ntp_fqdn)
322 return -ENOENT;
323
324 *ret = lease->ntp_fqdn;
325 return strv_length(lease->ntp_fqdn);
326 }
327
328 int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
329 int r;
330 char *fqdn;
331
332 assert_return(lease, -EINVAL);
333 assert_return(optval, -EINVAL);
334
335 if (optlen < 2)
336 return -ENODATA;
337
338 /* Ignore the flags field, it doesn't carry any useful
339 information for clients. */
340 r = dhcp6_option_parse_domainname(optval + 1, optlen - 1, &fqdn);
341 if (r < 0)
342 return r;
343
344 return free_and_replace(lease->fqdn, fqdn);
345 }
346
347 int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **ret) {
348 assert_return(lease, -EINVAL);
349 assert_return(ret, -EINVAL);
350
351 if (!lease->fqdn)
352 return -ENOENT;
353
354 *ret = lease->fqdn;
355 return 0;
356 }
357
358 static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
359 if (!lease)
360 return NULL;
361
362 free(lease->serverid);
363 dhcp6_lease_free_ia(&lease->ia);
364 dhcp6_lease_free_ia(&lease->pd);
365 free(lease->dns);
366 free(lease->fqdn);
367 strv_free(lease->domains);
368 free(lease->ntp);
369 strv_free(lease->ntp_fqdn);
370 free(lease->sntp);
371
372 return mfree(lease);
373 }
374
375 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_lease, sd_dhcp6_lease, dhcp6_lease_free);
376
377 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
378 sd_dhcp6_lease *lease;
379
380 lease = new0(sd_dhcp6_lease, 1);
381 if (!lease)
382 return -ENOMEM;
383
384 lease->n_ref = 1;
385
386 LIST_HEAD_INIT(lease->ia.addresses);
387
388 *ret = lease;
389 return 0;
390 }