File: | build-scan/../src/libsystemd-network/network-internal.c |
Warning: | line 256, column 17 Potential leak of memory pointed to by 'n' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <arpa/inet.h> | |||
4 | #include <linux1/if.h> | |||
5 | #include <netinet/ether.h> | |||
6 | ||||
7 | #include "sd-id128.h" | |||
8 | #include "sd-ndisc.h" | |||
9 | ||||
10 | #include "alloc-util.h" | |||
11 | #include "condition.h" | |||
12 | #include "conf-parser.h" | |||
13 | #include "dhcp-lease-internal.h" | |||
14 | #include "ether-addr-util.h" | |||
15 | #include "hexdecoct.h" | |||
16 | #include "log.h" | |||
17 | #include "network-internal.h" | |||
18 | #include "parse-util.h" | |||
19 | #include "siphash24.h" | |||
20 | #include "socket-util.h" | |||
21 | #include "string-util.h" | |||
22 | #include "strv.h" | |||
23 | #include "utf8.h" | |||
24 | #include "util.h" | |||
25 | ||||
26 | const char *net_get_name(struct udev_device *device) { | |||
27 | const char *name, *field; | |||
28 | ||||
29 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd-network/network-internal.c" , 29, __PRETTY_FUNCTION__); } while (0); | |||
30 | ||||
31 | /* fetch some persistent data unique (on this machine) to this device */ | |||
32 | FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC")for (char **_l = ({ char **_ll = ((char**) ((const char*[]) { "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH" , "ID_NET_NAME_MAC", ((void*)0) })); field = _ll ? _ll[0] : ( (void*)0); _ll; }); _l && *_l; field = ({ _l ++; _l[0 ]; })) { | |||
33 | name = udev_device_get_property_value(device, field); | |||
34 | if (name) | |||
35 | return name; | |||
36 | } | |||
37 | ||||
38 | return NULL((void*)0); | |||
39 | } | |||
40 | ||||
41 | #define HASH_KEY((const sd_id128_t) { .bytes = { 0xd3, 0x1e, 0x48, 0xfa, 0x90 , 0xfe, 0x4b, 0x4c, 0x9d, 0xaf, 0xd5, 0xd7, 0xa1, 0xb1, 0x2e, 0x8a }}) SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)((const sd_id128_t) { .bytes = { 0xd3, 0x1e, 0x48, 0xfa, 0x90 , 0xfe, 0x4b, 0x4c, 0x9d, 0xaf, 0xd5, 0xd7, 0xa1, 0xb1, 0x2e, 0x8a }}) | |||
42 | ||||
43 | int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result) { | |||
44 | size_t l, sz = 0; | |||
45 | const char *name = NULL((void*)0); | |||
46 | int r; | |||
47 | uint8_t *v; | |||
48 | ||||
49 | assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("device"), "../src/libsystemd-network/network-internal.c" , 49, __PRETTY_FUNCTION__); } while (0); | |||
50 | ||||
51 | name = net_get_name(device); | |||
52 | if (!name) | |||
53 | return -ENOENT2; | |||
54 | ||||
55 | l = strlen(name); | |||
56 | sz = sizeof(sd_id128_t) + l; | |||
57 | v = alloca(sz)__builtin_alloca (sz); | |||
58 | ||||
59 | /* fetch some persistent data unique to this machine */ | |||
60 | r = sd_id128_get_machine((sd_id128_t*) v); | |||
61 | if (r < 0) | |||
62 | return r; | |||
63 | memcpy(v + sizeof(sd_id128_t), name, l); | |||
64 | ||||
65 | /* Let's hash the machine ID plus the device name. We | |||
66 | * use a fixed, but originally randomly created hash | |||
67 | * key here. */ | |||
68 | *result = htole64(siphash24(v, sz, HASH_KEY((const sd_id128_t) { .bytes = { 0xd3, 0x1e, 0x48, 0xfa, 0x90 , 0xfe, 0x4b, 0x4c, 0x9d, 0xaf, 0xd5, 0xd7, 0xa1, 0xb1, 0x2e, 0x8a }}).bytes)); | |||
69 | ||||
70 | return 0; | |||
71 | } | |||
72 | ||||
73 | static bool_Bool net_condition_test_strv(char * const *raw_patterns, | |||
74 | const char *string) { | |||
75 | if (strv_isempty(raw_patterns)) | |||
76 | return true1; | |||
77 | ||||
78 | /* If the patterns begin with "!", edit it out and negate the test. */ | |||
79 | if (raw_patterns[0][0] == '!') { | |||
80 | char **patterns; | |||
81 | size_t i, length; | |||
82 | ||||
83 | length = strv_length(raw_patterns) + 1; /* Include the NULL. */ | |||
84 | patterns = newa(char*, length)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (char*), length))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("!size_multiply_overflow(sizeof(char*), length)"), "../src/libsystemd-network/network-internal.c" , 84, __PRETTY_FUNCTION__); } while (0); (char**) __builtin_alloca (sizeof(char*)*(length)); }); | |||
85 | patterns[0] = raw_patterns[0] + 1; /* Skip the "!". */ | |||
86 | for (i = 1; i < length; i++) | |||
87 | patterns[i] = raw_patterns[i]; | |||
88 | ||||
89 | return !string || !strv_fnmatch(patterns, string, 0); | |||
90 | } | |||
91 | ||||
92 | return string && strv_fnmatch(raw_patterns, string, 0); | |||
93 | } | |||
94 | ||||
95 | bool_Bool net_match_config(Set *match_mac, | |||
96 | char * const *match_paths, | |||
97 | char * const *match_drivers, | |||
98 | char * const *match_types, | |||
99 | char * const *match_names, | |||
100 | Condition *match_host, | |||
101 | Condition *match_virt, | |||
102 | Condition *match_kernel_cmdline, | |||
103 | Condition *match_kernel_version, | |||
104 | Condition *match_arch, | |||
105 | const struct ether_addr *dev_mac, | |||
106 | const char *dev_path, | |||
107 | const char *dev_parent_driver, | |||
108 | const char *dev_driver, | |||
109 | const char *dev_type, | |||
110 | const char *dev_name) { | |||
111 | ||||
112 | if (match_host && condition_test(match_host) <= 0) | |||
113 | return false0; | |||
114 | ||||
115 | if (match_virt && condition_test(match_virt) <= 0) | |||
116 | return false0; | |||
117 | ||||
118 | if (match_kernel_cmdline && condition_test(match_kernel_cmdline) <= 0) | |||
119 | return false0; | |||
120 | ||||
121 | if (match_kernel_version && condition_test(match_kernel_version) <= 0) | |||
122 | return false0; | |||
123 | ||||
124 | if (match_arch && condition_test(match_arch) <= 0) | |||
125 | return false0; | |||
126 | ||||
127 | if (match_mac && dev_mac && !set_contains(match_mac, dev_mac)) | |||
128 | return false0; | |||
129 | ||||
130 | if (!net_condition_test_strv(match_paths, dev_path)) | |||
131 | return false0; | |||
132 | ||||
133 | if (!net_condition_test_strv(match_drivers, dev_driver)) | |||
134 | return false0; | |||
135 | ||||
136 | if (!net_condition_test_strv(match_types, dev_type)) | |||
137 | return false0; | |||
138 | ||||
139 | if (!net_condition_test_strv(match_names, dev_name)) | |||
140 | return false0; | |||
141 | ||||
142 | return true1; | |||
143 | } | |||
144 | ||||
145 | int config_parse_net_condition(const char *unit, | |||
146 | const char *filename, | |||
147 | unsigned line, | |||
148 | const char *section, | |||
149 | unsigned section_line, | |||
150 | const char *lvalue, | |||
151 | int ltype, | |||
152 | const char *rvalue, | |||
153 | void *data, | |||
154 | void *userdata) { | |||
155 | ||||
156 | ConditionType cond = ltype; | |||
157 | Condition **ret = data; | |||
158 | bool_Bool negate; | |||
159 | Condition *c; | |||
160 | _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0); | |||
161 | ||||
162 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 162, __PRETTY_FUNCTION__); } while (0); | |||
163 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 163, __PRETTY_FUNCTION__); } while (0); | |||
164 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 164, __PRETTY_FUNCTION__); } while (0); | |||
165 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 165, __PRETTY_FUNCTION__); } while (0); | |||
166 | ||||
167 | negate = rvalue[0] == '!'; | |||
168 | if (negate) | |||
169 | rvalue++; | |||
170 | ||||
171 | s = strdup(rvalue); | |||
172 | if (!s) | |||
173 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 173, __func__); | |||
174 | ||||
175 | c = condition_new(cond, s, false0, negate); | |||
176 | if (!c) | |||
177 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 177, __func__); | |||
178 | ||||
179 | if (*ret) | |||
180 | condition_free(*ret); | |||
181 | ||||
182 | *ret = c; | |||
183 | return 0; | |||
184 | } | |||
185 | ||||
186 | int config_parse_ifnames( | |||
187 | const char *unit, | |||
188 | const char *filename, | |||
189 | unsigned line, | |||
190 | const char *section, | |||
191 | unsigned section_line, | |||
192 | const char *lvalue, | |||
193 | int ltype, | |||
194 | const char *rvalue, | |||
195 | void *data, | |||
196 | void *userdata) { | |||
197 | ||||
198 | char ***sv = data; | |||
199 | int r; | |||
200 | ||||
201 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 201, __PRETTY_FUNCTION__); } while (0); | |||
202 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 202, __PRETTY_FUNCTION__); } while (0); | |||
203 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 203, __PRETTY_FUNCTION__); } while (0); | |||
204 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 204, __PRETTY_FUNCTION__); } while (0); | |||
205 | ||||
206 | for (;;) { | |||
207 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
208 | ||||
209 | r = extract_first_word(&rvalue, &word, NULL((void*)0), 0); | |||
210 | if (r < 0) { | |||
211 | log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 211, __func__, "Failed to parse interface name list: %s", rvalue ) : -abs(_e); }); | |||
212 | return 0; | |||
213 | } | |||
214 | if (r == 0) | |||
215 | break; | |||
216 | ||||
217 | if (!ifname_valid(word)) { | |||
218 | log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 218, __func__, "Interface name is not valid or too long, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
219 | return 0; | |||
220 | } | |||
221 | ||||
222 | r = strv_push(sv, word); | |||
223 | if (r < 0) | |||
224 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 224, __func__); | |||
225 | ||||
226 | word = NULL((void*)0); | |||
227 | } | |||
228 | ||||
229 | return 0; | |||
230 | } | |||
231 | ||||
232 | int config_parse_ifalias(const char *unit, | |||
233 | const char *filename, | |||
234 | unsigned line, | |||
235 | const char *section, | |||
236 | unsigned section_line, | |||
237 | const char *lvalue, | |||
238 | int ltype, | |||
239 | const char *rvalue, | |||
240 | void *data, | |||
241 | void *userdata) { | |||
242 | ||||
243 | char **s = data; | |||
244 | _cleanup_free___attribute__((cleanup(freep))) char *n = NULL((void*)0); | |||
245 | ||||
246 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 246, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
247 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 247, __PRETTY_FUNCTION__); } while (0); | |||
248 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 248, __PRETTY_FUNCTION__); } while (0); | |||
249 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 249, __PRETTY_FUNCTION__); } while (0); | |||
250 | ||||
251 | n = strdup(rvalue); | |||
252 | if (!n) | |||
253 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 253, __func__); | |||
254 | ||||
255 | if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ256) { | |||
256 | log_syntax(unit, LOG_ERR, filename, line, 0, "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 256, __func__, "Interface alias is not ASCII clean or is too long, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
| ||||
257 | return 0; | |||
258 | } | |||
259 | ||||
260 | free(*s); | |||
261 | if (*n) | |||
262 | *s = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
263 | else | |||
264 | *s = NULL((void*)0); | |||
265 | ||||
266 | return 0; | |||
267 | } | |||
268 | ||||
269 | int config_parse_hwaddr(const char *unit, | |||
270 | const char *filename, | |||
271 | unsigned line, | |||
272 | const char *section, | |||
273 | unsigned section_line, | |||
274 | const char *lvalue, | |||
275 | int ltype, | |||
276 | const char *rvalue, | |||
277 | void *data, | |||
278 | void *userdata) { | |||
279 | ||||
280 | _cleanup_free___attribute__((cleanup(freep))) struct ether_addr *n = NULL((void*)0); | |||
281 | struct ether_addr **hwaddr = data; | |||
282 | int r; | |||
283 | ||||
284 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 284, __PRETTY_FUNCTION__); } while (0); | |||
285 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 285, __PRETTY_FUNCTION__); } while (0); | |||
286 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 286, __PRETTY_FUNCTION__); } while (0); | |||
287 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 287, __PRETTY_FUNCTION__); } while (0); | |||
288 | ||||
289 | n = new0(struct ether_addr, 1)((struct ether_addr*) calloc((1), sizeof(struct ether_addr))); | |||
290 | if (!n) | |||
291 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 291, __func__); | |||
292 | ||||
293 | r = ether_addr_from_string(rvalue, n); | |||
294 | if (r < 0) { | |||
295 | log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 295, __func__, "Not a valid MAC address, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
296 | return 0; | |||
297 | } | |||
298 | ||||
299 | *hwaddr = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
300 | ||||
301 | return 0; | |||
302 | } | |||
303 | ||||
304 | int config_parse_hwaddrs(const char *unit, | |||
305 | const char *filename, | |||
306 | unsigned line, | |||
307 | const char *section, | |||
308 | unsigned section_line, | |||
309 | const char *lvalue, | |||
310 | int ltype, | |||
311 | const char *rvalue, | |||
312 | void *data, | |||
313 | void *userdata) { | |||
314 | ||||
315 | _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *s = NULL((void*)0); | |||
316 | const char *p = rvalue; | |||
317 | Set **hwaddrs = data; | |||
318 | int r; | |||
319 | ||||
320 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 320, __PRETTY_FUNCTION__); } while (0); | |||
321 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 321, __PRETTY_FUNCTION__); } while (0); | |||
322 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 322, __PRETTY_FUNCTION__); } while (0); | |||
323 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 323, __PRETTY_FUNCTION__); } while (0); | |||
324 | ||||
325 | if (isempty(rvalue)) { | |||
326 | /* Empty assignment resets the list */ | |||
327 | *hwaddrs = set_free_free(*hwaddrs); | |||
328 | return 0; | |||
329 | } | |||
330 | ||||
331 | s = set_new(ðer_addr_hash_ops)internal_set_new(ðer_addr_hash_ops ); | |||
332 | if (!s) | |||
333 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 333, __func__); | |||
334 | ||||
335 | for (;;) { | |||
336 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
337 | _cleanup_free___attribute__((cleanup(freep))) struct ether_addr *n = NULL((void*)0); | |||
338 | ||||
339 | r = extract_first_word(&p, &word, NULL((void*)0), 0); | |||
340 | if (r == 0) | |||
341 | break; | |||
342 | if (r == -ENOMEM12) | |||
343 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 343, __func__); | |||
344 | if (r < 0) { | |||
345 | log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue)({ int _level = (4), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 345, __func__, "Invalid syntax, ignoring: %s", rvalue) : -abs (_e); }); | |||
346 | return 0; | |||
347 | } | |||
348 | ||||
349 | n = new(struct ether_addr, 1)((struct ether_addr*) malloc_multiply(sizeof(struct ether_addr ), (1))); | |||
350 | if (!n) | |||
351 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 351, __func__); | |||
352 | ||||
353 | r = ether_addr_from_string(word, n); | |||
354 | if (r < 0) { | |||
355 | log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring: %s", word)({ int _level = (3), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 355, __func__, "Not a valid MAC address, ignoring: %s", word ) : -abs(_e); }); | |||
356 | continue; | |||
357 | } | |||
358 | ||||
359 | r = set_put(s, n); | |||
360 | if (r < 0) | |||
361 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 361, __func__); | |||
362 | if (r > 0) | |||
363 | n = NULL((void*)0); /* avoid cleanup */ | |||
364 | } | |||
365 | ||||
366 | r = set_ensure_allocated(hwaddrs, ðer_addr_hash_ops)internal_set_ensure_allocated(hwaddrs, ðer_addr_hash_ops ); | |||
367 | if (r < 0) | |||
368 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 368, __func__); | |||
369 | ||||
370 | r = set_move(*hwaddrs, s); | |||
371 | if (r < 0) | |||
372 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/libsystemd-network/network-internal.c" , 372, __func__); | |||
373 | ||||
374 | return 0; | |||
375 | } | |||
376 | ||||
377 | int config_parse_iaid(const char *unit, | |||
378 | const char *filename, | |||
379 | unsigned line, | |||
380 | const char *section, | |||
381 | unsigned section_line, | |||
382 | const char *lvalue, | |||
383 | int ltype, | |||
384 | const char *rvalue, | |||
385 | void *data, | |||
386 | void *userdata) { | |||
387 | uint32_t iaid; | |||
388 | int r; | |||
389 | ||||
390 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 390, __PRETTY_FUNCTION__); } while (0); | |||
391 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 391, __PRETTY_FUNCTION__); } while (0); | |||
392 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 392, __PRETTY_FUNCTION__); } while (0); | |||
393 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 393, __PRETTY_FUNCTION__); } while (0); | |||
394 | ||||
395 | r = safe_atou32(rvalue, &iaid); | |||
396 | if (r < 0) { | |||
397 | log_syntax(unit, LOG_ERR, filename, line, r,({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 398, __func__, "Unable to read IAID, ignoring assignment: %s" , rvalue) : -abs(_e); }) | |||
398 | "Unable to read IAID, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 398, __func__, "Unable to read IAID, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
399 | return 0; | |||
400 | } | |||
401 | ||||
402 | *((uint32_t *)data) = iaid; | |||
403 | ||||
404 | return 0; | |||
405 | } | |||
406 | ||||
407 | int config_parse_bridge_port_priority( | |||
408 | const char *unit, | |||
409 | const char *filename, | |||
410 | unsigned line, | |||
411 | const char *section, | |||
412 | unsigned section_line, | |||
413 | const char *lvalue, | |||
414 | int ltype, | |||
415 | const char *rvalue, | |||
416 | void *data, | |||
417 | void *userdata) { | |||
418 | ||||
419 | uint16_t i; | |||
420 | int r; | |||
421 | ||||
422 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/libsystemd-network/network-internal.c" , 422, __PRETTY_FUNCTION__); } while (0); | |||
423 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/libsystemd-network/network-internal.c" , 423, __PRETTY_FUNCTION__); } while (0); | |||
424 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/libsystemd-network/network-internal.c" , 424, __PRETTY_FUNCTION__); } while (0); | |||
425 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 425, __PRETTY_FUNCTION__); } while (0); | |||
426 | ||||
427 | r = safe_atou16(rvalue, &i); | |||
428 | if (r < 0) { | |||
429 | log_syntax(unit, LOG_ERR, filename, line, r,({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 430, __func__, "Failed to parse bridge port priority, ignoring: %s" , rvalue) : -abs(_e); }) | |||
430 | "Failed to parse bridge port priority, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 430, __func__, "Failed to parse bridge port priority, ignoring: %s" , rvalue) : -abs(_e); }); | |||
431 | return 0; | |||
432 | } | |||
433 | ||||
434 | if (i > LINK_BRIDGE_PORT_PRIORITY_MAX63) { | |||
435 | log_syntax(unit, LOG_ERR, filename, line, r,({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 436, __func__, "Bridge port priority is larger than maximum %u, ignoring: %s" , 63, rvalue) : -abs(_e); }) | |||
436 | "Bridge port priority is larger than maximum %u, ignoring: %s", LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/libsystemd-network/network-internal.c" , 436, __func__, "Bridge port priority is larger than maximum %u, ignoring: %s" , 63, rvalue) : -abs(_e); }); | |||
437 | return 0; | |||
438 | } | |||
439 | ||||
440 | *((uint16_t *)data) = i; | |||
441 | ||||
442 | return 0; | |||
443 | } | |||
444 | ||||
445 | void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) { | |||
446 | unsigned i; | |||
447 | ||||
448 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/libsystemd-network/network-internal.c" , 448, __PRETTY_FUNCTION__); } while (0); | |||
449 | assert(addresses)do { if ((__builtin_expect(!!(!(addresses)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("addresses"), "../src/libsystemd-network/network-internal.c" , 449, __PRETTY_FUNCTION__); } while (0); | |||
450 | assert(size)do { if ((__builtin_expect(!!(!(size)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/network-internal.c" , 450, __PRETTY_FUNCTION__); } while (0); | |||
451 | ||||
452 | for (i = 0; i < size; i++) | |||
453 | fprintf(f, "%s%s", inet_ntoa(addresses[i]), | |||
454 | (i < (size - 1)) ? " ": ""); | |||
455 | } | |||
456 | ||||
457 | int deserialize_in_addrs(struct in_addr **ret, const char *string) { | |||
458 | _cleanup_free___attribute__((cleanup(freep))) struct in_addr *addresses = NULL((void*)0); | |||
459 | int size = 0; | |||
460 | ||||
461 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/network-internal.c" , 461, __PRETTY_FUNCTION__); } while (0); | |||
462 | assert(string)do { if ((__builtin_expect(!!(!(string)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("string"), "../src/libsystemd-network/network-internal.c" , 462, __PRETTY_FUNCTION__); } while (0); | |||
463 | ||||
464 | for (;;) { | |||
465 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
466 | struct in_addr *new_addresses; | |||
467 | int r; | |||
468 | ||||
469 | r = extract_first_word(&string, &word, NULL((void*)0), 0); | |||
470 | if (r < 0) | |||
471 | return r; | |||
472 | if (r == 0) | |||
473 | break; | |||
474 | ||||
475 | new_addresses = reallocarray(addresses, size + 1, sizeof(struct in_addr)); | |||
476 | if (!new_addresses) | |||
477 | return -ENOMEM12; | |||
478 | else | |||
479 | addresses = new_addresses; | |||
480 | ||||
481 | r = inet_pton(AF_INET2, word, &(addresses[size])); | |||
482 | if (r <= 0) | |||
483 | continue; | |||
484 | ||||
485 | size++; | |||
486 | } | |||
487 | ||||
488 | *ret = TAKE_PTR(addresses)({ typeof(addresses) _ptr_ = (addresses); (addresses) = ((void *)0); _ptr_; }); | |||
489 | ||||
490 | return size; | |||
491 | } | |||
492 | ||||
493 | void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, size_t size) { | |||
494 | unsigned i; | |||
495 | ||||
496 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/libsystemd-network/network-internal.c" , 496, __PRETTY_FUNCTION__); } while (0); | |||
497 | assert(addresses)do { if ((__builtin_expect(!!(!(addresses)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("addresses"), "../src/libsystemd-network/network-internal.c" , 497, __PRETTY_FUNCTION__); } while (0); | |||
498 | assert(size)do { if ((__builtin_expect(!!(!(size)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/network-internal.c" , 498, __PRETTY_FUNCTION__); } while (0); | |||
499 | ||||
500 | for (i = 0; i < size; i++) { | |||
501 | char buffer[INET6_ADDRSTRLEN46]; | |||
502 | ||||
503 | fputs(inet_ntop(AF_INET610, addresses+i, buffer, sizeof(buffer)), f); | |||
504 | ||||
505 | if (i < size - 1) | |||
506 | fputc(' ', f); | |||
507 | } | |||
508 | } | |||
509 | ||||
510 | int deserialize_in6_addrs(struct in6_addr **ret, const char *string) { | |||
511 | _cleanup_free___attribute__((cleanup(freep))) struct in6_addr *addresses = NULL((void*)0); | |||
512 | int size = 0; | |||
513 | ||||
514 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/network-internal.c" , 514, __PRETTY_FUNCTION__); } while (0); | |||
515 | assert(string)do { if ((__builtin_expect(!!(!(string)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("string"), "../src/libsystemd-network/network-internal.c" , 515, __PRETTY_FUNCTION__); } while (0); | |||
516 | ||||
517 | for (;;) { | |||
518 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
519 | struct in6_addr *new_addresses; | |||
520 | int r; | |||
521 | ||||
522 | r = extract_first_word(&string, &word, NULL((void*)0), 0); | |||
523 | if (r < 0) | |||
524 | return r; | |||
525 | if (r == 0) | |||
526 | break; | |||
527 | ||||
528 | new_addresses = reallocarray(addresses, size + 1, sizeof(struct in6_addr)); | |||
529 | if (!new_addresses) | |||
530 | return -ENOMEM12; | |||
531 | else | |||
532 | addresses = new_addresses; | |||
533 | ||||
534 | r = inet_pton(AF_INET610, word, &(addresses[size])); | |||
535 | if (r <= 0) | |||
536 | continue; | |||
537 | ||||
538 | size++; | |||
539 | } | |||
540 | ||||
541 | *ret = TAKE_PTR(addresses)({ typeof(addresses) _ptr_ = (addresses); (addresses) = ((void *)0); _ptr_; }); | |||
542 | ||||
543 | return size; | |||
544 | } | |||
545 | ||||
546 | void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) { | |||
547 | unsigned i; | |||
548 | ||||
549 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/libsystemd-network/network-internal.c" , 549, __PRETTY_FUNCTION__); } while (0); | |||
550 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd-network/network-internal.c" , 550, __PRETTY_FUNCTION__); } while (0); | |||
551 | assert(routes)do { if ((__builtin_expect(!!(!(routes)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("routes"), "../src/libsystemd-network/network-internal.c" , 551, __PRETTY_FUNCTION__); } while (0); | |||
552 | assert(size)do { if ((__builtin_expect(!!(!(size)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/network-internal.c" , 552, __PRETTY_FUNCTION__); } while (0); | |||
553 | ||||
554 | fprintf(f, "%s=", key); | |||
555 | ||||
556 | for (i = 0; i < size; i++) { | |||
557 | struct in_addr dest, gw; | |||
558 | uint8_t length; | |||
559 | ||||
560 | assert_se(sd_dhcp_route_get_destination(routes[i], &dest) >= 0)do { if ((__builtin_expect(!!(!(sd_dhcp_route_get_destination (routes[i], &dest) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sd_dhcp_route_get_destination(routes[i], &dest) >= 0" ), "../src/libsystemd-network/network-internal.c", 560, __PRETTY_FUNCTION__ ); } while (0); | |||
561 | assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0)do { if ((__builtin_expect(!!(!(sd_dhcp_route_get_gateway(routes [i], &gw) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("sd_dhcp_route_get_gateway(routes[i], &gw) >= 0"), "../src/libsystemd-network/network-internal.c" , 561, __PRETTY_FUNCTION__); } while (0); | |||
562 | assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0)do { if ((__builtin_expect(!!(!(sd_dhcp_route_get_destination_prefix_length (routes[i], &length) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0" ), "../src/libsystemd-network/network-internal.c", 562, __PRETTY_FUNCTION__ ); } while (0); | |||
563 | ||||
564 | fprintf(f, "%s/%" PRIu8"u", inet_ntoa(dest), length); | |||
565 | fprintf(f, ",%s%s", inet_ntoa(gw), (i < (size - 1)) ? " ": ""); | |||
566 | } | |||
567 | ||||
568 | fputs("\n", f); | |||
569 | } | |||
570 | ||||
571 | int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) { | |||
572 | _cleanup_free___attribute__((cleanup(freep))) struct sd_dhcp_route *routes = NULL((void*)0); | |||
573 | size_t size = 0, allocated = 0; | |||
574 | ||||
575 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/network-internal.c" , 575, __PRETTY_FUNCTION__); } while (0); | |||
576 | assert(ret_size)do { if ((__builtin_expect(!!(!(ret_size)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret_size"), "../src/libsystemd-network/network-internal.c" , 576, __PRETTY_FUNCTION__); } while (0); | |||
577 | assert(ret_allocated)do { if ((__builtin_expect(!!(!(ret_allocated)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret_allocated"), "../src/libsystemd-network/network-internal.c" , 577, __PRETTY_FUNCTION__); } while (0); | |||
578 | assert(string)do { if ((__builtin_expect(!!(!(string)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("string"), "../src/libsystemd-network/network-internal.c" , 578, __PRETTY_FUNCTION__); } while (0); | |||
579 | ||||
580 | /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */ | |||
581 | for (;;) { | |||
582 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
583 | char *tok, *tok_end; | |||
584 | unsigned n; | |||
585 | int r; | |||
586 | ||||
587 | r = extract_first_word(&string, &word, NULL((void*)0), 0); | |||
588 | if (r < 0) | |||
589 | return r; | |||
590 | if (r == 0) | |||
591 | break; | |||
592 | ||||
593 | if (!GREEDY_REALLOC(routes, allocated, size + 1)greedy_realloc((void**) &(routes), &(allocated), (size + 1), sizeof((routes)[0]))) | |||
594 | return -ENOMEM12; | |||
595 | ||||
596 | tok = word; | |||
597 | ||||
598 | /* get the subnet */ | |||
599 | tok_end = strchr(tok, '/'); | |||
600 | if (!tok_end) | |||
601 | continue; | |||
602 | *tok_end = '\0'; | |||
603 | ||||
604 | r = inet_aton(tok, &routes[size].dst_addr); | |||
605 | if (r == 0) | |||
606 | continue; | |||
607 | ||||
608 | tok = tok_end + 1; | |||
609 | ||||
610 | /* get the prefixlen */ | |||
611 | tok_end = strchr(tok, ','); | |||
612 | if (!tok_end) | |||
613 | continue; | |||
614 | ||||
615 | *tok_end = '\0'; | |||
616 | ||||
617 | r = safe_atou(tok, &n); | |||
618 | if (r < 0 || n > 32) | |||
619 | continue; | |||
620 | ||||
621 | routes[size].dst_prefixlen = (uint8_t) n; | |||
622 | tok = tok_end + 1; | |||
623 | ||||
624 | /* get the gateway */ | |||
625 | r = inet_aton(tok, &routes[size].gw_addr); | |||
626 | if (r == 0) | |||
627 | continue; | |||
628 | ||||
629 | size++; | |||
630 | } | |||
631 | ||||
632 | *ret_size = size; | |||
633 | *ret_allocated = allocated; | |||
634 | *ret = TAKE_PTR(routes)({ typeof(routes) _ptr_ = (routes); (routes) = ((void*)0); _ptr_ ; }); | |||
635 | ||||
636 | return 0; | |||
637 | } | |||
638 | ||||
639 | int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size) { | |||
640 | _cleanup_free___attribute__((cleanup(freep))) char *hex_buf = NULL((void*)0); | |||
641 | ||||
642 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/libsystemd-network/network-internal.c" , 642, __PRETTY_FUNCTION__); } while (0); | |||
643 | assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("key"), "../src/libsystemd-network/network-internal.c" , 643, __PRETTY_FUNCTION__); } while (0); | |||
644 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/libsystemd-network/network-internal.c" , 644, __PRETTY_FUNCTION__); } while (0); | |||
645 | ||||
646 | hex_buf = hexmem(data, size); | |||
647 | if (hex_buf == NULL((void*)0)) | |||
648 | return -ENOMEM12; | |||
649 | ||||
650 | fprintf(f, "%s=%s\n", key, hex_buf); | |||
651 | ||||
652 | return 0; | |||
653 | } |