File: | build-scan/../src/libsystemd-network/lldp-neighbor.c |
Warning: | line 656, column 24 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 "alloc-util.h" | |||
4 | #include "escape.h" | |||
5 | #include "ether-addr-util.h" | |||
6 | #include "hexdecoct.h" | |||
7 | #include "in-addr-util.h" | |||
8 | #include "lldp-internal.h" | |||
9 | #include "lldp-neighbor.h" | |||
10 | #include "unaligned.h" | |||
11 | ||||
12 | static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) { | |||
13 | const LLDPNeighborID *id = p; | |||
14 | ||||
15 | siphash24_compress(id->chassis_id, id->chassis_id_size, state); | |||
16 | siphash24_compress(&id->chassis_id_size, sizeof(id->chassis_id_size), state); | |||
17 | siphash24_compress(id->port_id, id->port_id_size, state); | |||
18 | siphash24_compress(&id->port_id_size, sizeof(id->port_id_size), state); | |||
19 | } | |||
20 | ||||
21 | static int lldp_neighbor_id_compare_func(const void *a, const void *b) { | |||
22 | const LLDPNeighborID *x = a, *y = b; | |||
23 | int r; | |||
24 | ||||
25 | r = memcmp(x->chassis_id, y->chassis_id, MIN(x->chassis_id_size, y->chassis_id_size)__extension__ ({ const typeof((x->chassis_id_size)) __unique_prefix_A4 = ((x->chassis_id_size)); const typeof((y->chassis_id_size )) __unique_prefix_B5 = ((y->chassis_id_size)); __unique_prefix_A4 < __unique_prefix_B5 ? __unique_prefix_A4 : __unique_prefix_B5 ; })); | |||
26 | if (r != 0) | |||
27 | return r; | |||
28 | ||||
29 | if (x->chassis_id_size < y->chassis_id_size) | |||
30 | return -1; | |||
31 | ||||
32 | if (x->chassis_id_size > y->chassis_id_size) | |||
33 | return 1; | |||
34 | ||||
35 | r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size)__extension__ ({ const typeof((x->port_id_size)) __unique_prefix_A6 = ((x->port_id_size)); const typeof((y->port_id_size)) __unique_prefix_B7 = ((y->port_id_size)); __unique_prefix_A6 < __unique_prefix_B7 ? __unique_prefix_A6 : __unique_prefix_B7 ; })); | |||
36 | if (r != 0) | |||
37 | return r; | |||
38 | ||||
39 | if (x->port_id_size < y->port_id_size) | |||
40 | return -1; | |||
41 | if (x->port_id_size > y->port_id_size) | |||
42 | return 1; | |||
43 | ||||
44 | return 0; | |||
45 | } | |||
46 | ||||
47 | const struct hash_ops lldp_neighbor_id_hash_ops = { | |||
48 | .hash = lldp_neighbor_id_hash_func, | |||
49 | .compare = lldp_neighbor_id_compare_func | |||
50 | }; | |||
51 | ||||
52 | int lldp_neighbor_prioq_compare_func(const void *a, const void *b) { | |||
53 | const sd_lldp_neighbor *x = a, *y = b; | |||
54 | ||||
55 | if (x->until < y->until) | |||
56 | return -1; | |||
57 | ||||
58 | if (x->until > y->until) | |||
59 | return 1; | |||
60 | ||||
61 | return 0; | |||
62 | } | |||
63 | ||||
64 | _public___attribute__ ((visibility("default"))) sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) { | |||
65 | if (!n) | |||
66 | return NULL((void*)0); | |||
67 | ||||
68 | assert(n->n_ref > 0 || n->lldp)do { if ((__builtin_expect(!!(!(n->n_ref > 0 || n->lldp )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n->n_ref > 0 || n->lldp" ), "../src/libsystemd-network/lldp-neighbor.c", 68, __PRETTY_FUNCTION__ ); } while (0); | |||
69 | n->n_ref++; | |||
70 | ||||
71 | return n; | |||
72 | } | |||
73 | ||||
74 | static void lldp_neighbor_free(sd_lldp_neighbor *n) { | |||
75 | assert(n)do { if ((__builtin_expect(!!(!(n)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 75, __PRETTY_FUNCTION__); } while (0); | |||
76 | ||||
77 | free(n->id.port_id); | |||
78 | free(n->id.chassis_id); | |||
79 | free(n->port_description); | |||
80 | free(n->system_name); | |||
81 | free(n->system_description); | |||
82 | free(n->chassis_id_as_string); | |||
83 | free(n->port_id_as_string); | |||
84 | free(n); | |||
85 | } | |||
86 | ||||
87 | _public___attribute__ ((visibility("default"))) sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n) { | |||
88 | ||||
89 | /* Drops one reference from the neighbor. Note that the object is not freed unless it is already unlinked from | |||
90 | * the sd_lldp object. */ | |||
91 | ||||
92 | if (!n) | |||
93 | return NULL((void*)0); | |||
94 | ||||
95 | assert(n->n_ref > 0)do { if ((__builtin_expect(!!(!(n->n_ref > 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n->n_ref > 0"), "../src/libsystemd-network/lldp-neighbor.c" , 95, __PRETTY_FUNCTION__); } while (0); | |||
96 | n->n_ref--; | |||
97 | ||||
98 | if (n->n_ref <= 0 && !n->lldp) | |||
99 | lldp_neighbor_free(n); | |||
100 | ||||
101 | return NULL((void*)0); | |||
102 | } | |||
103 | ||||
104 | sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n) { | |||
105 | ||||
106 | /* Removes the neighbor object from the LLDP object, and frees it if it also has no other reference. */ | |||
107 | ||||
108 | if (!n) | |||
109 | return NULL((void*)0); | |||
110 | ||||
111 | if (!n->lldp) | |||
112 | return NULL((void*)0); | |||
113 | ||||
114 | assert_se(hashmap_remove(n->lldp->neighbor_by_id, &n->id) == n)do { if ((__builtin_expect(!!(!(hashmap_remove(n->lldp-> neighbor_by_id, &n->id) == n)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("hashmap_remove(n->lldp->neighbor_by_id, &n->id) == n" ), "../src/libsystemd-network/lldp-neighbor.c", 114, __PRETTY_FUNCTION__ ); } while (0); | |||
115 | assert_se(prioq_remove(n->lldp->neighbor_by_expiry, n, &n->prioq_idx) >= 0)do { if ((__builtin_expect(!!(!(prioq_remove(n->lldp->neighbor_by_expiry , n, &n->prioq_idx) >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("prioq_remove(n->lldp->neighbor_by_expiry, n, &n->prioq_idx) >= 0" ), "../src/libsystemd-network/lldp-neighbor.c", 115, __PRETTY_FUNCTION__ ); } while (0); | |||
116 | ||||
117 | n->lldp = NULL((void*)0); | |||
118 | ||||
119 | if (n->n_ref <= 0) | |||
120 | lldp_neighbor_free(n); | |||
121 | ||||
122 | return NULL((void*)0); | |||
123 | } | |||
124 | ||||
125 | sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) { | |||
126 | sd_lldp_neighbor *n; | |||
127 | ||||
128 | n = malloc0(ALIGN(sizeof(sd_lldp_neighbor)) + raw_size)(calloc(1, ((((sizeof(sd_lldp_neighbor)) + 7) & ~7) + raw_size ))); | |||
129 | if (!n) | |||
130 | return NULL((void*)0); | |||
131 | ||||
132 | n->raw_size = raw_size; | |||
133 | n->n_ref = 1; | |||
134 | ||||
135 | return n; | |||
136 | } | |||
137 | ||||
138 | static int parse_string(char **s, const void *q, size_t n) { | |||
139 | const char *p = q; | |||
140 | char *k; | |||
141 | ||||
142 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd-network/lldp-neighbor.c" , 142, __PRETTY_FUNCTION__); } while (0); | |||
143 | assert(p || n == 0)do { if ((__builtin_expect(!!(!(p || n == 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p || n == 0"), "../src/libsystemd-network/lldp-neighbor.c" , 143, __PRETTY_FUNCTION__); } while (0); | |||
144 | ||||
145 | if (*s) { | |||
146 | log_lldp("Found duplicate string, ignoring field.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 146, __func__ , "LLDP: " "Found duplicate string, ignoring field."); | |||
147 | return 0; | |||
148 | } | |||
149 | ||||
150 | /* Strip trailing NULs, just to be nice */ | |||
151 | while (n > 0 && p[n-1] == 0) | |||
152 | n--; | |||
153 | ||||
154 | if (n <= 0) /* Ignore empty strings */ | |||
155 | return 0; | |||
156 | ||||
157 | /* Look for inner NULs */ | |||
158 | if (memchr(p, 0, n)) { | |||
159 | log_lldp("Found inner NUL in string, ignoring field.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 159, __func__ , "LLDP: " "Found inner NUL in string, ignoring field."); | |||
160 | return 0; | |||
161 | } | |||
162 | ||||
163 | /* Let's escape weird chars, for security reasons */ | |||
164 | k = cescape_length(p, n); | |||
165 | if (!k) | |||
166 | return -ENOMEM12; | |||
167 | ||||
168 | free(*s); | |||
169 | *s = k; | |||
170 | ||||
171 | return 1; | |||
172 | } | |||
173 | ||||
174 | int lldp_neighbor_parse(sd_lldp_neighbor *n) { | |||
175 | struct ether_header h; | |||
176 | const uint8_t *p; | |||
177 | size_t left; | |||
178 | int r; | |||
179 | ||||
180 | assert(n)do { if ((__builtin_expect(!!(!(n)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 180, __PRETTY_FUNCTION__); } while (0); | |||
181 | ||||
182 | if (n->raw_size < sizeof(struct ether_header)) { | |||
183 | log_lldp("Received truncated packet, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 183, __func__ , "LLDP: " "Received truncated packet, ignoring."); | |||
184 | return -EBADMSG74; | |||
185 | } | |||
186 | ||||
187 | memcpy(&h, LLDP_NEIGHBOR_RAW(n), sizeof(h)); | |||
188 | ||||
189 | if (h.ether_type != htobe16(ETHERTYPE_LLDP)__bswap_16 (0x88cc)) { | |||
190 | log_lldp("Received packet with wrong type, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 190, __func__ , "LLDP: " "Received packet with wrong type, ignoring."); | |||
191 | return -EBADMSG74; | |||
192 | } | |||
193 | ||||
194 | if (h.ether_dhost[0] != 0x01 || | |||
195 | h.ether_dhost[1] != 0x80 || | |||
196 | h.ether_dhost[2] != 0xc2 || | |||
197 | h.ether_dhost[3] != 0x00 || | |||
198 | h.ether_dhost[4] != 0x00 || | |||
199 | !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){0x00, 0x03, 0x0e})/sizeof(int)]; switch( h.ether_dhost[5]) { case 0x00: case 0x03: case 0x0e: _found = 1; break; default: break; } _found; })) { | |||
200 | log_lldp("Received packet with wrong destination address, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 200, __func__ , "LLDP: " "Received packet with wrong destination address, ignoring." ); | |||
201 | return -EBADMSG74; | |||
202 | } | |||
203 | ||||
204 | memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr)); | |||
205 | memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr)); | |||
206 | ||||
207 | p = (const uint8_t*) LLDP_NEIGHBOR_RAW(n) + sizeof(struct ether_header); | |||
208 | left = n->raw_size - sizeof(struct ether_header); | |||
209 | ||||
210 | for (;;) { | |||
211 | uint8_t type; | |||
212 | uint16_t length; | |||
213 | ||||
214 | if (left < 2) { | |||
215 | log_lldp("TLV lacks header, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 215, __func__ , "LLDP: " "TLV lacks header, ignoring."); | |||
216 | return -EBADMSG74; | |||
217 | } | |||
218 | ||||
219 | type = p[0] >> 1; | |||
220 | length = p[1] + (((uint16_t) (p[0] & 1)) << 8); | |||
221 | p += 2, left -= 2; | |||
222 | ||||
223 | if (left < length) { | |||
224 | log_lldp("TLV truncated, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 224, __func__ , "LLDP: " "TLV truncated, ignoring datagram."); | |||
225 | return -EBADMSG74; | |||
226 | } | |||
227 | ||||
228 | switch (type) { | |||
229 | ||||
230 | case SD_LLDP_TYPE_END: | |||
231 | if (length != 0) { | |||
232 | log_lldp("End marker TLV not zero-sized, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 232, __func__ , "LLDP: " "End marker TLV not zero-sized, ignoring datagram." ); | |||
233 | return -EBADMSG74; | |||
234 | } | |||
235 | ||||
236 | /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0 | |||
237 | * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */ | |||
238 | ||||
239 | goto end_marker; | |||
240 | ||||
241 | case SD_LLDP_TYPE_CHASSIS_ID: | |||
242 | if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */ | |||
243 | log_lldp("Chassis ID field size out of range, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 243, __func__ , "LLDP: " "Chassis ID field size out of range, ignoring datagram." ); | |||
244 | return -EBADMSG74; | |||
245 | } | |||
246 | if (n->id.chassis_id) { | |||
247 | log_lldp("Duplicate chassis ID field, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 247, __func__ , "LLDP: " "Duplicate chassis ID field, ignoring datagram."); | |||
248 | return -EBADMSG74; | |||
249 | } | |||
250 | ||||
251 | n->id.chassis_id = memdup(p, length); | |||
252 | if (!n->id.chassis_id) | |||
253 | return -ENOMEM12; | |||
254 | ||||
255 | n->id.chassis_id_size = length; | |||
256 | break; | |||
257 | ||||
258 | case SD_LLDP_TYPE_PORT_ID: | |||
259 | if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */ | |||
260 | log_lldp("Port ID field size out of range, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 260, __func__ , "LLDP: " "Port ID field size out of range, ignoring datagram." ); | |||
261 | return -EBADMSG74; | |||
262 | } | |||
263 | if (n->id.port_id) { | |||
264 | log_lldp("Duplicate port ID field, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 264, __func__ , "LLDP: " "Duplicate port ID field, ignoring datagram."); | |||
265 | return -EBADMSG74; | |||
266 | } | |||
267 | ||||
268 | n->id.port_id = memdup(p, length); | |||
269 | if (!n->id.port_id) | |||
270 | return -ENOMEM12; | |||
271 | ||||
272 | n->id.port_id_size = length; | |||
273 | break; | |||
274 | ||||
275 | case SD_LLDP_TYPE_TTL: | |||
276 | if (length != 2) { | |||
277 | log_lldp("TTL field has wrong size, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 277, __func__ , "LLDP: " "TTL field has wrong size, ignoring datagram."); | |||
278 | return -EBADMSG74; | |||
279 | } | |||
280 | ||||
281 | if (n->has_ttl) { | |||
282 | log_lldp("Duplicate TTL field, ignoring datagram.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 282, __func__ , "LLDP: " "Duplicate TTL field, ignoring datagram."); | |||
283 | return -EBADMSG74; | |||
284 | } | |||
285 | ||||
286 | n->ttl = unaligned_read_be16(p); | |||
287 | n->has_ttl = true1; | |||
288 | break; | |||
289 | ||||
290 | case SD_LLDP_TYPE_PORT_DESCRIPTION: | |||
291 | r = parse_string(&n->port_description, p, length); | |||
292 | if (r < 0) | |||
293 | return r; | |||
294 | break; | |||
295 | ||||
296 | case SD_LLDP_TYPE_SYSTEM_NAME: | |||
297 | r = parse_string(&n->system_name, p, length); | |||
298 | if (r < 0) | |||
299 | return r; | |||
300 | break; | |||
301 | ||||
302 | case SD_LLDP_TYPE_SYSTEM_DESCRIPTION: | |||
303 | r = parse_string(&n->system_description, p, length); | |||
304 | if (r < 0) | |||
305 | return r; | |||
306 | break; | |||
307 | ||||
308 | case SD_LLDP_TYPE_SYSTEM_CAPABILITIES: | |||
309 | if (length != 4) | |||
310 | log_lldp("System capabilities field has wrong size, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 310, __func__ , "LLDP: " "System capabilities field has wrong size, ignoring." ); | |||
311 | else { | |||
312 | n->system_capabilities = unaligned_read_be16(p); | |||
313 | n->enabled_capabilities = unaligned_read_be16(p + 2); | |||
314 | n->has_capabilities = true1; | |||
315 | } | |||
316 | ||||
317 | break; | |||
318 | ||||
319 | case SD_LLDP_TYPE_PRIVATE: | |||
320 | if (length < 4) | |||
321 | log_lldp("Found private TLV that is too short, ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 321, __func__ , "LLDP: " "Found private TLV that is too short, ignoring."); | |||
322 | ||||
323 | break; | |||
324 | } | |||
325 | ||||
326 | p += length, left -= length; | |||
327 | } | |||
328 | ||||
329 | end_marker: | |||
330 | if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) { | |||
331 | log_lldp("One or more mandatory TLV missing in datagram. Ignoring.")log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/libsystemd-network/lldp-neighbor.c", 331, __func__ , "LLDP: " "One or more mandatory TLV missing in datagram. Ignoring." ); | |||
332 | return -EBADMSG74; | |||
333 | ||||
334 | } | |||
335 | ||||
336 | n->rindex = sizeof(struct ether_header); | |||
337 | ||||
338 | return 0; | |||
339 | } | |||
340 | ||||
341 | void lldp_neighbor_start_ttl(sd_lldp_neighbor *n) { | |||
342 | assert(n)do { if ((__builtin_expect(!!(!(n)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 342, __PRETTY_FUNCTION__); } while (0); | |||
343 | ||||
344 | if (n->ttl > 0) { | |||
345 | usec_t base; | |||
346 | ||||
347 | /* Use the packet's timestamp if there is one known */ | |||
348 | base = triple_timestamp_by_clock(&n->timestamp, clock_boottime_or_monotonic()); | |||
349 | if (base <= 0 || base == USEC_INFINITY((usec_t) -1)) | |||
350 | base = now(clock_boottime_or_monotonic()); /* Otherwise, take the current time */ | |||
351 | ||||
352 | n->until = usec_add(base, n->ttl * USEC_PER_SEC((usec_t) 1000000ULL)); | |||
353 | } else | |||
354 | n->until = 0; | |||
355 | ||||
356 | if (n->lldp) | |||
357 | prioq_reshuffle(n->lldp->neighbor_by_expiry, n, &n->prioq_idx); | |||
358 | } | |||
359 | ||||
360 | bool_Bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b) { | |||
361 | if (a == b) | |||
362 | return true1; | |||
363 | ||||
364 | if (!a || !b) | |||
365 | return false0; | |||
366 | ||||
367 | if (a->raw_size != b->raw_size) | |||
368 | return false0; | |||
369 | ||||
370 | return memcmp(LLDP_NEIGHBOR_RAW(a), LLDP_NEIGHBOR_RAW(b), a->raw_size) == 0; | |||
371 | } | |||
372 | ||||
373 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address) { | |||
374 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 374, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
375 | assert_return(address, -EINVAL)do { if (!(((__builtin_expect(!!(address),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("address"), "../src/libsystemd-network/lldp-neighbor.c" , 375, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
376 | ||||
377 | *address = n->source_address; | |||
378 | return 0; | |||
379 | } | |||
380 | ||||
381 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address) { | |||
382 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 382, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
383 | assert_return(address, -EINVAL)do { if (!(((__builtin_expect(!!(address),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("address"), "../src/libsystemd-network/lldp-neighbor.c" , 383, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
384 | ||||
385 | *address = n->destination_address; | |||
386 | return 0; | |||
387 | } | |||
388 | ||||
389 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) { | |||
390 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 390, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
391 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 391, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
392 | assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/lldp-neighbor.c" , 392, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
393 | ||||
394 | *ret = LLDP_NEIGHBOR_RAW(n); | |||
395 | *size = n->raw_size; | |||
396 | ||||
397 | return 0; | |||
398 | } | |||
399 | ||||
400 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) { | |||
401 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 401, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
402 | assert_return(type, -EINVAL)do { if (!(((__builtin_expect(!!(type),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("type"), "../src/libsystemd-network/lldp-neighbor.c" , 402, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
403 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 403, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
404 | assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/lldp-neighbor.c" , 404, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
405 | ||||
406 | assert(n->id.chassis_id_size > 0)do { if ((__builtin_expect(!!(!(n->id.chassis_id_size > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n->id.chassis_id_size > 0" ), "../src/libsystemd-network/lldp-neighbor.c", 406, __PRETTY_FUNCTION__ ); } while (0); | |||
407 | ||||
408 | *type = *(uint8_t*) n->id.chassis_id; | |||
409 | *ret = (uint8_t*) n->id.chassis_id + 1; | |||
410 | *size = n->id.chassis_id_size - 1; | |||
411 | ||||
412 | return 0; | |||
413 | } | |||
414 | ||||
415 | static int format_mac_address(const void *data, size_t sz, char **ret) { | |||
416 | struct ether_addr a; | |||
417 | char *k; | |||
418 | ||||
419 | assert(data || sz <= 0)do { if ((__builtin_expect(!!(!(data || sz <= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data || sz <= 0"), "../src/libsystemd-network/lldp-neighbor.c" , 419, __PRETTY_FUNCTION__); } while (0); | |||
420 | ||||
421 | if (sz != 7) | |||
422 | return 0; | |||
423 | ||||
424 | memcpy(&a, (uint8_t*) data + 1, sizeof(a)); | |||
425 | ||||
426 | k = new(char, ETHER_ADDR_TO_STRING_MAX)((char*) malloc_multiply(sizeof(char), ((3*6)))); | |||
427 | if (!k) | |||
428 | return -ENOMEM12; | |||
429 | ||||
430 | *ret = ether_addr_to_string(&a, k); | |||
431 | return 1; | |||
432 | } | |||
433 | ||||
434 | static int format_network_address(const void *data, size_t sz, char **ret) { | |||
435 | union in_addr_union a; | |||
436 | int family, r; | |||
437 | ||||
438 | if (sz == 6 && ((uint8_t*) data)[1] == 1) { | |||
439 | memcpy(&a.in, (uint8_t*) data + 2, sizeof(a.in)); | |||
440 | family = AF_INET2; | |||
441 | } else if (sz == 18 && ((uint8_t*) data)[1] == 2) { | |||
442 | memcpy(&a.in6, (uint8_t*) data + 2, sizeof(a.in6)); | |||
443 | family = AF_INET610; | |||
444 | } else | |||
445 | return 0; | |||
446 | ||||
447 | r = in_addr_to_string(family, &a, ret); | |||
448 | if (r < 0) | |||
449 | return r; | |||
450 | return 1; | |||
451 | } | |||
452 | ||||
453 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, const char **ret) { | |||
454 | char *k; | |||
455 | int r; | |||
456 | ||||
457 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 457, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
458 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 458, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
459 | ||||
460 | if (n->chassis_id_as_string) { | |||
461 | *ret = n->chassis_id_as_string; | |||
462 | return 0; | |||
463 | } | |||
464 | ||||
465 | assert(n->id.chassis_id_size > 0)do { if ((__builtin_expect(!!(!(n->id.chassis_id_size > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n->id.chassis_id_size > 0" ), "../src/libsystemd-network/lldp-neighbor.c", 465, __PRETTY_FUNCTION__ ); } while (0); | |||
466 | ||||
467 | switch (*(uint8_t*) n->id.chassis_id) { | |||
468 | ||||
469 | case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT: | |||
470 | case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS: | |||
471 | case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT: | |||
472 | case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME: | |||
473 | case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED: | |||
474 | k = cescape_length((char*) n->id.chassis_id + 1, n->id.chassis_id_size - 1); | |||
475 | if (!k) | |||
476 | return -ENOMEM12; | |||
477 | ||||
478 | goto done; | |||
479 | ||||
480 | case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: | |||
481 | r = format_mac_address(n->id.chassis_id, n->id.chassis_id_size, &k); | |||
482 | if (r < 0) | |||
483 | return r; | |||
484 | if (r > 0) | |||
485 | goto done; | |||
486 | ||||
487 | break; | |||
488 | ||||
489 | case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS: | |||
490 | r = format_network_address(n->id.chassis_id, n->id.chassis_id_size, &k); | |||
491 | if (r < 0) | |||
492 | return r; | |||
493 | if (r > 0) | |||
494 | goto done; | |||
495 | ||||
496 | break; | |||
497 | } | |||
498 | ||||
499 | /* Generic fallback */ | |||
500 | k = hexmem(n->id.chassis_id, n->id.chassis_id_size); | |||
501 | if (!k) | |||
502 | return -ENOMEM12; | |||
503 | ||||
504 | done: | |||
505 | *ret = n->chassis_id_as_string = k; | |||
506 | return 0; | |||
507 | } | |||
508 | ||||
509 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_port_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) { | |||
510 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 510, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
511 | assert_return(type, -EINVAL)do { if (!(((__builtin_expect(!!(type),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("type"), "../src/libsystemd-network/lldp-neighbor.c" , 511, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
512 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 512, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
513 | assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/lldp-neighbor.c" , 513, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
514 | ||||
515 | assert(n->id.port_id_size > 0)do { if ((__builtin_expect(!!(!(n->id.port_id_size > 0) ),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n->id.port_id_size > 0" ), "../src/libsystemd-network/lldp-neighbor.c", 515, __PRETTY_FUNCTION__ ); } while (0); | |||
516 | ||||
517 | *type = *(uint8_t*) n->id.port_id; | |||
518 | *ret = (uint8_t*) n->id.port_id + 1; | |||
519 | *size = n->id.port_id_size - 1; | |||
520 | ||||
521 | return 0; | |||
522 | } | |||
523 | ||||
524 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const char **ret) { | |||
525 | char *k; | |||
526 | int r; | |||
527 | ||||
528 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 528, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
529 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 529, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
530 | ||||
531 | if (n->port_id_as_string) { | |||
532 | *ret = n->port_id_as_string; | |||
533 | return 0; | |||
534 | } | |||
535 | ||||
536 | assert(n->id.port_id_size > 0)do { if ((__builtin_expect(!!(!(n->id.port_id_size > 0) ),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n->id.port_id_size > 0" ), "../src/libsystemd-network/lldp-neighbor.c", 536, __PRETTY_FUNCTION__ ); } while (0); | |||
537 | ||||
538 | switch (*(uint8_t*) n->id.port_id) { | |||
539 | ||||
540 | case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: | |||
541 | case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT: | |||
542 | case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME: | |||
543 | case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: | |||
544 | k = cescape_length((char*) n->id.port_id + 1, n->id.port_id_size - 1); | |||
545 | if (!k) | |||
546 | return -ENOMEM12; | |||
547 | ||||
548 | goto done; | |||
549 | ||||
550 | case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS: | |||
551 | r = format_mac_address(n->id.port_id, n->id.port_id_size, &k); | |||
552 | if (r < 0) | |||
553 | return r; | |||
554 | if (r > 0) | |||
555 | goto done; | |||
556 | ||||
557 | break; | |||
558 | ||||
559 | case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS: | |||
560 | r = format_network_address(n->id.port_id, n->id.port_id_size, &k); | |||
561 | if (r < 0) | |||
562 | return r; | |||
563 | if (r > 0) | |||
564 | goto done; | |||
565 | ||||
566 | break; | |||
567 | } | |||
568 | ||||
569 | /* Generic fallback */ | |||
570 | k = hexmem(n->id.port_id, n->id.port_id_size); | |||
571 | if (!k) | |||
572 | return -ENOMEM12; | |||
573 | ||||
574 | done: | |||
575 | *ret = n->port_id_as_string = k; | |||
576 | return 0; | |||
577 | } | |||
578 | ||||
579 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec) { | |||
580 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 580, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
581 | 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/lldp-neighbor.c" , 581, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
582 | ||||
583 | *ret_sec = n->ttl; | |||
584 | return 0; | |||
585 | } | |||
586 | ||||
587 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret) { | |||
588 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 588, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
589 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 589, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
590 | ||||
591 | if (!n->system_name) | |||
592 | return -ENODATA61; | |||
593 | ||||
594 | *ret = n->system_name; | |||
595 | return 0; | |||
596 | } | |||
597 | ||||
598 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret) { | |||
599 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 599, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
600 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 600, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
601 | ||||
602 | if (!n->system_description) | |||
603 | return -ENODATA61; | |||
604 | ||||
605 | *ret = n->system_description; | |||
606 | return 0; | |||
607 | } | |||
608 | ||||
609 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret) { | |||
610 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 610, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
611 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 611, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
612 | ||||
613 | if (!n->port_description) | |||
614 | return -ENODATA61; | |||
615 | ||||
616 | *ret = n->port_description; | |||
617 | return 0; | |||
618 | } | |||
619 | ||||
620 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret) { | |||
621 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 621, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
622 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 622, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
623 | ||||
624 | if (!n->has_capabilities) | |||
625 | return -ENODATA61; | |||
626 | ||||
627 | *ret = n->system_capabilities; | |||
628 | return 0; | |||
629 | } | |||
630 | ||||
631 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret) { | |||
632 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 632, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
633 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 633, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
634 | ||||
635 | if (!n->has_capabilities) | |||
636 | return -ENODATA61; | |||
637 | ||||
638 | *ret = n->enabled_capabilities; | |||
639 | return 0; | |||
640 | } | |||
641 | ||||
642 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) { | |||
643 | _cleanup_(sd_lldp_neighbor_unrefp)__attribute__((cleanup(sd_lldp_neighbor_unrefp))) sd_lldp_neighbor *n = NULL((void*)0); | |||
644 | int r; | |||
645 | ||||
646 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 646, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
| ||||
647 | 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/lldp-neighbor.c" , 647, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
648 | ||||
649 | n = lldp_neighbor_new(raw_size); | |||
650 | if (!n
| |||
651 | return -ENOMEM12; | |||
652 | ||||
653 | memcpy(LLDP_NEIGHBOR_RAW(n), raw, raw_size); | |||
654 | r = lldp_neighbor_parse(n); | |||
655 | if (r
| |||
656 | return r; | |||
| ||||
657 | ||||
658 | *ret = TAKE_PTR(n)({ typeof(n) _ptr_ = (n); (n) = ((void*)0); _ptr_; }); | |||
659 | ||||
660 | return r; | |||
661 | } | |||
662 | ||||
663 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) { | |||
664 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 664, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
665 | ||||
666 | assert(n->raw_size >= sizeof(struct ether_header))do { if ((__builtin_expect(!!(!(n->raw_size >= sizeof(struct ether_header))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("n->raw_size >= sizeof(struct ether_header)"), "../src/libsystemd-network/lldp-neighbor.c" , 666, __PRETTY_FUNCTION__); } while (0); | |||
667 | n->rindex = sizeof(struct ether_header); | |||
668 | ||||
669 | return n->rindex < n->raw_size; | |||
670 | } | |||
671 | ||||
672 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n) { | |||
673 | size_t length; | |||
674 | ||||
675 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 675, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
676 | ||||
677 | if (n->rindex == n->raw_size) /* EOF */ | |||
678 | return -ESPIPE29; | |||
679 | ||||
680 | if (n->rindex + 2 > n->raw_size) /* Truncated message */ | |||
681 | return -EBADMSG74; | |||
682 | ||||
683 | length = LLDP_NEIGHBOR_TLV_LENGTH(n); | |||
684 | if (n->rindex + 2 + length > n->raw_size) | |||
685 | return -EBADMSG74; | |||
686 | ||||
687 | n->rindex += 2 + length; | |||
688 | return n->rindex < n->raw_size; | |||
689 | } | |||
690 | ||||
691 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_get_type(sd_lldp_neighbor *n, uint8_t *type) { | |||
692 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 692, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
693 | assert_return(type, -EINVAL)do { if (!(((__builtin_expect(!!(type),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("type"), "../src/libsystemd-network/lldp-neighbor.c" , 693, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
694 | ||||
695 | if (n->rindex == n->raw_size) /* EOF */ | |||
696 | return -ESPIPE29; | |||
697 | ||||
698 | if (n->rindex + 2 > n->raw_size) | |||
699 | return -EBADMSG74; | |||
700 | ||||
701 | *type = LLDP_NEIGHBOR_TLV_TYPE(n); | |||
702 | return 0; | |||
703 | } | |||
704 | ||||
705 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_is_type(sd_lldp_neighbor *n, uint8_t type) { | |||
706 | uint8_t k; | |||
707 | int r; | |||
708 | ||||
709 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 709, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
710 | ||||
711 | r = sd_lldp_neighbor_tlv_get_type(n, &k); | |||
712 | if (r < 0) | |||
713 | return r; | |||
714 | ||||
715 | return type == k; | |||
716 | } | |||
717 | ||||
718 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], uint8_t *subtype) { | |||
719 | const uint8_t *d; | |||
720 | size_t length; | |||
721 | int r; | |||
722 | ||||
723 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 723, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
724 | assert_return(oui, -EINVAL)do { if (!(((__builtin_expect(!!(oui),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("oui"), "../src/libsystemd-network/lldp-neighbor.c" , 724, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
725 | assert_return(subtype, -EINVAL)do { if (!(((__builtin_expect(!!(subtype),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("subtype"), "../src/libsystemd-network/lldp-neighbor.c" , 725, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
726 | ||||
727 | r = sd_lldp_neighbor_tlv_is_type(n, SD_LLDP_TYPE_PRIVATE); | |||
728 | if (r < 0) | |||
729 | return r; | |||
730 | if (r == 0) | |||
731 | return -ENXIO6; | |||
732 | ||||
733 | length = LLDP_NEIGHBOR_TLV_LENGTH(n); | |||
734 | if (length < 4) | |||
735 | return -EBADMSG74; | |||
736 | ||||
737 | if (n->rindex + 2 + length > n->raw_size) | |||
738 | return -EBADMSG74; | |||
739 | ||||
740 | d = LLDP_NEIGHBOR_TLV_DATA(n); | |||
741 | memcpy(oui, d, 3); | |||
742 | *subtype = d[3]; | |||
743 | ||||
744 | return 0; | |||
745 | } | |||
746 | ||||
747 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_is_oui(sd_lldp_neighbor *n, const uint8_t oui[3], uint8_t subtype) { | |||
748 | uint8_t k[3], st; | |||
749 | int r; | |||
750 | ||||
751 | r = sd_lldp_neighbor_tlv_get_oui(n, k, &st); | |||
752 | if (r == -ENXIO6) | |||
753 | return 0; | |||
754 | if (r < 0) | |||
755 | return r; | |||
756 | ||||
757 | return memcmp(k, oui, 3) == 0 && st == subtype; | |||
758 | } | |||
759 | ||||
760 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_tlv_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) { | |||
761 | size_t length; | |||
762 | ||||
763 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 763, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
764 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 764, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
765 | assert_return(size, -EINVAL)do { if (!(((__builtin_expect(!!(size),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("size"), "../src/libsystemd-network/lldp-neighbor.c" , 765, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
766 | ||||
767 | /* Note that this returns the full TLV, including the TLV header */ | |||
768 | ||||
769 | if (n->rindex + 2 > n->raw_size) | |||
770 | return -EBADMSG74; | |||
771 | ||||
772 | length = LLDP_NEIGHBOR_TLV_LENGTH(n); | |||
773 | if (n->rindex + 2 + length > n->raw_size) | |||
774 | return -EBADMSG74; | |||
775 | ||||
776 | *ret = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex; | |||
777 | *size = length + 2; | |||
778 | ||||
779 | return 0; | |||
780 | } | |||
781 | ||||
782 | _public___attribute__ ((visibility("default"))) int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret) { | |||
783 | assert_return(n, -EINVAL)do { if (!(((__builtin_expect(!!(n),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("n"), "../src/libsystemd-network/lldp-neighbor.c" , 783, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
784 | 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/lldp-neighbor.c" , 784, __PRETTY_FUNCTION__), 0))) return (-95); } while (0); | |||
785 | 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/lldp-neighbor.c" , 785, __PRETTY_FUNCTION__), 0))) return (-95); } while (0); | |||
786 | assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd-network/lldp-neighbor.c" , 786, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
787 | ||||
788 | if (!triple_timestamp_is_set(&n->timestamp)) | |||
789 | return -ENODATA61; | |||
790 | ||||
791 | *ret = triple_timestamp_by_clock(&n->timestamp, clock); | |||
792 | return 0; | |||
793 | } |