Bug Summary

File:build-scan/../src/libsystemd-network/ndisc-router.c
Warning:line 68, column 24
Potential leak of memory pointed to by 'rt'

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 ndisc-router.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/ndisc-router.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3 Copyright © 2014 Intel Corporation. All rights reserved.
4***/
5
6#include <netinet/icmp6.h>
7
8#include "sd-ndisc.h"
9
10#include "alloc-util.h"
11#include "dns-domain.h"
12#include "hostname-util.h"
13#include "missing.h"
14#include "ndisc-internal.h"
15#include "ndisc-router.h"
16#include "strv.h"
17
18_public___attribute__ ((visibility("default"))) sd_ndisc_router* sd_ndisc_router_ref(sd_ndisc_router *rt) {
19 if (!rt)
20 return NULL((void*)0);
21
22 assert(rt->n_ref > 0)do { if ((__builtin_expect(!!(!(rt->n_ref > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt->n_ref > 0"), "../src/libsystemd-network/ndisc-router.c"
, 22, __PRETTY_FUNCTION__); } while (0)
;
23 rt->n_ref++;
24
25 return rt;
26}
27
28_public___attribute__ ((visibility("default"))) sd_ndisc_router* sd_ndisc_router_unref(sd_ndisc_router *rt) {
29 if (!rt)
30 return NULL((void*)0);
31
32 assert(rt->n_ref > 0)do { if ((__builtin_expect(!!(!(rt->n_ref > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt->n_ref > 0"), "../src/libsystemd-network/ndisc-router.c"
, 32, __PRETTY_FUNCTION__); } while (0)
;
33 rt->n_ref--;
34
35 if (rt->n_ref > 0)
36 return NULL((void*)0);
37
38 return mfree(rt);
39}
40
41sd_ndisc_router *ndisc_router_new(size_t raw_size) {
42 sd_ndisc_router *rt;
43
44 rt = malloc0(ALIGN(sizeof(sd_ndisc_router)) + raw_size)(calloc(1, ((((sizeof(sd_ndisc_router)) + 7) & ~7) + raw_size
)))
;
10
Memory is allocated
45 if (!rt)
11
Assuming 'rt' is non-null
12
Taking false branch
46 return NULL((void*)0);
47
48 rt->raw_size = raw_size;
49 rt->n_ref = 1;
50
51 return rt;
52}
53
54_public___attribute__ ((visibility("default"))) int sd_ndisc_router_from_raw(sd_ndisc_router **ret, const void *raw, size_t raw_size) {
55 _cleanup_(sd_ndisc_router_unrefp)__attribute__((cleanup(sd_ndisc_router_unrefp))) sd_ndisc_router *rt = NULL((void*)0);
56 int r;
57
58 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 58, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1
Assuming 'ret' is non-null
2
'?' condition is true
3
Taking false branch
4
Loop condition is false. Exiting loop
59 assert_return(raw || raw_size <= 0, -EINVAL)do { if (!(((__builtin_expect(!!(raw || raw_size <= 0),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"raw || raw_size <= 0"), "../src/libsystemd-network/ndisc-router.c"
, 59, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
5
Assuming 'raw' is non-null
6
'?' condition is true
7
Taking false branch
8
Loop condition is false. Exiting loop
60
61 rt = ndisc_router_new(raw_size);
9
Calling 'ndisc_router_new'
13
Returned allocated memory
62 if (!rt
13.1
'rt' is non-null
)
14
Taking false branch
63 return -ENOMEM12;
64
65 memcpy(NDISC_ROUTER_RAW(rt), raw, raw_size);
66 r = ndisc_router_parse(rt);
67 if (r
14.1
'r' is < 0
< 0)
15
Taking true branch
68 return r;
16
Potential leak of memory pointed to by 'rt'
69
70 *ret = TAKE_PTR(rt)({ typeof(rt) _ptr_ = (rt); (rt) = ((void*)0); _ptr_; });
71
72 return r;
73}
74
75_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr) {
76 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 76, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
77 assert_return(ret_addr, -EINVAL)do { if (!(((__builtin_expect(!!(ret_addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret_addr"), "../src/libsystemd-network/ndisc-router.c"
, 77, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
78
79 if (IN6_IS_ADDR_UNSPECIFIED(&rt->address)(__extension__ ({ const struct in6_addr *__a = (const struct in6_addr
*) (&rt->address); __a->__in6_u.__u6_addr32[0] == 0
&& __a->__in6_u.__u6_addr32[1] == 0 && __a
->__in6_u.__u6_addr32[2] == 0 && __a->__in6_u.__u6_addr32
[3] == 0; }))
)
80 return -ENODATA61;
81
82 *ret_addr = rt->address;
83 return 0;
84}
85
86_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret) {
87 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 87, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
88 assert_return(TRIPLE_TIMESTAMP_HAS_CLOCK(clock), -EOPNOTSUPP)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){0, 8, 1, 7, 9})/sizeof(int)]; switch(clock)
{ case 0: case 8: case 1: case 7: case 9: _found = 1; break;
default: break; } _found; })),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("TRIPLE_TIMESTAMP_HAS_CLOCK(clock)"), "../src/libsystemd-network/ndisc-router.c"
, 88, __PRETTY_FUNCTION__), 0))) return (-95); } while (0)
;
89 assert_return(clock_supported(clock), -EOPNOTSUPP)do { if (!(((__builtin_expect(!!(clock_supported(clock)),1)))
? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"clock_supported(clock)"), "../src/libsystemd-network/ndisc-router.c"
, 89, __PRETTY_FUNCTION__), 0))) return (-95); } while (0)
;
90 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 90, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
91
92 if (!triple_timestamp_is_set(&rt->timestamp))
93 return -ENODATA61;
94
95 *ret = triple_timestamp_by_clock(&rt->timestamp, clock);
96 return 0;
97}
98
99_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *size) {
100 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 100, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
101 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 101, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
102 assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/ndisc-router.c"
, 102, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
103
104 *ret = NDISC_ROUTER_RAW(rt);
105 *size = rt->raw_size;
106
107 return 0;
108}
109
110int ndisc_router_parse(sd_ndisc_router *rt) {
111 struct nd_router_advert *a;
112 const uint8_t *p;
113 bool_Bool has_mtu = false0, has_flag_extension = false0;
114 size_t left;
115
116 assert(rt)do { if ((__builtin_expect(!!(!(rt)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 116, __PRETTY_FUNCTION__); } while (0)
;
117
118 if (rt->raw_size < sizeof(struct nd_router_advert)) {
119 log_ndisc("Too small to be a router advertisement, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 119, __func__
, "NDISC: " "Too small to be a router advertisement, ignoring."
)
;
120 return -EBADMSG74;
121 }
122
123 /* Router advertisement packets are neatly aligned to 64bit boundaries, hence we can access them directly */
124 a = NDISC_ROUTER_RAW(rt);
125
126 if (a->nd_ra_typend_ra_hdr.icmp6_type != ND_ROUTER_ADVERT134) {
127 log_ndisc("Received ND packet that is not a router advertisement, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 127, __func__
, "NDISC: " "Received ND packet that is not a router advertisement, ignoring."
)
;
128 return -EBADMSG74;
129 }
130
131 if (a->nd_ra_codend_ra_hdr.icmp6_code != 0) {
132 log_ndisc("Received ND packet with wrong RA code, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 132, __func__
, "NDISC: " "Received ND packet with wrong RA code, ignoring."
)
;
133 return -EBADMSG74;
134 }
135
136 rt->hop_limit = a->nd_ra_curhoplimitnd_ra_hdr.icmp6_dataun.icmp6_un_data8[0];
137 rt->flags = a->nd_ra_flags_reservednd_ra_hdr.icmp6_dataun.icmp6_un_data8[1]; /* the first 8bit */
138 rt->lifetime = be16toh(a->nd_ra_router_lifetime)__bswap_16 (a->nd_ra_hdr.icmp6_dataun.icmp6_un_data16[1]);
139
140 rt->preference = (rt->flags >> 3) & 3;
141 if (!IN_SET(rt->preference, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH
})/sizeof(int)]; switch(rt->preference) { case SD_NDISC_PREFERENCE_LOW
: case SD_NDISC_PREFERENCE_HIGH: _found = 1; break; default: break
; } _found; })
)
142 rt->preference = SD_NDISC_PREFERENCE_MEDIUM;
143
144 p = (const uint8_t*) NDISC_ROUTER_RAW(rt) + sizeof(struct nd_router_advert);
145 left = rt->raw_size - sizeof(struct nd_router_advert);
146
147 for (;;) {
148 uint8_t type;
149 size_t length;
150
151 if (left == 0)
152 break;
153
154 if (left < 2) {
155 log_ndisc("Option lacks header, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 155, __func__
, "NDISC: " "Option lacks header, ignoring datagram.")
;
156 return -EBADMSG74;
157 }
158
159 type = p[0];
160 length = p[1] * 8;
161
162 if (length == 0) {
163 log_ndisc("Zero-length option, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 163, __func__
, "NDISC: " "Zero-length option, ignoring datagram.")
;
164 return -EBADMSG74;
165 }
166 if (left < length) {
167 log_ndisc("Option truncated, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 167, __func__
, "NDISC: " "Option truncated, ignoring datagram.")
;
168 return -EBADMSG74;
169 }
170
171 switch (type) {
172
173 case SD_NDISC_OPTION_PREFIX_INFORMATION:
174
175 if (length != 4*8) {
176 log_ndisc("Prefix option of invalid size, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 176, __func__
, "NDISC: " "Prefix option of invalid size, ignoring datagram."
)
;
177 return -EBADMSG74;
178 }
179
180 if (p[2] > 128) {
181 log_ndisc("Bad prefix length, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 181, __func__
, "NDISC: " "Bad prefix length, ignoring datagram.")
;
182 return -EBADMSG74;
183 }
184
185 break;
186
187 case SD_NDISC_OPTION_MTU: {
188 uint32_t m;
189
190 if (has_mtu) {
191 log_ndisc("MTU option specified twice, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 191, __func__
, "NDISC: " "MTU option specified twice, ignoring.")
;
192 break;
193 }
194
195 if (length != 8) {
196 log_ndisc("MTU option of invalid size, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 196, __func__
, "NDISC: " "MTU option of invalid size, ignoring datagram.")
;
197 return -EBADMSG74;
198 }
199
200 m = be32toh(*(uint32_t*) (p + 4))__bswap_32 (*(uint32_t*) (p + 4));
201 if (m >= IPV6_MIN_MTU1280) /* ignore invalidly small MTUs */
202 rt->mtu = m;
203
204 has_mtu = true1;
205 break;
206 }
207
208 case SD_NDISC_OPTION_ROUTE_INFORMATION:
209 if (length < 1*8 || length > 3*8) {
210 log_ndisc("Route information option of invalid size, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 210, __func__
, "NDISC: " "Route information option of invalid size, ignoring datagram."
)
;
211 return -EBADMSG74;
212 }
213
214 if (p[2] > 128) {
215 log_ndisc("Bad route prefix length, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 215, __func__
, "NDISC: " "Bad route prefix length, ignoring datagram.")
;
216 return -EBADMSG74;
217 }
218
219 break;
220
221 case SD_NDISC_OPTION_RDNSS:
222 if (length < 3*8 || (length % (2*8)) != 1*8) {
223 log_ndisc("RDNSS option has invalid size.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 223, __func__
, "NDISC: " "RDNSS option has invalid size.")
;
224 return -EBADMSG74;
225 }
226
227 break;
228
229 case SD_NDISC_OPTION_FLAGS_EXTENSION:
230
231 if (has_flag_extension) {
232 log_ndisc("Flags extension option specified twice, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 232, __func__
, "NDISC: " "Flags extension option specified twice, ignoring."
)
;
233 break;
234 }
235
236 if (length < 1*8) {
237 log_ndisc("Flags extension option has invalid size.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 237, __func__
, "NDISC: " "Flags extension option has invalid size.")
;
238 return -EBADMSG74;
239 }
240
241 /* Add in the additional flags bits */
242 rt->flags |=
243 ((uint64_t) p[2] << 8) |
244 ((uint64_t) p[3] << 16) |
245 ((uint64_t) p[4] << 24) |
246 ((uint64_t) p[5] << 32) |
247 ((uint64_t) p[6] << 40) |
248 ((uint64_t) p[7] << 48);
249
250 has_flag_extension = true1;
251 break;
252
253 case SD_NDISC_OPTION_DNSSL:
254 if (length < 2*8) {
255 log_ndisc("DNSSL option has invalid size.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 255, __func__
, "NDISC: " "DNSSL option has invalid size.")
;
256 return -EBADMSG74;
257 }
258
259 break;
260 }
261
262 p += length, left -= length;
263 }
264
265 rt->rindex = sizeof(struct nd_router_advert);
266 return 0;
267}
268
269_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret) {
270 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 270, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
271 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 271, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
272
273 *ret = rt->hop_limit;
274 return 0;
275}
276
277_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret_flags) {
278 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 278, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
279 assert_return(ret_flags, -EINVAL)do { if (!(((__builtin_expect(!!(ret_flags),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret_flags"), "../src/libsystemd-network/ndisc-router.c"
, 279, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
280
281 *ret_flags = rt->flags;
282 return 0;
283}
284
285_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint16_t *ret_lifetime) {
286 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 286, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
287 assert_return(ret_lifetime, -EINVAL)do { if (!(((__builtin_expect(!!(ret_lifetime),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("ret_lifetime"
), "../src/libsystemd-network/ndisc-router.c", 287, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
288
289 *ret_lifetime = rt->lifetime;
290 return 0;
291}
292
293_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret) {
294 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 294, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
295 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 295, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
296
297 *ret = rt->preference;
298 return 0;
299}
300
301_public___attribute__ ((visibility("default"))) int sd_ndisc_router_get_mtu(sd_ndisc_router *rt, uint32_t *ret) {
302 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 302, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
303 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 303, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
304
305 if (rt->mtu <= 0)
306 return -ENODATA61;
307
308 *ret = rt->mtu;
309 return 0;
310}
311
312_public___attribute__ ((visibility("default"))) int sd_ndisc_router_option_rewind(sd_ndisc_router *rt) {
313 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 313, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
314
315 assert(rt->raw_size >= sizeof(struct nd_router_advert))do { if ((__builtin_expect(!!(!(rt->raw_size >= sizeof(
struct nd_router_advert))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("rt->raw_size >= sizeof(struct nd_router_advert)"), "../src/libsystemd-network/ndisc-router.c"
, 315, __PRETTY_FUNCTION__); } while (0)
;
316 rt->rindex = sizeof(struct nd_router_advert);
317
318 return rt->rindex < rt->raw_size;
319}
320
321_public___attribute__ ((visibility("default"))) int sd_ndisc_router_option_next(sd_ndisc_router *rt) {
322 size_t length;
323
324 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 324, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
325
326 if (rt->rindex == rt->raw_size) /* EOF */
327 return -ESPIPE29;
328
329 if (rt->rindex + 2 > rt->raw_size) /* Truncated message */
330 return -EBADMSG74;
331
332 length = NDISC_ROUTER_OPTION_LENGTH(rt);
333 if (rt->rindex + length > rt->raw_size)
334 return -EBADMSG74;
335
336 rt->rindex += length;
337 return rt->rindex < rt->raw_size;
338}
339
340_public___attribute__ ((visibility("default"))) int sd_ndisc_router_option_get_type(sd_ndisc_router *rt, uint8_t *ret) {
341 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 341, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
342 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 342, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
343
344 if (rt->rindex == rt->raw_size) /* EOF */
345 return -ESPIPE29;
346
347 if (rt->rindex + 2 > rt->raw_size) /* Truncated message */
348 return -EBADMSG74;
349
350 *ret = NDISC_ROUTER_OPTION_TYPE(rt);
351 return 0;
352}
353
354_public___attribute__ ((visibility("default"))) int sd_ndisc_router_option_is_type(sd_ndisc_router *rt, uint8_t type) {
355 uint8_t k;
356 int r;
357
358 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 358, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
359
360 r = sd_ndisc_router_option_get_type(rt, &k);
361 if (r < 0)
362 return r;
363
364 return type == k;
365}
366
367_public___attribute__ ((visibility("default"))) int sd_ndisc_router_option_get_raw(sd_ndisc_router *rt, const void **ret, size_t *size) {
368 size_t length;
369
370 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 370, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
371 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 371, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
372 assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/ndisc-router.c"
, 372, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
373
374 /* Note that this returns the full option, including the option header */
375
376 if (rt->rindex + 2 > rt->raw_size)
377 return -EBADMSG74;
378
379 length = NDISC_ROUTER_OPTION_LENGTH(rt);
380 if (rt->rindex + length > rt->raw_size)
381 return -EBADMSG74;
382
383 *ret = (uint8_t*) NDISC_ROUTER_RAW(rt) + rt->rindex;
384 *size = length;
385
386 return 0;
387}
388
389static int get_prefix_info(sd_ndisc_router *rt, struct nd_opt_prefix_info **ret) {
390 struct nd_opt_prefix_info *ri;
391 size_t length;
392 int r;
393
394 assert(rt)do { if ((__builtin_expect(!!(!(rt)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 394, __PRETTY_FUNCTION__); } while (0)
;
395 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 395, __PRETTY_FUNCTION__); } while (0)
;
396
397 r = sd_ndisc_router_option_is_type(rt, SD_NDISC_OPTION_PREFIX_INFORMATION);
398 if (r < 0)
399 return r;
400 if (r == 0)
401 return -EMEDIUMTYPE124;
402
403 length = NDISC_ROUTER_OPTION_LENGTH(rt);
404 if (length != sizeof(struct nd_opt_prefix_info))
405 return -EBADMSG74;
406
407 ri = (struct nd_opt_prefix_info*) ((uint8_t*) NDISC_ROUTER_RAW(rt) + rt->rindex);
408 if (ri->nd_opt_pi_prefix_len > 128)
409 return -EBADMSG74;
410
411 *ret = ri;
412 return 0;
413}
414
415_public___attribute__ ((visibility("default"))) int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
416 struct nd_opt_prefix_info *ri;
417 int r;
418
419 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 419, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
420 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 420, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
421
422 r = get_prefix_info(rt, &ri);
423 if (r < 0)
424 return r;
425
426 *ret = be32toh(ri->nd_opt_pi_valid_time)__bswap_32 (ri->nd_opt_pi_valid_time);
427 return 0;
428}
429
430_public___attribute__ ((visibility("default"))) int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
431 struct nd_opt_prefix_info *pi;
432 int r;
433
434 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 434, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
435 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 435, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
436
437 r = get_prefix_info(rt, &pi);
438 if (r < 0)
439 return r;
440
441 *ret = be32toh(pi->nd_opt_pi_preferred_time)__bswap_32 (pi->nd_opt_pi_preferred_time);
442 return 0;
443}
444
445_public___attribute__ ((visibility("default"))) int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret) {
446 struct nd_opt_prefix_info *pi;
447 uint8_t flags;
448 int r;
449
450 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 450, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
451 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 451, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
452
453 r = get_prefix_info(rt, &pi);
454 if (r < 0)
455 return r;
456
457 flags = pi->nd_opt_pi_flags_reserved;
458
459 if ((flags & ND_OPT_PI_FLAG_AUTO0x40) && (pi->nd_opt_pi_prefix_len != 64)) {
460 log_ndisc("Invalid prefix length, ignoring prefix for stateless autoconfiguration.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))),
0, "../src/libsystemd-network/ndisc-router.c", 460, __func__
, "NDISC: " "Invalid prefix length, ignoring prefix for stateless autoconfiguration."
)
;
461 flags &= ~ND_OPT_PI_FLAG_AUTO0x40;
462 }
463
464 *ret = flags;
465 return 0;
466}
467
468_public___attribute__ ((visibility("default"))) int sd_ndisc_router_prefix_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr) {
469 struct nd_opt_prefix_info *pi;
470 int r;
471
472 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 472, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
473 assert_return(ret_addr, -EINVAL)do { if (!(((__builtin_expect(!!(ret_addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret_addr"), "../src/libsystemd-network/ndisc-router.c"
, 473, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
474
475 r = get_prefix_info(rt, &pi);
476 if (r < 0)
477 return r;
478
479 *ret_addr = pi->nd_opt_pi_prefix;
480 return 0;
481}
482
483_public___attribute__ ((visibility("default"))) int sd_ndisc_router_prefix_get_prefixlen(sd_ndisc_router *rt, unsigned *ret) {
484 struct nd_opt_prefix_info *pi;
485 int r;
486
487 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 487, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
488 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 488, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
489
490 r = get_prefix_info(rt, &pi);
491 if (r < 0)
492 return r;
493
494 if (pi->nd_opt_pi_prefix_len > 128)
495 return -EBADMSG74;
496
497 *ret = pi->nd_opt_pi_prefix_len;
498 return 0;
499}
500
501static int get_route_info(sd_ndisc_router *rt, uint8_t **ret) {
502 uint8_t *ri;
503 size_t length;
504 int r;
505
506 assert(rt)do { if ((__builtin_expect(!!(!(rt)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 506, __PRETTY_FUNCTION__); } while (0)
;
507 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 507, __PRETTY_FUNCTION__); } while (0)
;
508
509 r = sd_ndisc_router_option_is_type(rt, SD_NDISC_OPTION_ROUTE_INFORMATION);
510 if (r < 0)
511 return r;
512 if (r == 0)
513 return -EMEDIUMTYPE124;
514
515 length = NDISC_ROUTER_OPTION_LENGTH(rt);
516 if (length < 1*8 || length > 3*8)
517 return -EBADMSG74;
518
519 ri = (uint8_t*) NDISC_ROUTER_RAW(rt) + rt->rindex;
520
521 if (ri[2] > 128)
522 return -EBADMSG74;
523
524 *ret = ri;
525 return 0;
526}
527
528_public___attribute__ ((visibility("default"))) int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
529 uint8_t *ri;
530 int r;
531
532 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 532, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
533 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 533, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
534
535 r = get_route_info(rt, &ri);
536 if (r < 0)
537 return r;
538
539 *ret = be32toh(*(uint32_t*) (ri + 4))__bswap_32 (*(uint32_t*) (ri + 4));
540 return 0;
541}
542
543_public___attribute__ ((visibility("default"))) int sd_ndisc_router_route_get_address(sd_ndisc_router *rt, struct in6_addr *ret_addr) {
544 uint8_t *ri;
545 int r;
546
547 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 547, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
548 assert_return(ret_addr, -EINVAL)do { if (!(((__builtin_expect(!!(ret_addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret_addr"), "../src/libsystemd-network/ndisc-router.c"
, 548, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
549
550 r = get_route_info(rt, &ri);
551 if (r < 0)
552 return r;
553
554 zero(*ret_addr)(({ size_t _l_ = (sizeof(*ret_addr)); void *_x_ = (&(*ret_addr
)); _l_ == 0 ? _x_ : memset(_x_, 0, _l_); }))
;
555 memcpy(ret_addr, ri + 8, NDISC_ROUTER_OPTION_LENGTH(rt) - 8);
556
557 return 0;
558}
559
560_public___attribute__ ((visibility("default"))) int sd_ndisc_router_route_get_prefixlen(sd_ndisc_router *rt, unsigned *ret) {
561 uint8_t *ri;
562 int r;
563
564 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 564, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
565 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 565, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
566
567 r = get_route_info(rt, &ri);
568 if (r < 0)
569 return r;
570
571 *ret = ri[2];
572 return 0;
573}
574
575_public___attribute__ ((visibility("default"))) int sd_ndisc_router_route_get_preference(sd_ndisc_router *rt, unsigned *ret) {
576 uint8_t *ri;
577 int r;
578
579 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 579, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
580 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 580, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
581
582 r = get_route_info(rt, &ri);
583 if (r < 0)
584 return r;
585
586 *ret = (ri[3] >> 3) & 3;
587 if (!IN_SET(*ret, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH
})/sizeof(int)]; switch(*ret) { case SD_NDISC_PREFERENCE_LOW:
case SD_NDISC_PREFERENCE_HIGH: _found = 1; break; default: break
; } _found; })
)
588 *ret = SD_NDISC_PREFERENCE_MEDIUM;
589
590 return 0;
591}
592
593static int get_rdnss_info(sd_ndisc_router *rt, uint8_t **ret) {
594 size_t length;
595 int r;
596
597 assert(rt)do { if ((__builtin_expect(!!(!(rt)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 597, __PRETTY_FUNCTION__); } while (0)
;
598 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 598, __PRETTY_FUNCTION__); } while (0)
;
599
600 r = sd_ndisc_router_option_is_type(rt, SD_NDISC_OPTION_RDNSS);
601 if (r < 0)
602 return r;
603 if (r == 0)
604 return -EMEDIUMTYPE124;
605
606 length = NDISC_ROUTER_OPTION_LENGTH(rt);
607 if (length < 3*8 || (length % (2*8)) != 1*8)
608 return -EBADMSG74;
609
610 *ret = (uint8_t*) NDISC_ROUTER_RAW(rt) + rt->rindex;
611 return 0;
612}
613
614_public___attribute__ ((visibility("default"))) int sd_ndisc_router_rdnss_get_addresses(sd_ndisc_router *rt, const struct in6_addr **ret) {
615 uint8_t *ri;
616 int r;
617
618 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 618, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
619 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 619, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
620
621 r = get_rdnss_info(rt, &ri);
622 if (r < 0)
623 return r;
624
625 *ret = (const struct in6_addr*) (ri + 8);
626 return (NDISC_ROUTER_OPTION_LENGTH(rt) - 8) / 16;
627}
628
629_public___attribute__ ((visibility("default"))) int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
630 uint8_t *ri;
631 int r;
632
633 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 633, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
634 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 634, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
635
636 r = get_rdnss_info(rt, &ri);
637 if (r < 0)
638 return r;
639
640 *ret = be32toh(*(uint32_t*) (ri + 4))__bswap_32 (*(uint32_t*) (ri + 4));
641 return 0;
642}
643
644static int get_dnssl_info(sd_ndisc_router *rt, uint8_t **ret) {
645 size_t length;
646 int r;
647
648 assert(rt)do { if ((__builtin_expect(!!(!(rt)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 648, __PRETTY_FUNCTION__); } while (0)
;
649 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 649, __PRETTY_FUNCTION__); } while (0)
;
650
651 r = sd_ndisc_router_option_is_type(rt, SD_NDISC_OPTION_DNSSL);
652 if (r < 0)
653 return r;
654 if (r == 0)
655 return -EMEDIUMTYPE124;
656
657 length = NDISC_ROUTER_OPTION_LENGTH(rt);
658 if (length < 2*8)
659 return -EBADMSG74;
660
661 *ret = (uint8_t*) NDISC_ROUTER_RAW(rt) + rt->rindex;
662 return 0;
663}
664
665_public___attribute__ ((visibility("default"))) int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret) {
666 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
667 _cleanup_free___attribute__((cleanup(freep))) char *e = NULL((void*)0);
668 size_t allocated = 0, n = 0, left;
669 uint8_t *ri, *p;
670 bool_Bool first = true1;
671 int r;
672 unsigned k = 0;
673
674 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 674, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
675 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/ndisc-router.c"
, 675, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
676
677 r = get_dnssl_info(rt, &ri);
678 if (r < 0)
679 return r;
680
681 p = ri + 8;
682 left = NDISC_ROUTER_OPTION_LENGTH(rt) - 8;
683
684 for (;;) {
685 if (left == 0) {
686
687 if (n > 0) /* Not properly NUL terminated */
688 return -EBADMSG74;
689
690 break;
691 }
692
693 if (*p == 0) {
694 /* Found NUL termination */
695
696 if (n > 0) {
697 _cleanup_free___attribute__((cleanup(freep))) char *normalized = NULL((void*)0);
698
699 e[n] = 0;
700 r = dns_name_normalize(e, &normalized);
701 if (r < 0)
702 return r;
703
704 /* Ignore the root domain name or "localhost" and friends */
705 if (!is_localhost(normalized) &&
706 !dns_name_is_root(normalized)) {
707
708 if (strv_push(&l, normalized) < 0)
709 return -ENOMEM12;
710
711 normalized = NULL((void*)0);
712 k++;
713 }
714 }
715
716 n = 0;
717 first = true1;
718 p++, left--;
719 continue;
720 }
721
722 /* Check for compression (which is not allowed) */
723 if (*p > 63)
724 return -EBADMSG74;
725
726 if (1U + *p + 1U > left)
727 return -EBADMSG74;
728
729 if (!GREEDY_REALLOC(e, allocated, n + !first + DNS_LABEL_ESCAPED_MAX + 1U)greedy_realloc((void**) &(e), &(allocated), (n + !first
+ (63*4+1) + 1U), sizeof((e)[0]))
)
730 return -ENOMEM12;
731
732 if (first)
733 first = false0;
734 else
735 e[n++] = '.';
736
737 r = dns_label_escape((char*) p+1, *p, e + n, DNS_LABEL_ESCAPED_MAX(63*4+1));
738 if (r < 0)
739 return r;
740
741 n += r;
742
743 left -= 1 + *p;
744 p += 1 + *p;
745 }
746
747 if (strv_isempty(l)) {
748 *ret = NULL((void*)0);
749 return 0;
750 }
751
752 *ret = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
753
754 return k;
755}
756
757_public___attribute__ ((visibility("default"))) int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret_sec) {
758 uint8_t *ri;
759 int r;
760
761 assert_return(rt, -EINVAL)do { if (!(((__builtin_expect(!!(rt),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("rt"), "../src/libsystemd-network/ndisc-router.c"
, 761, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
762 assert_return(ret_sec, -EINVAL)do { if (!(((__builtin_expect(!!(ret_sec),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret_sec"), "../src/libsystemd-network/ndisc-router.c"
, 762, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
763
764 r = get_dnssl_info(rt, &ri);
765 if (r < 0)
766 return r;
767
768 *ret_sec = be32toh(*(uint32_t*) (ri + 4))__bswap_32 (*(uint32_t*) (ri + 4));
769 return 0;
770}