]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/lldpd-structs.h
OpenBSD support.
[thirdparty/lldpd.git] / src / lldpd-structs.h
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #ifndef _LLDPD_STRUCTS_H
19 #define _LLDPD_STRUCTS_H
20
21 #if HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <sys/types.h>
26 #include <sys/socket.h>
27
28 /* This is not very convenient, but we need net/if.h for IFNAMSIZ and others but
29 * we may also need linux/if.h in some modules. And they conflict each others.
30 */
31 #ifdef HOST_OS_LINUX
32 # include <linux/if.h>
33 #else
34 # include <net/if.h>
35 #endif
36
37 #include <netinet/if_ether.h>
38 #include <netinet/in.h>
39 #include <sys/queue.h>
40
41 #include "compat/compat.h"
42 #include "marshal.h"
43 #include "lldp-const.h"
44
45 #ifdef ENABLE_DOT1
46 struct lldpd_ppvid {
47 TAILQ_ENTRY(lldpd_ppvid) p_entries;
48 u_int8_t p_cap_status;
49 u_int16_t p_ppvid;
50 };
51 MARSHAL_BEGIN(lldpd_ppvid)
52 MARSHAL_TQE(lldpd_ppvid, p_entries)
53 MARSHAL_END;
54
55 struct lldpd_vlan {
56 TAILQ_ENTRY(lldpd_vlan) v_entries;
57 char *v_name;
58 u_int16_t v_vid;
59 };
60 MARSHAL_BEGIN(lldpd_vlan)
61 MARSHAL_TQE(lldpd_vlan, v_entries)
62 MARSHAL_STR(lldpd_vlan, v_name)
63 MARSHAL_END;
64
65 struct lldpd_pi {
66 TAILQ_ENTRY(lldpd_pi) p_entries;
67 char *p_pi;
68 int p_pi_len;
69 };
70 MARSHAL_BEGIN(lldpd_pi)
71 MARSHAL_TQE(lldpd_pi, p_entries)
72 MARSHAL_FSTR(lldpd_pi, p_pi, p_pi_len)
73 MARSHAL_END;
74 #endif
75
76 #ifdef ENABLE_LLDPMED
77 struct lldpd_med_policy {
78 u_int8_t index; /* Not used. */
79 u_int8_t type;
80 u_int8_t unknown;
81 u_int8_t tagged;
82 u_int16_t vid;
83 u_int8_t priority;
84 u_int8_t dscp;
85 };
86 MARSHAL(lldpd_med_policy);
87
88 struct lldpd_med_loc {
89 u_int8_t index; /* Not used. */
90 u_int8_t format;
91 char *data;
92 int data_len;
93 };
94 MARSHAL_BEGIN(lldpd_med_loc)
95 MARSHAL_FSTR(lldpd_med_loc, data, data_len)
96 MARSHAL_END;
97
98 struct lldpd_med_power {
99 u_int8_t devicetype; /* PD or PSE */
100 u_int8_t source;
101 u_int8_t priority;
102 u_int16_t val;
103 };
104 MARSHAL(lldpd_med_power);
105 #endif
106
107 #ifdef ENABLE_DOT3
108 struct lldpd_dot3_macphy {
109 u_int8_t autoneg_support;
110 u_int8_t autoneg_enabled;
111 u_int16_t autoneg_advertised;
112 u_int16_t mau_type;
113 };
114
115 struct lldpd_dot3_power {
116 u_int8_t devicetype;
117 u_int8_t supported;
118 u_int8_t enabled;
119 u_int8_t paircontrol;
120 u_int8_t pairs;
121 u_int8_t class;
122 u_int8_t powertype; /* If set to LLDP_DOT3_POWER_8023AT_OFF,
123 following fields have no meaning */
124 u_int8_t source;
125 u_int8_t priority;
126 u_int16_t requested;
127 u_int16_t allocated;
128 };
129 MARSHAL(lldpd_dot3_power);
130 #endif
131
132 enum {
133 LLDPD_AF_UNSPEC = 0,
134 LLDPD_AF_IPV4,
135 LLDPD_AF_IPV6,
136 LLDPD_AF_LAST
137 };
138
139 inline static int
140 lldpd_af(int af)
141 {
142 switch (af) {
143 case LLDPD_AF_IPV4: return AF_INET;
144 case LLDPD_AF_IPV6: return AF_INET6;
145 case LLDPD_AF_LAST: return AF_MAX;
146 default: return AF_UNSPEC;
147 }
148 }
149
150 #define LLDPD_MGMT_MAXADDRSIZE 16 /* sizeof(struct in6_addr) */
151 struct lldpd_mgmt {
152 TAILQ_ENTRY(lldpd_mgmt) m_entries;
153 int m_family;
154 union {
155 struct in_addr inet;
156 struct in6_addr inet6;
157 u_int8_t octets[LLDPD_MGMT_MAXADDRSIZE];
158 } m_addr;
159 size_t m_addrsize;
160 u_int32_t m_iface;
161 };
162 MARSHAL_BEGIN(lldpd_mgmt)
163 MARSHAL_TQE(lldpd_mgmt, m_entries)
164 MARSHAL_END;
165
166 struct lldpd_chassis {
167 TAILQ_ENTRY(lldpd_chassis) c_entries;
168 u_int16_t c_refcount; /* Reference count by ports */
169 u_int16_t c_index; /* Monotonic index */
170 u_int8_t c_protocol; /* Protocol used to get this chassis */
171 u_int8_t c_id_subtype;
172 char *c_id;
173 int c_id_len;
174 char *c_name;
175 char *c_descr;
176
177 u_int16_t c_cap_available;
178 u_int16_t c_cap_enabled;
179
180 u_int16_t c_ttl;
181
182 TAILQ_HEAD(, lldpd_mgmt) c_mgmt;
183
184 #ifdef ENABLE_LLDPMED
185 u_int16_t c_med_cap_available;
186 u_int8_t c_med_type;
187 char *c_med_hw;
188 char *c_med_fw;
189 char *c_med_sw;
190 char *c_med_sn;
191 char *c_med_manuf;
192 char *c_med_model;
193 char *c_med_asset;
194 #endif
195
196 };
197 /* WARNING: any change to this structure should also be reflected into
198 `lldpd_copy_chassis()` which is not using marshaling. */
199 MARSHAL_BEGIN(lldpd_chassis)
200 MARSHAL_IGNORE(lldpd_chassis, c_entries.tqe_next)
201 MARSHAL_IGNORE(lldpd_chassis, c_entries.tqe_prev)
202 MARSHAL_FSTR(lldpd_chassis, c_id, c_id_len)
203 MARSHAL_STR(lldpd_chassis, c_name)
204 MARSHAL_STR(lldpd_chassis, c_descr)
205 MARSHAL_SUBTQ(lldpd_chassis, lldpd_mgmt, c_mgmt)
206 #ifdef ENABLE_LLDPMED
207 MARSHAL_STR(lldpd_chassis, c_med_hw)
208 MARSHAL_STR(lldpd_chassis, c_med_fw)
209 MARSHAL_STR(lldpd_chassis, c_med_sw)
210 MARSHAL_STR(lldpd_chassis, c_med_sn)
211 MARSHAL_STR(lldpd_chassis, c_med_manuf)
212 MARSHAL_STR(lldpd_chassis, c_med_model)
213 MARSHAL_STR(lldpd_chassis, c_med_asset)
214 #endif
215 MARSHAL_END;
216
217
218 struct lldpd_port {
219 TAILQ_ENTRY(lldpd_port) p_entries;
220 struct lldpd_chassis *p_chassis; /* Attached chassis */
221 time_t p_lastchange; /* Time of last change of values */
222 time_t p_lastupdate; /* Time of last update received */
223 struct lldpd_frame *p_lastframe; /* Frame received during last update */
224 u_int8_t p_protocol; /* Protocol used to get this port */
225 u_int8_t p_id_subtype;
226 char *p_id;
227 int p_id_len;
228 char *p_descr;
229 u_int16_t p_mfs;
230 u_int8_t p_hidden_in:1; /* Considered as hidden for reception */
231 u_int8_t p_hidden_out:2; /* Considered as hidden for emission */
232
233 #ifdef ENABLE_DOT3
234 /* Dot3 stuff */
235 u_int32_t p_aggregid;
236 struct lldpd_dot3_macphy p_macphy;
237 struct lldpd_dot3_power p_power;
238 #endif
239
240 #ifdef ENABLE_LLDPMED
241 u_int16_t p_med_cap_enabled;
242 struct lldpd_med_policy p_med_policy[LLDP_MED_APPTYPE_LAST];
243 struct lldpd_med_loc p_med_location[LLDP_MED_LOCFORMAT_LAST];
244 struct lldpd_med_power p_med_power;
245 #endif
246
247 #ifdef ENABLE_DOT1
248 u_int16_t p_pvid;
249 TAILQ_HEAD(, lldpd_vlan) p_vlans;
250 TAILQ_HEAD(, lldpd_ppvid) p_ppvids;
251 TAILQ_HEAD(, lldpd_pi) p_pids;
252 #endif
253 };
254 MARSHAL_BEGIN(lldpd_port)
255 MARSHAL_TQE(lldpd_port, p_entries)
256 MARSHAL_POINTER(lldpd_port, lldpd_chassis, p_chassis)
257 MARSHAL_IGNORE(lldpd_port, p_lastframe)
258 MARSHAL_FSTR(lldpd_port, p_id, p_id_len)
259 MARSHAL_STR(lldpd_port, p_descr)
260 #ifdef ENABLE_LLDPMED
261 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[0])
262 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[1])
263 MARSHAL_SUBSTRUCT(lldpd_port, lldpd_med_loc, p_med_location[2])
264 #endif
265 #ifdef ENABLE_DOT1
266 MARSHAL_SUBTQ(lldpd_port, lldpd_vlan, p_vlans)
267 MARSHAL_SUBTQ(lldpd_port, lldpd_ppvid, p_ppvids)
268 MARSHAL_SUBTQ(lldpd_port, lldpd_pi, p_pids)
269 #endif
270 MARSHAL_END;
271
272 /* Used to modify some port related settings */
273 struct lldpd_port_set {
274 char *ifname;
275 #ifdef ENABLE_LLDPMED
276 struct lldpd_med_policy *med_policy;
277 struct lldpd_med_loc *med_location;
278 struct lldpd_med_power *med_power;
279 #endif
280 #ifdef ENABLE_DOT3
281 struct lldpd_dot3_power *dot3_power;
282 #endif
283 };
284 MARSHAL_BEGIN(lldpd_port_set)
285 MARSHAL_STR(lldpd_port_set, ifname)
286 #ifdef ENABLE_LLDPMED
287 MARSHAL_POINTER(lldpd_port_set, lldpd_med_policy, med_policy)
288 MARSHAL_POINTER(lldpd_port_set, lldpd_med_loc, med_location)
289 MARSHAL_POINTER(lldpd_port_set, lldpd_med_power, med_power)
290 #endif
291 #ifdef ENABLE_DOT3
292 MARSHAL_POINTER(lldpd_port_set, lldpd_dot3_power, dot3_power)
293 #endif
294 MARSHAL_END;
295
296 /* Smart mode / Hide mode */
297 #define SMART_INCOMING_FILTER (1<<0) /* Incoming filtering enabled */
298 #define SMART_INCOMING_ONE_PROTO (1<<1) /* On reception, keep only one proto */
299 #define SMART_INCOMING_ONE_NEIGH (1<<2) /* On reception, keep only one neighbor */
300 #define SMART_OUTGOING_FILTER (1<<3) /* Outgoing filtering enabled */
301 #define SMART_OUTGOING_ONE_PROTO (1<<4) /* On emission, keep only one proto */
302 #define SMART_OUTGOING_ONE_NEIGH (1<<5) /* On emission, consider only one neighbor */
303 #define SMART_INCOMING (SMART_INCOMING_FILTER | \
304 SMART_INCOMING_ONE_PROTO | \
305 SMART_INCOMING_ONE_NEIGH)
306 #define SMART_OUTGOING (SMART_OUTGOING_FILTER | \
307 SMART_OUTGOING_ONE_PROTO | \
308 SMART_OUTGOING_ONE_NEIGH)
309
310 struct lldpd_config {
311 int c_tx_interval; /* Transmit interval */
312 int c_smart; /* Bitmask for smart configuration (see SMART_*) */
313 int c_receiveonly; /* Receive only mode */
314
315 char *c_mgmt_pattern; /* Pattern to match a management address */
316 char *c_cid_pattern; /* Pattern to match interfaces to use for chassis ID */
317 char *c_iface_pattern; /* Pattern to match interfaces to use */
318
319 char *c_platform; /* Override platform description (for CDP) */
320 char *c_description; /* Override chassis description */
321 int c_advertise_version; /* Should the precise version be advertised? */
322
323 #ifdef ENABLE_LLDPMED
324 int c_noinventory; /* Don't send inventory with LLDP-MED */
325 #endif
326 };
327 MARSHAL_BEGIN(lldpd_config)
328 MARSHAL_STR(lldpd_config, c_mgmt_pattern)
329 MARSHAL_STR(lldpd_config, c_cid_pattern)
330 MARSHAL_STR(lldpd_config, c_iface_pattern)
331 MARSHAL_STR(lldpd_config, c_platform)
332 MARSHAL_STR(lldpd_config, c_description)
333 MARSHAL_END;
334
335 struct lldpd_frame {
336 int size;
337 unsigned char frame[1];
338 };
339
340 struct lldpd_hardware;
341 struct lldpd;
342 struct lldpd_ops {
343 int(*send)(struct lldpd *,
344 struct lldpd_hardware*,
345 char *, size_t); /* Function to send a frame */
346 int(*recv)(struct lldpd *,
347 struct lldpd_hardware*,
348 int, char *, size_t); /* Function to receive a frame */
349 int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
350 };
351
352 /* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
353 * means if an interface becomes enslaved, it will be considered as a new
354 * interface. The same applies for renaming and we include the index in case of
355 * renaming to an existing interface. */
356 struct lldpd_hardware {
357 TAILQ_ENTRY(lldpd_hardware) h_entries;
358
359 struct lldpd *h_cfg; /* Pointer to main configuration */
360 void *h_recv; /* FD for reception */
361 int h_sendfd; /* FD for sending, only used by h_ops */
362 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
363 void *h_data; /* Hardware-dependent data */
364
365 int h_mtu;
366 int h_flags; /* Packets will be sent only
367 if IFF_RUNNING. Will be
368 removed if this is left
369 to 0. */
370 int h_ifindex; /* Interface index, used by SNMP */
371 char h_ifname[IFNAMSIZ]; /* Should be unique */
372 u_int8_t h_lladdr[ETHER_ADDR_LEN];
373
374 u_int64_t h_tx_cnt;
375 u_int64_t h_rx_cnt;
376 u_int64_t h_rx_discarded_cnt;
377 u_int64_t h_rx_unrecognized_cnt;
378 u_int64_t h_ageout_cnt;
379 u_int64_t h_insert_cnt;
380 u_int64_t h_delete_cnt;
381
382 struct lldpd_port h_lport; /* Port attached to this hardware port */
383 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
384 };
385 MARSHAL_BEGIN(lldpd_hardware)
386 MARSHAL_IGNORE(lldpd_hardware, h_entries.tqe_next)
387 MARSHAL_IGNORE(lldpd_hardware, h_entries.tqe_prev)
388 MARSHAL_IGNORE(lldpd_hardware, h_ops)
389 MARSHAL_IGNORE(lldpd_hardware, h_data)
390 MARSHAL_IGNORE(lldpd_hardware, h_cfg)
391 MARSHAL_SUBSTRUCT(lldpd_hardware, lldpd_port, h_lport)
392 MARSHAL_SUBTQ(lldpd_hardware, lldpd_port, h_rports)
393 MARSHAL_END;
394
395 struct lldpd_interface {
396 TAILQ_ENTRY(lldpd_interface) next;
397 char *name;
398 };
399 MARSHAL_BEGIN(lldpd_interface)
400 MARSHAL_TQE(lldpd_interface, next)
401 MARSHAL_STR(lldpd_interface, name)
402 MARSHAL_END;
403 TAILQ_HEAD(lldpd_interface_list, lldpd_interface);
404 MARSHAL_TQ(lldpd_interface_list, lldpd_interface);
405
406 struct lldpd_neighbor_change {
407 char *ifname;
408 #define NEIGHBOR_CHANGE_DELETED -1
409 #define NEIGHBOR_CHANGE_ADDED 1
410 #define NEIGHBOR_CHANGE_UPDATED 0
411 int state;
412 struct lldpd_port *neighbor;
413 };
414 MARSHAL_BEGIN(lldpd_neighbor_change)
415 MARSHAL_STR(lldpd_neighbor_change, ifname)
416 MARSHAL_POINTER(lldpd_neighbor_change, lldpd_port, neighbor)
417 MARSHAL_END;
418
419 /* Cleanup functions */
420 void lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *);
421 void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
422 void lldpd_remote_cleanup(struct lldpd_hardware *,
423 void(*expire)(struct lldpd_hardware *, struct lldpd_port *));
424 void lldpd_port_cleanup(struct lldpd_port *, int);
425 void lldpd_config_cleanup(struct lldpd_config *);
426 #ifdef ENABLE_DOT1
427 void lldpd_ppvid_cleanup(struct lldpd_port *);
428 void lldpd_vlan_cleanup(struct lldpd_port *);
429 void lldpd_pi_cleanup(struct lldpd_port *);
430 #endif
431
432 #endif