chiark / gitweb /
sd-bus: rework ELF error mapping table magic
[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->iaaddr.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->iaaddr.address,
160                 sizeof(struct in6_addr));
161         *lifetime_preferred =
162                 be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
163         *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);
164
165         lease->addr_iter = lease->addr_iter->addresses_next;
166
167         return 0;
168 }
169
170 int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease,
171                                      struct in6_addr *addr,
172                                      uint32_t *lifetime_preferred,
173                                      uint32_t *lifetime_valid) {
174         assert_return(lease, -EINVAL);
175         assert_return(addr, -EINVAL);
176         assert_return(lifetime_preferred, -EINVAL);
177         assert_return(lifetime_valid, -EINVAL);
178
179         if (!lease->ia.addresses)
180                 return -ENOMSG;
181
182         lease->addr_iter = lease->ia.addresses;
183
184         return sd_dhcp6_lease_get_next_address(lease, addr, lifetime_preferred,
185                                                lifetime_valid);
186 }
187
188 sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
189         if (lease)
190                 assert_se(REFCNT_INC(lease->n_ref) >= 2);
191
192         return lease;
193 }
194
195 sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
196         if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
197                 free(lease->serverid);
198                 dhcp6_lease_free_ia(&lease->ia);
199
200                 free(lease);
201         }
202
203         return NULL;
204 }
205
206 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
207         sd_dhcp6_lease *lease;
208
209         lease = new0(sd_dhcp6_lease, 1);
210         if (!lease)
211                 return -ENOMEM;
212
213         lease->n_ref = REFCNT_INIT;
214
215         LIST_HEAD_INIT(lease->ia.addresses);
216
217         *ret = lease;
218         return 0;
219 }