Line data Source code
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 7 : int dhcp6_lease_clear_timers(DHCP6IA *ia) {
28 7 : assert_return(ia, -EINVAL);
29 :
30 7 : ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
31 7 : ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
32 :
33 7 : return 0;
34 : }
35 :
36 0 : int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
37 : DHCP6Address *addr;
38 0 : uint32_t valid = 0, t;
39 :
40 0 : assert_return(ia, -EINVAL);
41 0 : assert_return(expire, -EINVAL);
42 :
43 0 : LIST_FOREACH(addresses, addr, ia->addresses) {
44 0 : t = be32toh(addr->iaaddr.lifetime_valid);
45 0 : if (valid < t)
46 0 : valid = t;
47 : }
48 :
49 0 : t = be32toh(ia->lifetime_t2);
50 0 : if (t > valid)
51 0 : return -EINVAL;
52 :
53 0 : *expire = valid - t;
54 :
55 0 : return 0;
56 : }
57 :
58 6 : DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
59 : DHCP6Address *address;
60 :
61 6 : if (!ia)
62 0 : return NULL;
63 :
64 6 : dhcp6_lease_clear_timers(ia);
65 :
66 16 : while (ia->addresses) {
67 4 : address = ia->addresses;
68 :
69 4 : LIST_REMOVE(addresses, ia->addresses, address);
70 :
71 4 : free(address);
72 : }
73 :
74 6 : return NULL;
75 : }
76 :
77 4 : int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
78 : size_t len) {
79 4 : assert_return(lease, -EINVAL);
80 4 : assert_return(id, -EINVAL);
81 :
82 4 : free(lease->serverid);
83 :
84 4 : lease->serverid = memdup(id, len);
85 4 : if (!lease->serverid)
86 0 : return -EINVAL;
87 :
88 4 : lease->serverid_len = len;
89 :
90 4 : return 0;
91 : }
92 :
93 6 : int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
94 6 : assert_return(lease, -EINVAL);
95 6 : assert_return(id, -EINVAL);
96 6 : assert_return(len, -EINVAL);
97 :
98 6 : *id = lease->serverid;
99 6 : *len = lease->serverid_len;
100 :
101 6 : return 0;
102 : }
103 :
104 2 : int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
105 2 : assert_return(lease, -EINVAL);
106 :
107 2 : lease->preference = preference;
108 :
109 2 : return 0;
110 : }
111 :
112 3 : int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
113 3 : assert_return(preference, -EINVAL);
114 :
115 3 : if (!lease)
116 1 : return -EINVAL;
117 :
118 2 : *preference = lease->preference;
119 :
120 2 : return 0;
121 : }
122 :
123 0 : int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
124 0 : assert_return(lease, -EINVAL);
125 :
126 0 : lease->rapid_commit = true;
127 :
128 0 : return 0;
129 : }
130 :
131 0 : int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
132 0 : assert_return(lease, -EINVAL);
133 0 : assert_return(rapid_commit, -EINVAL);
134 :
135 0 : *rapid_commit = lease->rapid_commit;
136 :
137 0 : return 0;
138 : }
139 :
140 2 : int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
141 2 : assert_return(lease, -EINVAL);
142 2 : assert_return(iaid, -EINVAL);
143 :
144 2 : *iaid = lease->ia.id;
145 :
146 2 : return 0;
147 : }
148 :
149 9 : int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
150 : uint32_t *lifetime_preferred,
151 : uint32_t *lifetime_valid) {
152 9 : assert_return(lease, -EINVAL);
153 9 : assert_return(addr, -EINVAL);
154 9 : assert_return(lifetime_preferred, -EINVAL);
155 9 : assert_return(lifetime_valid, -EINVAL);
156 :
157 9 : if (!lease->addr_iter)
158 5 : return -ENOMSG;
159 :
160 4 : memcpy(addr, &lease->addr_iter->iaaddr.address,
161 : sizeof(struct in6_addr));
162 4 : *lifetime_preferred =
163 4 : be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
164 4 : *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);
165 :
166 4 : lease->addr_iter = lease->addr_iter->addresses_next;
167 :
168 4 : return 0;
169 : }
170 :
171 5 : void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
172 5 : if (lease)
173 5 : lease->addr_iter = lease->ia.addresses;
174 5 : }
175 :
176 0 : sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
177 0 : if (lease)
178 0 : assert_se(REFCNT_INC(lease->n_ref) >= 2);
179 :
180 0 : return lease;
181 : }
182 :
183 8 : sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
184 8 : if (lease && REFCNT_DEC(lease->n_ref) == 0) {
185 6 : free(lease->serverid);
186 6 : dhcp6_lease_free_ia(&lease->ia);
187 :
188 6 : free(lease);
189 : }
190 :
191 8 : return NULL;
192 : }
193 :
194 6 : int dhcp6_lease_new(sd_dhcp6_lease **ret) {
195 : sd_dhcp6_lease *lease;
196 :
197 6 : lease = new0(sd_dhcp6_lease, 1);
198 6 : if (!lease)
199 0 : return -ENOMEM;
200 :
201 6 : lease->n_ref = REFCNT_INIT;
202 :
203 6 : LIST_HEAD_INIT(lease->ia.addresses);
204 :
205 6 : *ret = lease;
206 6 : return 0;
207 : }
|