chiark / gitweb /
cbda7d8c84bb8932ce811c474d625feaf7c7b38a
[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 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
37         DHCP6Address *address;
38
39         if (!ia)
40                 return NULL;
41
42         dhcp6_lease_clear_timers(ia);
43
44         while (ia->addresses) {
45                 address = ia->addresses;
46
47                 LIST_REMOVE(addresses, ia->addresses, address);
48
49                 free(address);
50         }
51
52         return NULL;
53 }
54
55 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
56                              size_t len) {
57         assert_return(lease, -EINVAL);
58         assert_return(id, -EINVAL);
59
60         free(lease->serverid);
61
62         lease->serverid = memdup(id, len);
63         if (!lease->serverid)
64                 return -EINVAL;
65
66         lease->serverid_len = len;
67
68         return 0;
69 }
70
71 int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
72         assert_return(lease, -EINVAL);
73         assert_return(id, -EINVAL);
74         assert_return(len, -EINVAL);
75
76         *id = lease->serverid;
77         *len = lease->serverid_len;
78
79         return 0;
80 }
81
82 int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
83         assert_return(lease, -EINVAL);
84
85         lease->preference = preference;
86
87         return 0;
88 }
89
90 int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
91         assert_return(lease, -EINVAL);
92         assert_return(preference, -EINVAL);
93
94         *preference = lease->preference;
95
96         return 0;
97 }
98
99 int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
100         assert_return(lease, -EINVAL);
101         assert_return(iaid, -EINVAL);
102
103         *iaid = lease->ia.id;
104
105         return 0;
106 }
107
108 int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease,
109                                     struct in6_addr *addr,
110                                     uint32_t *lifetime_preferred,
111                                     uint32_t *lifetime_valid) {
112         assert_return(lease, -EINVAL);
113         assert_return(addr, -EINVAL);
114         assert_return(lifetime_preferred, -EINVAL);
115         assert_return(lifetime_valid, -EINVAL);
116
117         if (!lease->addr_iter)
118                 return -ENOMSG;
119
120         memcpy(addr, &lease->addr_iter->address, sizeof(struct in6_addr));
121         *lifetime_preferred = be32toh(lease->addr_iter->lifetime_preferred);
122         *lifetime_valid = be32toh(lease->addr_iter->lifetime_valid);
123
124         lease->addr_iter = lease->addr_iter->addresses_next;
125
126         return 0;
127 }
128
129 int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease,
130                                      struct in6_addr *addr,
131                                      uint32_t *lifetime_preferred,
132                                      uint32_t *lifetime_valid) {
133         assert_return(lease, -EINVAL);
134         assert_return(addr, -EINVAL);
135         assert_return(lifetime_preferred, -EINVAL);
136         assert_return(lifetime_valid, -EINVAL);
137
138         if (!lease->ia.addresses)
139                 return -ENOMSG;
140
141         lease->addr_iter = lease->ia.addresses;
142
143         return sd_dhcp6_lease_get_next_address(lease, addr, lifetime_preferred,
144                                                lifetime_valid);
145 }
146
147 sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
148         if (lease)
149                 assert_se(REFCNT_INC(lease->n_ref) >= 2);
150
151         return lease;
152 }
153
154 sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
155         if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
156                 free(lease->serverid);
157                 dhcp6_lease_free_ia(&lease->ia);
158
159                 free(lease);
160         }
161
162         return NULL;
163 }
164
165 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
166         sd_dhcp6_lease *lease;
167
168         lease = new0(sd_dhcp6_lease, 1);
169         if (!lease)
170                 return -ENOMEM;
171
172         lease->n_ref = REFCNT_INIT;
173
174         LIST_HEAD_INIT(lease->ia.addresses);
175
176         *ret = lease;
177         return 0;
178 }