Bug Summary

File:build-scan/../src/libsystemd-network/sd-dhcp-lease.c
Warning:line 668, column 25
Potential leak of memory pointed to by 'tz'

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)
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)
;
265 lease->n_ref--;
266
267 if (lease->n_ref > 0)
268 return NULL((void*)0);
269
270 while (lease->private_options) {
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)
;
274
275 free(option->data);
276 free(option);
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)
;
6
Assuming 'option' is non-null
7
Taking false branch
8
Loop condition is false. Exiting loop
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)
;
9
Taking false branch
10
Loop condition is false. Exiting loop
332
333 if (len <= 0)
11
Assuming 'len' is > 0
12
Taking false branch
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))
13
Assuming the condition is false
14
Taking false branch
343 return -EINVAL22;
344
345 string = strndup((const char *) option, len);
15
Memory is allocated
346 if (!string)
16
Assuming 'string' is non-null
17
Taking false branch
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)
;
1
Assuming 'lease' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
536
537 switch(code) {
4
Control jumps to 'case SD_DHCP_OPTION_NEW_TZDB_TIMEZONE:' at line 658
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);
5
Calling 'lease_parse_string'
18
Returned allocated memory via 3rd parameter
662 if (r
18.1
'r' is >= 0
< 0) {
19
Taking false branch
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)) {
20
Assuming the condition is true
21
Taking true branch
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); })
;
22
Potential leak of memory pointed to by 'tz'
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}