chiark / gitweb /
service: minor modernization
[elogind.git] / src / libsystemd-network / sd-dhcp6-lease.c
1 /***
2   This file is part of systemd.
3
4   Copyright (C) 2014 Tom Gundersen
5   Copyright (C) 2014 Intel Corporation. All rights reserved.
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22
23 #include "util.h"
24
25 #include "dhcp6-lease-internal.h"
26
27 int dhcp6_lease_clear_timers(DHCP6IA *ia) {
28         assert_return(ia, -EINVAL);
29
30         ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
31         ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
32
33         return 0;
34 }
35
36 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
37         DHCP6Address *addr;
38         uint32_t valid = 0, t;
39
40         assert_return(ia, -EINVAL);
41         assert_return(expire, -EINVAL);
42
43         LIST_FOREACH(addresses, addr, ia->addresses) {
44                 t = be32toh(addr->lifetime_valid);
45                 if (valid < t)
46                         valid = t;
47         }
48
49         t = be32toh(ia->lifetime_t2);
50         if (t > valid)
51                 return -EINVAL;
52
53         *expire = valid - t;
54
55         return 0;
56 }
57
58 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
59         DHCP6Address *address;
60
61         if (!ia)
62                 return NULL;
63
64         dhcp6_lease_clear_timers(ia);
65
66         while (ia->addresses) {
67                 address = ia->addresses;
68
69                 LIST_REMOVE(addresses, ia->addresses, address);
70
71                 free(address);
72         }
73
74         return NULL;
75 }
76
77 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
78                              size_t len) {
79         assert_return(lease, -EINVAL);
80         assert_return(id, -EINVAL);
81
82         free(lease->serverid);
83
84         lease->serverid = memdup(id, len);
85         if (!lease->serverid)
86                 return -EINVAL;
87
88         lease->serverid_len = len;
89
90         return 0;
91 }
92
93 int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
94         assert_return(lease, -EINVAL);
95         assert_return(id, -EINVAL);
96         assert_return(len, -EINVAL);
97
98         *id = lease->serverid;
99         *len = lease->serverid_len;
100
101         return 0;
102 }
103
104 int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
105         assert_return(lease, -EINVAL);
106
107         lease->preference = preference;
108
109         return 0;
110 }
111
112 int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
113         assert_return(lease, -EINVAL);
114         assert_return(preference, -EINVAL);
115
116         *preference = lease->preference;
117
118         return 0;
119 }
120
121 int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
122         assert_return(lease, -EINVAL);
123
124         lease->rapid_commit = true;
125
126         return 0;
127 }
128
129 int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
130         assert_return(lease, -EINVAL);
131         assert_return(rapid_commit, -EINVAL);
132
133         *rapid_commit = lease->rapid_commit;
134
135         return 0;
136 }
137
138 int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
139         assert_return(lease, -EINVAL);
140         assert_return(iaid, -EINVAL);
141
142         *iaid = lease->ia.id;
143
144         return 0;
145 }
146
147 int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease,
148                                     struct in6_addr *addr,
149                                     uint32_t *lifetime_preferred,
150                                     uint32_t *lifetime_valid) {
151         assert_return(lease, -EINVAL);
152         assert_return(addr, -EINVAL);
153         assert_return(lifetime_preferred, -EINVAL);
154         assert_return(lifetime_valid, -EINVAL);
155
156         if (!lease->addr_iter)
157                 return -ENOMSG;
158
159         memcpy(addr, &lease->addr_iter->address, sizeof(struct in6_addr));
160         *lifetime_preferred = be32toh(lease->addr_iter->lifetime_preferred);
161         *lifetime_valid = be32toh(lease->addr_iter->lifetime_valid);
162
163         lease->addr_iter = lease->addr_iter->addresses_next;
164
165         return 0;
166 }
167
168 int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease,
169                                      struct in6_addr *addr,
170                                      uint32_t *lifetime_preferred,
171                                      uint32_t *lifetime_valid) {
172         assert_return(lease, -EINVAL);
173         assert_return(addr, -EINVAL);
174         assert_return(lifetime_preferred, -EINVAL);
175         assert_return(lifetime_valid, -EINVAL);
176
177         if (!lease->ia.addresses)
178                 return -ENOMSG;
179
180         lease->addr_iter = lease->ia.addresses;
181
182         return sd_dhcp6_lease_get_next_address(lease, addr, lifetime_preferred,
183                                                lifetime_valid);
184 }
185
186 sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
187         if (lease)
188                 assert_se(REFCNT_INC(lease->n_ref) >= 2);
189
190         return lease;
191 }
192
193 sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
194         if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
195                 free(lease->serverid);
196                 dhcp6_lease_free_ia(&lease->ia);
197
198                 free(lease);
199         }
200
201         return NULL;
202 }
203
204 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
205         sd_dhcp6_lease *lease;
206
207         lease = new0(sd_dhcp6_lease, 1);
208         if (!lease)
209                 return -ENOMEM;
210
211         lease->n_ref = REFCNT_INIT;
212
213         LIST_HEAD_INIT(lease->ia.addresses);
214
215         *ret = lease;
216         return 0;
217 }