Bug Summary

File:build-scan/../src/libsystemd-network/sd-dhcp-lease.c
Warning:line 273, column 17
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sd-dhcp-lease.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/libsystemd-network/libsystemd-network.a.p -I src/libsystemd-network -I ../src/libsystemd-network -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd-network/sd-dhcp-lease.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3 Copyright © 2013 Intel Corporation. All rights reserved.
4***/
5
6#include <arpa/inet.h>
7#include <errno(*__errno_location ()).h>
8#include <stdio.h>
9#include <stdio_ext.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "sd-dhcp-lease.h"
14
15#include "alloc-util.h"
16#include "dhcp-lease-internal.h"
17#include "dhcp-protocol.h"
18#include "dns-domain.h"
19#include "fd-util.h"
20#include "fileio.h"
21#include "hexdecoct.h"
22#include "hostname-util.h"
23#include "in-addr-util.h"
24#include "network-internal.h"
25#include "parse-util.h"
26#include "stdio-util.h"
27#include "string-util.h"
28#include "unaligned.h"
29
30int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
31 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 31, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
32 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 32, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
33
34 if (lease->address == 0)
35 return -ENODATA61;
36
37 addr->s_addr = lease->address;
38 return 0;
39}
40
41int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr) {
42 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 42, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
43 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 43, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
44
45 if (!lease->have_broadcast)
46 return -ENODATA61;
47
48 addr->s_addr = lease->broadcast;
49 return 0;
50}
51
52int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
53 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 53, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
54 assert_return(lifetime, -EINVAL)do { if (!(((__builtin_expect(!!(lifetime),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lifetime"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 54, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
55
56 if (lease->lifetime <= 0)
57 return -ENODATA61;
58
59 *lifetime = lease->lifetime;
60 return 0;
61}
62
63int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1) {
64 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 64, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
65 assert_return(t1, -EINVAL)do { if (!(((__builtin_expect(!!(t1),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("t1"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 65, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
66
67 if (lease->t1 <= 0)
68 return -ENODATA61;
69
70 *t1 = lease->t1;
71 return 0;
72}
73
74int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2) {
75 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 75, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
76 assert_return(t2, -EINVAL)do { if (!(((__builtin_expect(!!(t2),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("t2"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 76, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
77
78 if (lease->t2 <= 0)
79 return -ENODATA61;
80
81 *t2 = lease->t2;
82 return 0;
83}
84
85int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
86 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 86, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
87 assert_return(mtu, -EINVAL)do { if (!(((__builtin_expect(!!(mtu),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("mtu"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 87, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
88
89 if (lease->mtu <= 0)
90 return -ENODATA61;
91
92 *mtu = lease->mtu;
93 return 0;
94}
95
96int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
97 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 97, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
98 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 98, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
99
100 if (lease->dns_size <= 0)
101 return -ENODATA61;
102
103 *addr = lease->dns;
104 return (int) lease->dns_size;
105}
106
107int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
108 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 108, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
109 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 109, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
110
111 if (lease->ntp_size <= 0)
112 return -ENODATA61;
113
114 *addr = lease->ntp;
115 return (int) lease->ntp_size;
116}
117
118int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
119 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 119, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
120 assert_return(domainname, -EINVAL)do { if (!(((__builtin_expect(!!(domainname),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("domainname"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 120, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
121
122 if (!lease->domainname)
123 return -ENODATA61;
124
125 *domainname = lease->domainname;
126 return 0;
127}
128
129int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
130 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 130, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
131 assert_return(hostname, -EINVAL)do { if (!(((__builtin_expect(!!(hostname),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("hostname"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 131, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
132
133 if (!lease->hostname)
134 return -ENODATA61;
135
136 *hostname = lease->hostname;
137 return 0;
138}
139
140int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
141 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 141, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
142 assert_return(root_path, -EINVAL)do { if (!(((__builtin_expect(!!(root_path),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("root_path"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 142, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
143
144 if (!lease->root_path)
145 return -ENODATA61;
146
147 *root_path = lease->root_path;
148 return 0;
149}
150
151int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
152 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 152, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
153 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 153, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
154
155 if (lease->router == 0)
156 return -ENODATA61;
157
158 addr->s_addr = lease->router;
159 return 0;
160}
161
162int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
163 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 163, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
164 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 164, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
165
166 if (!lease->have_subnet_mask)
167 return -ENODATA61;
168
169 addr->s_addr = lease->subnet_mask;
170 return 0;
171}
172
173int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) {
174 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 174, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
175 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 175, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
176
177 if (lease->server_address == 0)
178 return -ENODATA61;
179
180 addr->s_addr = lease->server_address;
181 return 0;
182}
183
184int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
185 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 185, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
186 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 186, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
187
188 if (lease->next_server == 0)
189 return -ENODATA61;
190
191 addr->s_addr = lease->next_server;
192 return 0;
193}
194
195/*
196 * The returned routes array must be freed by the caller.
197 * Route objects have the same lifetime of the lease and must not be freed.
198 */
199int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
200 sd_dhcp_route **ret;
201 unsigned i;
202
203 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 203, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
204 assert_return(routes, -EINVAL)do { if (!(((__builtin_expect(!!(routes),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("routes"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 204, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
205
206 if (lease->static_route_size <= 0)
207 return -ENODATA61;
208
209 ret = new(sd_dhcp_route *, lease->static_route_size)((sd_dhcp_route **) malloc_multiply(sizeof(sd_dhcp_route *), (
lease->static_route_size)))
;
210 if (!ret)
211 return -ENOMEM12;
212
213 for (i = 0; i < lease->static_route_size; i++)
214 ret[i] = &lease->static_route[i];
215
216 *routes = ret;
217 return (int) lease->static_route_size;
218}
219
220int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
221 size_t r;
222
223 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 223, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
224 assert_return(domains, -EINVAL)do { if (!(((__builtin_expect(!!(domains),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("domains"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 224, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
225
226 r = strv_length(lease->search_domains);
227 if (r > 0) {
228 *domains = lease->search_domains;
229 return (int) r;
230 }
231
232 return -ENODATA61;
233}
234
235int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
236 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 236, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
237 assert_return(data, -EINVAL)do { if (!(((__builtin_expect(!!(data),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 237, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
238 assert_return(data_len, -EINVAL)do { if (!(((__builtin_expect(!!(data_len),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("data_len"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 238, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
239
240 if (lease->vendor_specific_len <= 0)
241 return -ENODATA61;
242
243 *data = lease->vendor_specific;
244 *data_len = lease->vendor_specific_len;
245 return 0;
246}
247
248sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
249
250 if (!lease)
251 return NULL((void*)0);
252
253 assert(lease->n_ref >= 1)do { if ((__builtin_expect(!!(!(lease->n_ref >= 1)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("lease->n_ref >= 1"
), "../src/libsystemd-network/sd-dhcp-lease.c", 253, __PRETTY_FUNCTION__
); } while (0)
;
254 lease->n_ref++;
255
256 return lease;
257}
258
259sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
260
261 if (!lease)
1
Assuming 'lease' is non-null
2
Taking false branch
262 return NULL((void*)0);
263
264 assert(lease->n_ref >= 1)do { if ((__builtin_expect(!!(!(lease->n_ref >= 1)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("lease->n_ref >= 1"
), "../src/libsystemd-network/sd-dhcp-lease.c", 264, __PRETTY_FUNCTION__
); } while (0)
;
3
Assuming field 'n_ref' is >= 1
4
Taking false branch
5
Loop condition is false. Exiting loop
265 lease->n_ref--;
266
267 if (lease->n_ref > 0)
6
Assuming field 'n_ref' is <= 0
7
Taking false branch
268 return NULL((void*)0);
269
270 while (lease->private_options) {
8
Loop condition is true. Entering loop body
17
Loop condition is true. Entering loop body
271 struct sd_dhcp_raw_option *option = lease->private_options;
272
273 LIST_REMOVE(options, lease->private_options, option)do { typeof(*(lease->private_options)) **_head = &(lease
->private_options), *_item = (option); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd-network/sd-dhcp-lease.c", 273,
__PRETTY_FUNCTION__); } while (0); if (_item->options_next
) _item->options_next->options_prev = _item->options_prev
; if (_item->options_prev) _item->options_prev->options_next
= _item->options_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 273, __PRETTY_FUNCTION__); } while (0); *_head = _item->
options_next; } _item->options_next = _item->options_prev
= ((void*)0); } while (0)
;
9
Taking false branch
10
Loop condition is false. Exiting loop
11
Assuming field 'options_next' is null
12
Taking false branch
13
Assuming field 'options_prev' is non-null
14
Taking true branch
15
Loop condition is false. Exiting loop
18
Taking false branch
19
Loop condition is false. Exiting loop
20
Use of memory after it is freed
274
275 free(option->data);
276 free(option);
16
Memory is released
277 }
278
279 free(lease->hostname);
280 free(lease->domainname);
281 free(lease->dns);
282 free(lease->ntp);
283 free(lease->static_route);
284 free(lease->client_id);
285 free(lease->vendor_specific);
286 strv_free(lease->search_domains);
287 return mfree(lease);
288}
289
290static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
291 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 291, __PRETTY_FUNCTION__); } while (0)
;
292 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 292, __PRETTY_FUNCTION__); } while (0)
;
293
294 if (len != 4)
295 return -EINVAL22;
296
297 *ret = unaligned_read_be32((be32_t*) option);
298 if (*ret < min)
299 *ret = min;
300
301 return 0;
302}
303
304static int lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
305 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 305, __PRETTY_FUNCTION__); } while (0)
;
306 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 306, __PRETTY_FUNCTION__); } while (0)
;
307
308 if (len != 2)
309 return -EINVAL22;
310
311 *ret = unaligned_read_be16((be16_t*) option);
312 if (*ret < min)
313 *ret = min;
314
315 return 0;
316}
317
318static int lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
319 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 319, __PRETTY_FUNCTION__); } while (0)
;
320 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 320, __PRETTY_FUNCTION__); } while (0)
;
321
322 if (len != 4)
323 return -EINVAL22;
324
325 memcpy(ret, option, 4);
326 return 0;
327}
328
329static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
330 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 330, __PRETTY_FUNCTION__); } while (0)
;
331 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 331, __PRETTY_FUNCTION__); } while (0)
;
332
333 if (len <= 0)
334 *ret = mfree(*ret);
335 else {
336 char *string;
337
338 /*
339 * One trailing NUL byte is OK, we don't mind. See:
340 * https://github.com/systemd/systemd/issues/1337
341 */
342 if (memchr(option, 0, len - 1))
343 return -EINVAL22;
344
345 string = strndup((const char *) option, len);
346 if (!string)
347 return -ENOMEM12;
348
349 free(*ret);
350 *ret = string;
351 }
352
353 return 0;
354}
355
356static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
357 _cleanup_free___attribute__((cleanup(freep))) char *name = NULL((void*)0), *normalized = NULL((void*)0);
358 int r;
359
360 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 360, __PRETTY_FUNCTION__); } while (0)
;
361 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 361, __PRETTY_FUNCTION__); } while (0)
;
362
363 r = lease_parse_string(option, len, &name);
364 if (r < 0)
365 return r;
366 if (!name) {
367 *ret = mfree(*ret);
368 return 0;
369 }
370
371 r = dns_name_normalize(name, &normalized);
372 if (r < 0)
373 return r;
374
375 if (is_localhost(normalized))
376 return -EINVAL22;
377
378 if (dns_name_is_root(normalized))
379 return -EINVAL22;
380
381 free_and_replace(*ret, normalized)({ free(*ret); (*ret) = (normalized); (normalized) = ((void*)
0); 0; })
;
382
383 return 0;
384}
385
386static void filter_bogus_addresses(struct in_addr *addresses, size_t *n) {
387 size_t i, j;
388
389 /* Silently filter DNS/NTP servers supplied to us that do not make outside of the local scope. */
390
391 for (i = 0, j = 0; i < *n; i ++) {
392
393 if (in4_addr_is_null(addresses+i) ||
394 in4_addr_is_localhost(addresses+i))
395 continue;
396
397 addresses[j++] = addresses[i];
398 }
399
400 *n = j;
401}
402
403static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
404 assert(option)do { if ((__builtin_expect(!!(!(option)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 404, __PRETTY_FUNCTION__); } while (0)
;
405 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 405, __PRETTY_FUNCTION__); } while (0)
;
406 assert(n_ret)do { if ((__builtin_expect(!!(!(n_ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("n_ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 406, __PRETTY_FUNCTION__); } while (0)
;
407
408 if (len <= 0) {
409 *ret = mfree(*ret);
410 *n_ret = 0;
411 } else {
412 size_t n_addresses;
413 struct in_addr *addresses;
414
415 if (len % 4 != 0)
416 return -EINVAL22;
417
418 n_addresses = len / 4;
419
420 addresses = newdup(struct in_addr, option, n_addresses)((struct in_addr*) memdup_multiply(option, sizeof(struct in_addr
), (n_addresses)))
;
421 if (!addresses)
422 return -ENOMEM12;
423
424 filter_bogus_addresses(addresses, &n_addresses);
425
426 free(*ret);
427 *ret = addresses;
428 *n_ret = n_addresses;
429 }
430
431 return 0;
432}
433
434static int lease_parse_routes(
435 const uint8_t *option, size_t len,
436 struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
437
438 struct in_addr addr;
439
440 assert(option || len <= 0)do { if ((__builtin_expect(!!(!(option || len <= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option || len <= 0"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 440, __PRETTY_FUNCTION__); } while (0)
;
441 assert(routes)do { if ((__builtin_expect(!!(!(routes)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 441, __PRETTY_FUNCTION__); } while (0)
;
442 assert(routes_size)do { if ((__builtin_expect(!!(!(routes_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes_size"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 442, __PRETTY_FUNCTION__); } while (0)
;
443 assert(routes_allocated)do { if ((__builtin_expect(!!(!(routes_allocated)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes_allocated"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 443, __PRETTY_FUNCTION__); } while (0)
;
444
445 if (len <= 0)
446 return 0;
447
448 if (len % 8 != 0)
449 return -EINVAL22;
450
451 if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + (len / 8))greedy_realloc((void**) &(*routes), &(*routes_allocated
), (*routes_size + (len / 8)), sizeof((*routes)[0]))
)
452 return -ENOMEM12;
453
454 while (len >= 8) {
455 struct sd_dhcp_route *route = *routes + *routes_size;
456 int r;
457
458 route->option = SD_DHCP_OPTION_STATIC_ROUTE;
459 r = in4_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen);
460 if (r < 0) {
461 log_debug("Failed to determine destination prefix length from class based IP, ignoring")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 461, __func__,
"Failed to determine destination prefix length from class based IP, ignoring"
) : -abs(_e); })
;
462 continue;
463 }
464
465 assert_se(lease_parse_be32(option, 4, &addr.s_addr) >= 0)do { if ((__builtin_expect(!!(!(lease_parse_be32(option, 4, &
addr.s_addr) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("lease_parse_be32(option, 4, &addr.s_addr) >= 0"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 465, __PRETTY_FUNCTION__); } while (0)
;
466 route->dst_addr = inet_makeaddr(inet_netof(addr), 0);
467 option += 4;
468
469 assert_se(lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0)do { if ((__builtin_expect(!!(!(lease_parse_be32(option, 4, &
route->gw_addr.s_addr) >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0"
), "../src/libsystemd-network/sd-dhcp-lease.c", 469, __PRETTY_FUNCTION__
); } while (0)
;
470 option += 4;
471
472 len -= 8;
473 (*routes_size)++;
474 }
475
476 return 0;
477}
478
479/* parses RFC3442 Classless Static Route Option */
480static int lease_parse_classless_routes(
481 const uint8_t *option, size_t len,
482 struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
483
484 assert(option || len <= 0)do { if ((__builtin_expect(!!(!(option || len <= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("option || len <= 0"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 484, __PRETTY_FUNCTION__); } while (0)
;
485 assert(routes)do { if ((__builtin_expect(!!(!(routes)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 485, __PRETTY_FUNCTION__); } while (0)
;
486 assert(routes_size)do { if ((__builtin_expect(!!(!(routes_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes_size"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 486, __PRETTY_FUNCTION__); } while (0)
;
487 assert(routes_allocated)do { if ((__builtin_expect(!!(!(routes_allocated)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("routes_allocated"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 487, __PRETTY_FUNCTION__); } while (0)
;
488
489 if (len <= 0)
490 return 0;
491
492 /* option format: (subnet-mask-width significant-subnet-octets gateway-ip)* */
493
494 while (len > 0) {
495 uint8_t dst_octets;
496 struct sd_dhcp_route *route;
497
498 if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1)greedy_realloc((void**) &(*routes), &(*routes_allocated
), (*routes_size + 1), sizeof((*routes)[0]))
)
499 return -ENOMEM12;
500
501 route = *routes + *routes_size;
502 route->option = SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE;
503
504 dst_octets = (*option == 0 ? 0 : ((*option - 1) / 8) + 1);
505 route->dst_prefixlen = *option;
506 option++;
507 len--;
508
509 /* can't have more than 4 octets in IPv4 */
510 if (dst_octets > 4 || len < dst_octets)
511 return -EINVAL22;
512
513 route->dst_addr.s_addr = 0;
514 memcpy(&route->dst_addr.s_addr, option, dst_octets);
515 option += dst_octets;
516 len -= dst_octets;
517
518 if (len < 4)
519 return -EINVAL22;
520
521 assert_se(lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0)do { if ((__builtin_expect(!!(!(lease_parse_be32(option, 4, &
route->gw_addr.s_addr) >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease_parse_be32(option, 4, &route->gw_addr.s_addr) >= 0"
), "../src/libsystemd-network/sd-dhcp-lease.c", 521, __PRETTY_FUNCTION__
); } while (0)
;
522 option += 4;
523 len -= 4;
524
525 (*routes_size)++;
526 }
527
528 return 0;
529}
530
531int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata) {
532 sd_dhcp_lease *lease = userdata;
533 int r;
534
535 assert(lease)do { if ((__builtin_expect(!!(!(lease)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 535, __PRETTY_FUNCTION__); } while (0)
;
536
537 switch(code) {
538
539 case SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
540 r = lease_parse_u32(option, len, &lease->lifetime, 1);
541 if (r < 0)
542 log_debug_errno(r, "Failed to parse lease time, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 542, __func__,
"Failed to parse lease time, ignoring: %m") : -abs(_e); })
;
543
544 break;
545
546 case SD_DHCP_OPTION_SERVER_IDENTIFIER:
547 r = lease_parse_be32(option, len, &lease->server_address);
548 if (r < 0)
549 log_debug_errno(r, "Failed to parse server identifier, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 549, __func__,
"Failed to parse server identifier, ignoring: %m") : -abs(_e
); })
;
550
551 break;
552
553 case SD_DHCP_OPTION_SUBNET_MASK:
554 r = lease_parse_be32(option, len, &lease->subnet_mask);
555 if (r < 0)
556 log_debug_errno(r, "Failed to parse subnet mask, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 556, __func__,
"Failed to parse subnet mask, ignoring: %m") : -abs(_e); })
;
557 else
558 lease->have_subnet_mask = true1;
559 break;
560
561 case SD_DHCP_OPTION_BROADCAST:
562 r = lease_parse_be32(option, len, &lease->broadcast);
563 if (r < 0)
564 log_debug_errno(r, "Failed to parse broadcast address, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 564, __func__,
"Failed to parse broadcast address, ignoring: %m") : -abs(_e
); })
;
565 else
566 lease->have_broadcast = true1;
567 break;
568
569 case SD_DHCP_OPTION_ROUTER:
570 if (len >= 4) {
571 r = lease_parse_be32(option, 4, &lease->router);
572 if (r < 0)
573 log_debug_errno(r, "Failed to parse router address, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 573, __func__,
"Failed to parse router address, ignoring: %m") : -abs(_e); }
)
;
574 }
575 break;
576
577 case SD_DHCP_OPTION_DOMAIN_NAME_SERVER:
578 r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size);
579 if (r < 0)
580 log_debug_errno(r, "Failed to parse DNS server, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 580, __func__,
"Failed to parse DNS server, ignoring: %m") : -abs(_e); })
;
581 break;
582
583 case SD_DHCP_OPTION_NTP_SERVER:
584 r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size);
585 if (r < 0)
586 log_debug_errno(r, "Failed to parse NTP server, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 586, __func__,
"Failed to parse NTP server, ignoring: %m") : -abs(_e); })
;
587 break;
588
589 case SD_DHCP_OPTION_STATIC_ROUTE:
590 r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
591 if (r < 0)
592 log_debug_errno(r, "Failed to parse static routes, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 592, __func__,
"Failed to parse static routes, ignoring: %m") : -abs(_e); }
)
;
593 break;
594
595 case SD_DHCP_OPTION_INTERFACE_MTU:
596 r = lease_parse_u16(option, len, &lease->mtu, 68);
597 if (r < 0)
598 log_debug_errno(r, "Failed to parse MTU, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 598, __func__,
"Failed to parse MTU, ignoring: %m") : -abs(_e); })
;
599 if (lease->mtu < DHCP_DEFAULT_MIN_SIZE576) {
600 log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_DEFAULT_MIN_SIZE)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 600, __func__,
"MTU value of %" "u" " too small. Using default MTU value of %d instead."
, lease->mtu, 576) : -abs(_e); })
;
601 lease->mtu = DHCP_DEFAULT_MIN_SIZE576;
602 }
603
604 break;
605
606 case SD_DHCP_OPTION_DOMAIN_NAME:
607 r = lease_parse_domain(option, len, &lease->domainname);
608 if (r < 0) {
609 log_debug_errno(r, "Failed to parse domain name, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 609, __func__,
"Failed to parse domain name, ignoring: %m") : -abs(_e); })
;
610 return 0;
611 }
612
613 break;
614
615 case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
616 r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
617 if (r < 0)
618 log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 618, __func__,
"Failed to parse Domain Search List, ignoring: %m") : -abs(_e
); })
;
619 break;
620
621 case SD_DHCP_OPTION_HOST_NAME:
622 r = lease_parse_domain(option, len, &lease->hostname);
623 if (r < 0) {
624 log_debug_errno(r, "Failed to parse host name, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 624, __func__,
"Failed to parse host name, ignoring: %m") : -abs(_e); })
;
625 return 0;
626 }
627
628 break;
629
630 case SD_DHCP_OPTION_ROOT_PATH:
631 r = lease_parse_string(option, len, &lease->root_path);
632 if (r < 0)
633 log_debug_errno(r, "Failed to parse root path, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 633, __func__,
"Failed to parse root path, ignoring: %m") : -abs(_e); })
;
634 break;
635
636 case SD_DHCP_OPTION_RENEWAL_T1_TIME:
637 r = lease_parse_u32(option, len, &lease->t1, 1);
638 if (r < 0)
639 log_debug_errno(r, "Failed to parse T1 time, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 639, __func__,
"Failed to parse T1 time, ignoring: %m") : -abs(_e); })
;
640 break;
641
642 case SD_DHCP_OPTION_REBINDING_T2_TIME:
643 r = lease_parse_u32(option, len, &lease->t2, 1);
644 if (r < 0)
645 log_debug_errno(r, "Failed to parse T2 time, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 645, __func__,
"Failed to parse T2 time, ignoring: %m") : -abs(_e); })
;
646 break;
647
648 case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
649 r = lease_parse_classless_routes(
650 option, len,
651 &lease->static_route,
652 &lease->static_route_size,
653 &lease->static_route_allocated);
654 if (r < 0)
655 log_debug_errno(r, "Failed to parse classless routes, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 655, __func__,
"Failed to parse classless routes, ignoring: %m") : -abs(_e)
; })
;
656 break;
657
658 case SD_DHCP_OPTION_NEW_TZDB_TIMEZONE: {
659 _cleanup_free___attribute__((cleanup(freep))) char *tz = NULL((void*)0);
660
661 r = lease_parse_string(option, len, &tz);
662 if (r < 0) {
663 log_debug_errno(r, "Failed to parse timezone option, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 663, __func__,
"Failed to parse timezone option, ignoring: %m") : -abs(_e);
})
;
664 return 0;
665 }
666
667 if (!timezone_is_valid(tz, LOG_DEBUG7)) {
668 log_debug_errno(r, "Timezone is not valid, ignoring: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 668, __func__,
"Timezone is not valid, ignoring: %m") : -abs(_e); })
;
669 return 0;
670 }
671
672 free_and_replace(lease->timezone, tz)({ free(lease->timezone); (lease->timezone) = (tz); (tz
) = ((void*)0); 0; })
;
673
674 break;
675 }
676
677 case SD_DHCP_OPTION_VENDOR_SPECIFIC:
678
679 if (len <= 0)
680 lease->vendor_specific = mfree(lease->vendor_specific);
681 else {
682 void *p;
683
684 p = memdup(option, len);
685 if (!p)
686 return -ENOMEM12;
687
688 free(lease->vendor_specific);
689 lease->vendor_specific = p;
690 }
691
692 lease->vendor_specific_len = len;
693 break;
694
695 case SD_DHCP_OPTION_PRIVATE_BASE ... SD_DHCP_OPTION_PRIVATE_LAST:
696 r = dhcp_lease_insert_private_option(lease, code, option, len);
697 if (r < 0)
698 return r;
699
700 break;
701
702 default:
703 log_debug("Ignoring option DHCP option %"PRIu8" while parsing.", code)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 703, __func__,
"Ignoring option DHCP option %""u"" while parsing.", code) :
-abs(_e); })
;
704 break;
705 }
706
707 return 0;
708}
709
710/* Parses compressed domain names. */
711int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
712 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **names = NULL((void*)0);
713 size_t pos = 0, cnt = 0;
714 int r;
715
716 assert(domains)do { if ((__builtin_expect(!!(!(domains)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("domains"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 716, __PRETTY_FUNCTION__); } while (0)
;
717 assert_return(option && len > 0, -ENODATA)do { if (!(((__builtin_expect(!!(option && len > 0
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("option && len > 0"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 717, __PRETTY_FUNCTION__), 0))) return (-61); } while (0)
;
718
719 while (pos < len) {
720 _cleanup_free___attribute__((cleanup(freep))) char *name = NULL((void*)0);
721 size_t n = 0, allocated = 0;
722 size_t jump_barrier = pos, next_chunk = 0;
723 bool_Bool first = true1;
724
725 for (;;) {
726 uint8_t c;
727 c = option[pos++];
728
729 if (c == 0) {
730 /* End of name */
731 break;
732 } else if (c <= 63) {
733 const char *label;
734
735 /* Literal label */
736 label = (const char*) (option + pos);
737 pos += c;
738 if (pos >= len)
739 return -EBADMSG74;
740
741 if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)greedy_realloc((void**) &(name), &(allocated), (n + !
first + (63*4+1)), sizeof((name)[0]))
)
742 return -ENOMEM12;
743
744 if (first)
745 first = false0;
746 else
747 name[n++] = '.';
748
749 r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX(63*4+1));
750 if (r < 0)
751 return r;
752
753 n += r;
754 } else if ((c & 0xc0) == 0xc0) {
755 /* Pointer */
756
757 uint8_t d;
758 uint16_t ptr;
759
760 if (pos >= len)
761 return -EBADMSG74;
762
763 d = option[pos++];
764 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
765
766 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
767 if (ptr >= jump_barrier)
768 return -EBADMSG74;
769 jump_barrier = ptr;
770
771 /* Save current location so we don't end up re-parsing what's parsed so far. */
772 if (next_chunk == 0)
773 next_chunk = pos;
774
775 pos = ptr;
776 } else
777 return -EBADMSG74;
778 }
779
780 if (!GREEDY_REALLOC(name, allocated, n + 1)greedy_realloc((void**) &(name), &(allocated), (n + 1
), sizeof((name)[0]))
)
781 return -ENOMEM12;
782 name[n] = 0;
783
784 r = strv_extend(&names, name);
785 if (r < 0)
786 return r;
787
788 cnt++;
789
790 if (next_chunk != 0)
791 pos = next_chunk;
792 }
793
794 *domains = TAKE_PTR(names)({ typeof(names) _ptr_ = (names); (names) = ((void*)0); _ptr_
; })
;
795
796 return cnt;
797}
798
799int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
800 struct sd_dhcp_raw_option *cur, *option;
801
802 assert(lease)do { if ((__builtin_expect(!!(!(lease)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 802, __PRETTY_FUNCTION__); } while (0)
;
803
804 LIST_FOREACH(options, cur, lease->private_options)for ((cur) = (lease->private_options); (cur); (cur) = (cur
)->options_next)
{
805 if (tag < cur->tag)
806 break;
807 if (tag == cur->tag) {
808 log_debug("Ignoring duplicate option, tagged %i.", tag)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 808, __func__,
"Ignoring duplicate option, tagged %i.", tag) : -abs(_e); })
;
809 return 0;
810 }
811 }
812
813 option = new(struct sd_dhcp_raw_option, 1)((struct sd_dhcp_raw_option*) malloc_multiply(sizeof(struct sd_dhcp_raw_option
), (1)))
;
814 if (!option)
815 return -ENOMEM12;
816
817 option->tag = tag;
818 option->length = len;
819 option->data = memdup(data, len);
820 if (!option->data) {
821 free(option);
822 return -ENOMEM12;
823 }
824
825 LIST_INSERT_BEFORE(options, lease->private_options, cur, option)do { typeof(*(lease->private_options)) **_head = &(lease
->private_options), *_a = (cur), *_b = (option); do { if (
(__builtin_expect(!!(!(_b)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("_b"), "../src/libsystemd-network/sd-dhcp-lease.c", 825, __PRETTY_FUNCTION__
); } while (0); if (!_a) { if (!*_head) { _b->options_next
= ((void*)0); _b->options_prev = ((void*)0); *_head = _b;
} else { typeof(*(lease->private_options)) *_tail = (lease
->private_options); while (_tail->options_next) _tail =
_tail->options_next; _b->options_next = ((void*)0); _b
->options_prev = _tail; _tail->options_next = _b; } } else
{ if ((_b->options_prev = _a->options_prev)) _b->options_prev
->options_next = _b; else *_head = _b; _b->options_next
= _a; _a->options_prev = _b; } } while (0)
;
826 return 0;
827}
828
829int dhcp_lease_new(sd_dhcp_lease **ret) {
830 sd_dhcp_lease *lease;
831
832 lease = new0(sd_dhcp_lease, 1)((sd_dhcp_lease*) calloc((1), sizeof(sd_dhcp_lease)));
833 if (!lease)
834 return -ENOMEM12;
835
836 lease->router = INADDR_ANY((in_addr_t) 0x00000000);
837 lease->n_ref = 1;
838
839 *ret = lease;
840 return 0;
841}
842
843int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
844 _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0);
845 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
846 struct sd_dhcp_raw_option *option;
847 struct in_addr address;
848 const struct in_addr *addresses;
849 const void *client_id, *data;
850 size_t client_id_len, data_len;
851 const char *string;
852 uint16_t mtu;
853 _cleanup_free___attribute__((cleanup(freep))) sd_dhcp_route **routes = NULL((void*)0);
854 char **search_domains = NULL((void*)0);
855 uint32_t t1, t2, lifetime;
856 int r;
857
858 assert(lease)do { if ((__builtin_expect(!!(!(lease)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 858, __PRETTY_FUNCTION__); } while (0)
;
859 assert(lease_file)do { if ((__builtin_expect(!!(!(lease_file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease_file"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 859, __PRETTY_FUNCTION__); } while (0)
;
860
861 r = fopen_temporary(lease_file, &f, &temp_path);
862 if (r < 0)
863 goto fail;
864
865 (void) __fsetlocking(f, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER);
866 (void) fchmod(fileno(f), 0644);
867
868 fprintf(f,
869 "# This is private data. Do not parse.\n");
870
871 r = sd_dhcp_lease_get_address(lease, &address);
872 if (r >= 0)
873 fprintf(f, "ADDRESS=%s\n", inet_ntoa(address));
874
875 r = sd_dhcp_lease_get_netmask(lease, &address);
876 if (r >= 0)
877 fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
878
879 r = sd_dhcp_lease_get_router(lease, &address);
880 if (r >= 0)
881 fprintf(f, "ROUTER=%s\n", inet_ntoa(address));
882
883 r = sd_dhcp_lease_get_server_identifier(lease, &address);
884 if (r >= 0)
885 fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntoa(address));
886
887 r = sd_dhcp_lease_get_next_server(lease, &address);
888 if (r >= 0)
889 fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
890
891 r = sd_dhcp_lease_get_broadcast(lease, &address);
892 if (r >= 0)
893 fprintf(f, "BROADCAST=%s\n", inet_ntoa(address));
894
895 r = sd_dhcp_lease_get_mtu(lease, &mtu);
896 if (r >= 0)
897 fprintf(f, "MTU=%" PRIu16"u" "\n", mtu);
898
899 r = sd_dhcp_lease_get_t1(lease, &t1);
900 if (r >= 0)
901 fprintf(f, "T1=%" PRIu32"u" "\n", t1);
902
903 r = sd_dhcp_lease_get_t2(lease, &t2);
904 if (r >= 0)
905 fprintf(f, "T2=%" PRIu32"u" "\n", t2);
906
907 r = sd_dhcp_lease_get_lifetime(lease, &lifetime);
908 if (r >= 0)
909 fprintf(f, "LIFETIME=%" PRIu32"u" "\n", lifetime);
910
911 r = sd_dhcp_lease_get_dns(lease, &addresses);
912 if (r > 0) {
913 fputs("DNS=", f);
914 serialize_in_addrs(f, addresses, r);
915 fputs("\n", f);
916 }
917
918 r = sd_dhcp_lease_get_ntp(lease, &addresses);
919 if (r > 0) {
920 fputs("NTP=", f);
921 serialize_in_addrs(f, addresses, r);
922 fputs("\n", f);
923 }
924
925 r = sd_dhcp_lease_get_domainname(lease, &string);
926 if (r >= 0)
927 fprintf(f, "DOMAINNAME=%s\n", string);
928
929 r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
930 if (r > 0) {
931 fputs("DOMAIN_SEARCH_LIST=", f);
932 fputstrv(f, search_domains, NULL((void*)0), NULL((void*)0));
933 fputs("\n", f);
934 }
935
936 r = sd_dhcp_lease_get_hostname(lease, &string);
937 if (r >= 0)
938 fprintf(f, "HOSTNAME=%s\n", string);
939
940 r = sd_dhcp_lease_get_root_path(lease, &string);
941 if (r >= 0)
942 fprintf(f, "ROOT_PATH=%s\n", string);
943
944 r = sd_dhcp_lease_get_routes(lease, &routes);
945 if (r > 0)
946 serialize_dhcp_routes(f, "ROUTES", routes, r);
947
948 r = sd_dhcp_lease_get_timezone(lease, &string);
949 if (r >= 0)
950 fprintf(f, "TIMEZONE=%s\n", string);
951
952 r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len);
953 if (r >= 0) {
954 _cleanup_free___attribute__((cleanup(freep))) char *client_id_hex = NULL((void*)0);
955
956 client_id_hex = hexmem(client_id, client_id_len);
957 if (!client_id_hex) {
958 r = -ENOMEM12;
959 goto fail;
960 }
961 fprintf(f, "CLIENTID=%s\n", client_id_hex);
962 }
963
964 r = sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len);
965 if (r >= 0) {
966 _cleanup_free___attribute__((cleanup(freep))) char *option_hex = NULL((void*)0);
967
968 option_hex = hexmem(data, data_len);
969 if (!option_hex) {
970 r = -ENOMEM12;
971 goto fail;
972 }
973 fprintf(f, "VENDOR_SPECIFIC=%s\n", option_hex);
974 }
975
976 LIST_FOREACH(options, option, lease->private_options)for ((option) = (lease->private_options); (option); (option
) = (option)->options_next)
{
977 char key[STRLEN("OPTION_000")(sizeof("""OPTION_000""") - 1)+1];
978
979 xsprintf(key, "OPTION_%" PRIu8, option->tag)do { if ((__builtin_expect(!!(!(((size_t) snprintf(key, __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(key), typeof(&*(key))), sizeof(key)/sizeof((key)[0]), ((
void)0))), "OPTION_%" "u", option->tag) < (__extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(key), typeof(&*(key))), sizeof(key)/sizeof((key)[0]), ((
void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("xsprintf: " "key" "[] must be big enough"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 979, __PRETTY_FUNCTION__); } while (0)
;
980 r = serialize_dhcp_option(f, key, option->data, option->length);
981 if (r < 0)
982 goto fail;
983 }
984
985 r = fflush_and_check(f);
986 if (r < 0)
987 goto fail;
988
989 if (rename(temp_path, lease_file) < 0) {
990 r = -errno(*__errno_location ());
991 goto fail;
992 }
993
994 return 0;
995
996fail:
997 if (temp_path)
998 (void) unlink(temp_path);
999
1000 return log_error_errno(r, "Failed to save lease data %s: %m", lease_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1000, __func__
, "Failed to save lease data %s: %m", lease_file) : -abs(_e);
})
;
1001}
1002
1003int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
1004
1005 _cleanup_(sd_dhcp_lease_unrefp)__attribute__((cleanup(sd_dhcp_lease_unrefp))) sd_dhcp_lease *lease = NULL((void*)0);
1006 _cleanup_free___attribute__((cleanup(freep))) char
1007 *address = NULL((void*)0),
1008 *router = NULL((void*)0),
1009 *netmask = NULL((void*)0),
1010 *server_address = NULL((void*)0),
1011 *next_server = NULL((void*)0),
1012 *broadcast = NULL((void*)0),
1013 *dns = NULL((void*)0),
1014 *ntp = NULL((void*)0),
1015 *mtu = NULL((void*)0),
1016 *routes = NULL((void*)0),
1017 *domains = NULL((void*)0),
1018 *client_id_hex = NULL((void*)0),
1019 *vendor_specific_hex = NULL((void*)0),
1020 *lifetime = NULL((void*)0),
1021 *t1 = NULL((void*)0),
1022 *t2 = NULL((void*)0),
1023 *options[SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1] = {};
1024
1025 int r, i;
1026
1027 assert(lease_file)do { if ((__builtin_expect(!!(!(lease_file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease_file"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1027, __PRETTY_FUNCTION__); } while (0)
;
1028 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1028, __PRETTY_FUNCTION__); } while (0)
;
1029
1030 r = dhcp_lease_new(&lease);
1031 if (r < 0)
1032 return r;
1033
1034 r = parse_env_file(NULL((void*)0), lease_file, NEWLINE"\n\r",
1035 "ADDRESS", &address,
1036 "ROUTER", &router,
1037 "NETMASK", &netmask,
1038 "SERVER_IDENTIFIER", &server_address,
1039 "NEXT_SERVER", &next_server,
1040 "BROADCAST", &broadcast,
1041 "DNS", &dns,
1042 "NTP", &ntp,
1043 "MTU", &mtu,
1044 "DOMAINNAME", &lease->domainname,
1045 "HOSTNAME", &lease->hostname,
1046 "DOMAIN_SEARCH_LIST", &domains,
1047 "ROOT_PATH", &lease->root_path,
1048 "ROUTES", &routes,
1049 "CLIENTID", &client_id_hex,
1050 "TIMEZONE", &lease->timezone,
1051 "VENDOR_SPECIFIC", &vendor_specific_hex,
1052 "LIFETIME", &lifetime,
1053 "T1", &t1,
1054 "T2", &t2,
1055 "OPTION_224", &options[0],
1056 "OPTION_225", &options[1],
1057 "OPTION_226", &options[2],
1058 "OPTION_227", &options[3],
1059 "OPTION_228", &options[4],
1060 "OPTION_229", &options[5],
1061 "OPTION_230", &options[6],
1062 "OPTION_231", &options[7],
1063 "OPTION_232", &options[8],
1064 "OPTION_233", &options[9],
1065 "OPTION_234", &options[10],
1066 "OPTION_235", &options[11],
1067 "OPTION_236", &options[12],
1068 "OPTION_237", &options[13],
1069 "OPTION_238", &options[14],
1070 "OPTION_239", &options[15],
1071 "OPTION_240", &options[16],
1072 "OPTION_241", &options[17],
1073 "OPTION_242", &options[18],
1074 "OPTION_243", &options[19],
1075 "OPTION_244", &options[20],
1076 "OPTION_245", &options[21],
1077 "OPTION_246", &options[22],
1078 "OPTION_247", &options[23],
1079 "OPTION_248", &options[24],
1080 "OPTION_249", &options[25],
1081 "OPTION_250", &options[26],
1082 "OPTION_251", &options[27],
1083 "OPTION_252", &options[28],
1084 "OPTION_253", &options[29],
1085 "OPTION_254", &options[30],
1086 NULL((void*)0));
1087 if (r < 0)
1088 return r;
1089
1090 if (address) {
1091 r = inet_pton(AF_INET2, address, &lease->address);
1092 if (r <= 0)
1093 log_debug("Failed to parse address %s, ignoring.", address)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1093, __func__
, "Failed to parse address %s, ignoring.", address) : -abs(_e
); })
;
1094 }
1095
1096 if (router) {
1097 r = inet_pton(AF_INET2, router, &lease->router);
1098 if (r <= 0)
1099 log_debug("Failed to parse router %s, ignoring.", router)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1099, __func__
, "Failed to parse router %s, ignoring.", router) : -abs(_e);
})
;
1100 }
1101
1102 if (netmask) {
1103 r = inet_pton(AF_INET2, netmask, &lease->subnet_mask);
1104 if (r <= 0)
1105 log_debug("Failed to parse netmask %s, ignoring.", netmask)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1105, __func__
, "Failed to parse netmask %s, ignoring.", netmask) : -abs(_e
); })
;
1106 else
1107 lease->have_subnet_mask = true1;
1108 }
1109
1110 if (server_address) {
1111 r = inet_pton(AF_INET2, server_address, &lease->server_address);
1112 if (r <= 0)
1113 log_debug("Failed to parse server address %s, ignoring.", server_address)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1113, __func__
, "Failed to parse server address %s, ignoring.", server_address
) : -abs(_e); })
;
1114 }
1115
1116 if (next_server) {
1117 r = inet_pton(AF_INET2, next_server, &lease->next_server);
1118 if (r <= 0)
1119 log_debug("Failed to parse next server %s, ignoring.", next_server)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1119, __func__
, "Failed to parse next server %s, ignoring.", next_server) :
-abs(_e); })
;
1120 }
1121
1122 if (broadcast) {
1123 r = inet_pton(AF_INET2, broadcast, &lease->broadcast);
1124 if (r <= 0)
1125 log_debug("Failed to parse broadcast address %s, ignoring.", broadcast)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1125, __func__
, "Failed to parse broadcast address %s, ignoring.", broadcast
) : -abs(_e); })
;
1126 else
1127 lease->have_broadcast = true1;
1128 }
1129
1130 if (dns) {
1131 r = deserialize_in_addrs(&lease->dns, dns);
1132 if (r < 0)
1133 log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1133, __func__
, "Failed to deserialize DNS servers %s, ignoring: %m", dns) :
-abs(_e); })
;
1134 else
1135 lease->dns_size = r;
1136 }
1137
1138 if (ntp) {
1139 r = deserialize_in_addrs(&lease->ntp, ntp);
1140 if (r < 0)
1141 log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1141, __func__
, "Failed to deserialize NTP servers %s, ignoring: %m", ntp) :
-abs(_e); })
;
1142 else
1143 lease->ntp_size = r;
1144 }
1145
1146 if (mtu) {
1147 r = safe_atou16(mtu, &lease->mtu);
1148 if (r < 0)
1149 log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1149, __func__
, "Failed to parse MTU %s, ignoring: %m", mtu) : -abs(_e); })
;
1150 }
1151
1152 if (domains) {
1153 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0);
1154 a = strv_split(domains, " ");
1155 if (!a)
1156 return -ENOMEM12;
1157
1158 if (!strv_isempty(a)) {
1159 lease->search_domains = a;
1160 a = NULL((void*)0);
1161 }
1162 }
1163
1164 if (routes) {
1165 r = deserialize_dhcp_routes(
1166 &lease->static_route,
1167 &lease->static_route_size,
1168 &lease->static_route_allocated,
1169 routes);
1170 if (r < 0)
1171 log_debug_errno(r, "Failed to parse DHCP routes %s, ignoring: %m", routes)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1171, __func__
, "Failed to parse DHCP routes %s, ignoring: %m", routes) : -
abs(_e); })
;
1172 }
1173
1174 if (lifetime) {
1175 r = safe_atou32(lifetime, &lease->lifetime);
1176 if (r < 0)
1177 log_debug_errno(r, "Failed to parse lifetime %s, ignoring: %m", lifetime)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1177, __func__
, "Failed to parse lifetime %s, ignoring: %m", lifetime) : -abs
(_e); })
;
1178 }
1179
1180 if (t1) {
1181 r = safe_atou32(t1, &lease->t1);
1182 if (r < 0)
1183 log_debug_errno(r, "Failed to parse T1 %s, ignoring: %m", t1)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1183, __func__
, "Failed to parse T1 %s, ignoring: %m", t1) : -abs(_e); })
;
1184 }
1185
1186 if (t2) {
1187 r = safe_atou32(t2, &lease->t2);
1188 if (r < 0)
1189 log_debug_errno(r, "Failed to parse T2 %s, ignoring: %m", t2)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1189, __func__
, "Failed to parse T2 %s, ignoring: %m", t2) : -abs(_e); })
;
1190 }
1191
1192 if (client_id_hex) {
1193 r = unhexmem(client_id_hex, (size_t) -1, &lease->client_id, &lease->client_id_len);
1194 if (r < 0)
1195 log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1195, __func__
, "Failed to parse client ID %s, ignoring: %m", client_id_hex
) : -abs(_e); })
;
1196 }
1197
1198 if (vendor_specific_hex) {
1199 r = unhexmem(vendor_specific_hex, (size_t) -1, &lease->vendor_specific, &lease->vendor_specific_len);
1200 if (r < 0)
1201 log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex)({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1201, __func__
, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex
) : -abs(_e); })
;
1202 }
1203
1204 for (i = 0; i <= SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE; i++) {
1205 _cleanup_free___attribute__((cleanup(freep))) void *data = NULL((void*)0);
1206 size_t len;
1207
1208 if (!options[i])
1209 continue;
1210
1211 r = unhexmem(options[i], (size_t) -1, &data, &len);
1212 if (r < 0) {
1213 log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i])({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd-network/sd-dhcp-lease.c", 1213, __func__
, "Failed to parse private DHCP option %s, ignoring: %m", options
[i]) : -abs(_e); })
;
1214 continue;
1215 }
1216
1217 r = dhcp_lease_insert_private_option(lease, SD_DHCP_OPTION_PRIVATE_BASE + i, data, len);
1218 if (r < 0)
1219 return r;
1220 }
1221
1222 *ret = TAKE_PTR(lease)({ typeof(lease) _ptr_ = (lease); (lease) = ((void*)0); _ptr_
; })
;
1223
1224 return 0;
1225}
1226
1227int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
1228 struct in_addr address, mask;
1229 int r;
1230
1231 assert(lease)do { if ((__builtin_expect(!!(!(lease)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1231, __PRETTY_FUNCTION__); } while (0)
;
1232
1233 if (lease->address == 0)
1234 return -ENODATA61;
1235
1236 address.s_addr = lease->address;
1237
1238 /* fall back to the default subnet masks based on address class */
1239 r = in4_addr_default_subnet_mask(&address, &mask);
1240 if (r < 0)
1241 return r;
1242
1243 lease->subnet_mask = mask.s_addr;
1244 lease->have_subnet_mask = true1;
1245
1246 return 0;
1247}
1248
1249int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) {
1250 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1250, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1251 assert_return(client_id, -EINVAL)do { if (!(((__builtin_expect(!!(client_id),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("client_id"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1251, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1252 assert_return(client_id_len, -EINVAL)do { if (!(((__builtin_expect(!!(client_id_len),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("client_id_len"
), "../src/libsystemd-network/sd-dhcp-lease.c", 1252, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
1253
1254 if (!lease->client_id)
1255 return -ENODATA61;
1256
1257 *client_id = lease->client_id;
1258 *client_id_len = lease->client_id_len;
1259
1260 return 0;
1261}
1262
1263int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len) {
1264 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1264, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1265 assert_return(client_id || client_id_len <= 0, -EINVAL)do { if (!(((__builtin_expect(!!(client_id || client_id_len <=
0),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("client_id || client_id_len <= 0"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1265, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1266
1267 if (client_id_len <= 0)
1268 lease->client_id = mfree(lease->client_id);
1269 else {
1270 void *p;
1271
1272 p = memdup(client_id, client_id_len);
1273 if (!p)
1274 return -ENOMEM12;
1275
1276 free(lease->client_id);
1277 lease->client_id = p;
1278 lease->client_id_len = client_id_len;
1279 }
1280
1281 return 0;
1282}
1283
1284int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) {
1285 assert_return(lease, -EINVAL)do { if (!(((__builtin_expect(!!(lease),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("lease"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1285, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1286 assert_return(tz, -EINVAL)do { if (!(((__builtin_expect(!!(tz),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("tz"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1286, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1287
1288 if (!lease->timezone)
1289 return -ENODATA61;
1290
1291 *tz = lease->timezone;
1292 return 0;
1293}
1294
1295int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination) {
1296 assert_return(route, -EINVAL)do { if (!(((__builtin_expect(!!(route),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("route"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1296, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1297 assert_return(destination, -EINVAL)do { if (!(((__builtin_expect(!!(destination),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("destination"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1297, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1298
1299 *destination = route->dst_addr;
1300 return 0;
1301}
1302
1303int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length) {
1304 assert_return(route, -EINVAL)do { if (!(((__builtin_expect(!!(route),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("route"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1304, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1305 assert_return(length, -EINVAL)do { if (!(((__builtin_expect(!!(length),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("length"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1305, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1306
1307 *length = route->dst_prefixlen;
1308 return 0;
1309}
1310
1311int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
1312 assert_return(route, -EINVAL)do { if (!(((__builtin_expect(!!(route),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("route"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1312, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1313 assert_return(gateway, -EINVAL)do { if (!(((__builtin_expect(!!(gateway),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("gateway"), "../src/libsystemd-network/sd-dhcp-lease.c"
, 1313, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1314
1315 *gateway = route->gw_addr;
1316 return 0;
1317}