1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include <inttypes.h>
5 #include <stdbool.h>
6 #include <sys/types.h>
7 
8 #include "sd-lldp-rx.h"
9 
10 #include "hash-funcs.h"
11 #include "lldp-rx-internal.h"
12 #include "time-util.h"
13 
14 typedef struct LLDPNeighborID {
15         /* The spec calls this an "MSAP identifier" */
16         void *chassis_id;
17         size_t chassis_id_size;
18 
19         void *port_id;
20         size_t port_id_size;
21 } LLDPNeighborID;
22 
23 struct sd_lldp_neighbor {
24         /* Neighbor objects stay around as long as they are linked into an "sd_lldp_rx" object or n_ref > 0. */
25         sd_lldp_rx *lldp_rx;
26         unsigned n_ref;
27 
28         triple_timestamp timestamp;
29 
30         usec_t until;
31         unsigned prioq_idx;
32 
33         struct ether_addr source_address;
34         struct ether_addr destination_address;
35 
36         LLDPNeighborID id;
37 
38         /* The raw packet size. The data is appended to the object, accessible via LLDP_NEIGHBOR_RAW() */
39         size_t raw_size;
40 
41         /* The current read index for the iterative TLV interface */
42         size_t rindex;
43 
44         /* And a couple of fields parsed out. */
45         bool has_ttl:1;
46         bool has_capabilities:1;
47         bool has_port_vlan_id:1;
48 
49         uint16_t ttl;
50 
51         uint16_t system_capabilities;
52         uint16_t enabled_capabilities;
53 
54         char *port_description;
55         char *system_name;
56         char *system_description;
57         char *mud_url;
58 
59         uint16_t port_vlan_id;
60 
61         char *chassis_id_as_string;
62         char *port_id_as_string;
63 };
64 
LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor * n)65 static inline void *LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor *n) {
66         return (uint8_t*) n + ALIGN(sizeof(sd_lldp_neighbor));
67 }
68 
LLDP_NEIGHBOR_TLV_TYPE(const sd_lldp_neighbor * n)69 static inline uint8_t LLDP_NEIGHBOR_TLV_TYPE(const sd_lldp_neighbor *n) {
70         return ((uint8_t*) LLDP_NEIGHBOR_RAW(n))[n->rindex] >> 1;
71 }
72 
LLDP_NEIGHBOR_TLV_LENGTH(const sd_lldp_neighbor * n)73 static inline size_t LLDP_NEIGHBOR_TLV_LENGTH(const sd_lldp_neighbor *n) {
74         uint8_t *p;
75 
76         p = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex;
77         return p[1] + (((size_t) (p[0] & 1)) << 8);
78 }
79 
LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor * n)80 static inline void* LLDP_NEIGHBOR_TLV_DATA(const sd_lldp_neighbor *n) {
81         return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2;
82 }
83 
84 extern const struct hash_ops lldp_neighbor_hash_ops;
85 int lldp_neighbor_id_compare_func(const LLDPNeighborID *x, const LLDPNeighborID *y);
86 int lldp_neighbor_prioq_compare_func(const void *a, const void *b);
87 
88 sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n);
89 sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size);
90 int lldp_neighbor_parse(sd_lldp_neighbor *n);
91 void lldp_neighbor_start_ttl(sd_lldp_neighbor *n);
92 bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b);
93