]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/lldpd.h
Change the way interface information are collected.
[thirdparty/lldpd.git] / src / lldpd.h
1 /*
2 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef _LLDPD_H
18 #define _LLDPD_H
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #define _GNU_SOURCE 1
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/queue.h>
28 #ifndef INCLUDE_LINUX_IF_H
29 #include <net/if.h>
30 #else
31 #include <arpa/inet.h>
32 #include <linux/if.h>
33 #endif
34 #include <ifaddrs.h>
35 #include <net/ethernet.h>
36 #include <netinet/in.h>
37 #include <linux/ethtool.h>
38
39 #include "compat.h"
40 #include "lldp.h"
41 #if defined (ENABLE_CDP) || defined (ENABLE_FDP)
42 #include "cdp.h"
43 #endif
44 #ifdef ENABLE_SONMP
45 #include "sonmp.h"
46 #endif
47 #ifdef ENABLE_EDP
48 #include "edp.h"
49 #endif
50
51 #define SYSFS_CLASS_NET "/sys/class/net/"
52 #define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
53 #define LLDPD_TTL 120
54 #define LLDPD_TX_DELAY 30
55 #define LLDPD_TX_MSGDELAY 1
56 #define LLDPD_CTL_SOCKET "/var/run/lldpd.socket"
57 #define LLDPD_PID_FILE "/var/run/lldpd.pid"
58
59 #define UNIX_PATH_MAX 108
60
61 #define USING_AGENTX_SUBAGENT_MODULE 1
62
63 #ifdef ENABLE_DOT1
64 struct lldpd_vlan {
65 TAILQ_ENTRY(lldpd_vlan) v_entries;
66 char *v_name;
67 u_int16_t v_vid;
68 };
69 #define STRUCT_LLDPD_VLAN "(Lsw)"
70 #endif
71
72 #ifdef ENABLE_LLDPMED
73 #define STRUCT_LLDPD_MED_POLICY "(bbbwbb)"
74 struct lldpd_med_policy {
75 u_int8_t type;
76 u_int8_t unknown;
77 u_int8_t tagged;
78 u_int16_t vid;
79 u_int8_t priority;
80 u_int8_t dscp;
81 };
82
83 #define STRUCT_LLDPD_MED_LOC "(bC)"
84 struct lldpd_med_loc {
85 u_int8_t format;
86 char *data;
87 int data_len;
88 };
89 #endif
90
91 struct lldpd_chassis {
92 TAILQ_ENTRY(lldpd_chassis) c_entries;
93 u_int16_t c_refcount; /* Reference count by ports */
94 u_int16_t c_index; /* Monotonic index */
95 u_int8_t c_protocol; /* Protocol used to get this chassis */
96 u_int8_t c_id_subtype;
97 char *c_id;
98 int c_id_len;
99 char *c_name;
100 char *c_descr;
101
102 u_int16_t c_cap_available;
103 u_int16_t c_cap_enabled;
104
105 u_int16_t c_ttl;
106
107 struct in_addr c_mgmt;
108 u_int32_t c_mgmt_if;
109
110 #ifdef ENABLE_LLDPMED
111 #define STRUCT_LLDPD_CHASSIS_MED "wbsssssss"
112 u_int16_t c_med_cap_available;
113 u_int8_t c_med_type;
114 char *c_med_hw;
115 char *c_med_fw;
116 char *c_med_sw;
117 char *c_med_sn;
118 char *c_med_manuf;
119 char *c_med_model;
120 char *c_med_asset;
121 #else
122 #define STRUCT_LLDPD_CHASSIS_MED ""
123 #endif
124
125 };
126 #define STRUCT_LLDPD_CHASSIS "(LwwbbCsswwwll" STRUCT_LLDPD_CHASSIS_MED ")"
127
128 struct lldpd_port {
129 TAILQ_ENTRY(lldpd_port) p_entries;
130 struct lldpd_chassis *p_chassis; /* Attached chassis */
131 time_t p_lastchange; /* Time of last change of values */
132 time_t p_lastupdate; /* Time of last update received */
133 struct lldpd_frame *p_lastframe; /* Frame received during last update */
134 u_int8_t p_protocol; /* Protocol used to get this port */
135 u_int8_t p_id_subtype;
136 char *p_id;
137 int p_id_len;
138 char *p_descr;
139 u_int16_t p_mfs;
140
141 #ifdef ENABLE_DOT3
142 #define STRUCT_LLDPD_PORT_DOT3 "lbbww"
143 /* Dot3 stuff */
144 u_int32_t p_aggregid;
145 u_int8_t p_autoneg_support;
146 u_int8_t p_autoneg_enabled;
147 u_int16_t p_autoneg_advertised;
148 u_int16_t p_mau_type;
149 #else
150 #define STRUCT_LLDPD_PORT_DOT3 ""
151 #endif
152
153 #ifdef ENABLE_LLDPMED
154 #define STRUCT_LLDPD_PORT_MED "w" \
155 STRUCT_LLDPD_MED_POLICY \
156 STRUCT_LLDPD_MED_POLICY \
157 STRUCT_LLDPD_MED_POLICY \
158 STRUCT_LLDPD_MED_POLICY \
159 STRUCT_LLDPD_MED_POLICY \
160 STRUCT_LLDPD_MED_POLICY \
161 STRUCT_LLDPD_MED_POLICY \
162 STRUCT_LLDPD_MED_POLICY \
163 STRUCT_LLDPD_MED_LOC \
164 STRUCT_LLDPD_MED_LOC \
165 STRUCT_LLDPD_MED_LOC \
166 "bbbw"
167 u_int16_t p_med_cap_enabled;
168 struct lldpd_med_policy p_med_policy[LLDPMED_APPTYPE_LAST];
169 struct lldpd_med_loc p_med_location[LLDPMED_LOCFORMAT_LAST];
170 u_int8_t p_med_pow_devicetype; /* PD or PSE */
171 u_int8_t p_med_pow_source;
172 u_int8_t p_med_pow_priority;
173 u_int16_t p_med_pow_val;
174 #else
175 #define STRUCT_LLDPD_PORT_MED ""
176 #endif
177
178 #ifdef ENABLE_DOT1
179 #define STRUCT_LLDPD_PORT_DOT1 "wPP"
180 u_int16_t p_pvid;
181 TAILQ_HEAD(, lldpd_vlan) p_vlans;
182 #else
183 #define STRUCT_LLDPD_PORT_DOT1 ""
184 #endif
185 };
186
187 #define STRUCT_LLDPD_PORT "(LPttPbbCsw" \
188 STRUCT_LLDPD_PORT_DOT3 \
189 STRUCT_LLDPD_PORT_MED \
190 STRUCT_LLDPD_PORT_DOT1 ")"
191
192 struct lldpd_frame {
193 int size;
194 unsigned char frame[];
195 };
196
197 struct lldpd_hardware;
198 struct lldpd;
199 struct lldpd_ops {
200 int(*send)(struct lldpd *,
201 struct lldpd_hardware*,
202 char *, size_t); /* Function to send a frame */
203 int(*recv)(struct lldpd *,
204 struct lldpd_hardware*,
205 int, char *, size_t); /* Function to receive a frame */
206 int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
207 };
208
209 struct lldpd_hardware {
210 TAILQ_ENTRY(lldpd_hardware) h_entries;
211
212 fd_set h_recvfds; /* FD for reception */
213 int h_sendfd; /* FD for sending, only used by h_ops */
214 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
215 void *h_data; /* Hardware-dependent data */
216
217 int h_mtu;
218 int h_flags; /* Packets will be sent only
219 if IFF_RUNNING. Will be
220 removed if this is left
221 to 0. */
222 int h_ifindex; /* Interface index, used by SNMP */
223 char h_ifname[IFNAMSIZ]; /* Should be unique */
224 u_int8_t h_lladdr[ETHER_ADDR_LEN];
225
226 u_int64_t h_tx_cnt;
227 u_int64_t h_rx_cnt;
228 u_int64_t h_rx_discarded_cnt;
229 u_int64_t h_rx_ageout_cnt;
230 u_int64_t h_rx_unrecognized_cnt;
231
232 struct lldpd_port h_lport; /* Port attached to this hardware port */
233 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
234 };
235
236 struct lldpd_interface {
237 TAILQ_ENTRY(lldpd_interface) next;
238 char *name;
239 };
240 #define STRUCT_LLDPD_INTERFACE "(Ls)"
241
242 struct lldpd_client {
243 TAILQ_ENTRY(lldpd_client) next;
244 int fd;
245 };
246
247 #define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
248 #define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
249 #define PROTO_GUESS_SIG char *, int
250
251 struct protocol {
252 #define LLDPD_MODE_LLDP 1
253 #define LLDPD_MODE_CDPV1 2
254 #define LLDPD_MODE_CDPV2 3
255 #define LLDPD_MODE_SONMP 4
256 #define LLDPD_MODE_EDP 5
257 #define LLDPD_MODE_FDP 6
258 int mode; /* > 0 mode identifier (unique per protocol) */
259 int enabled; /* Is this protocol enabled? */
260 char *name; /* Name of protocol */
261 char arg; /* Argument to enable this protocol */
262 int(*send)(PROTO_SEND_SIG); /* How to send a frame */
263 int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
264 int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
265 u_int8_t mac[ETH_ALEN]; /* Destination MAC address used by this protocol */
266 struct sock_filter *filter; /* BPF filter */
267 size_t filterlen; /* Size of BPF filter */
268 };
269
270 struct lldpd {
271 int g_sock;
272 int g_delay;
273
274 struct protocol *g_protocols;
275 #ifdef ENABLE_LLDPMED
276 int g_noinventory;
277 #endif
278
279 time_t g_lastsent;
280 int g_lastrid;
281 #ifdef USE_SNMP
282 int g_snmp;
283 #endif /* USE_SNMP */
284
285 /* Unix socket handling */
286 int g_ctl;
287 TAILQ_HEAD(, lldpd_client) g_clients;
288
289 char *g_mgmt_pattern;
290
291 #define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
292 TAILQ_HEAD(, lldpd_chassis) g_chassis;
293 TAILQ_HEAD(, lldpd_hardware) g_hardware;
294 };
295
296 typedef void(*lldpd_ifhandlers)(struct lldpd *, struct ifaddrs *);
297
298 enum hmsg_type {
299 HMSG_NONE,
300 HMSG_GET_INTERFACES,
301 HMSG_GET_NB_PORTS,
302 HMSG_GET_PORT,
303 HMSG_GET_CHASSIS,
304 HMSG_GET_VLANS,
305 HMSG_SET_LOCATION,
306 HMSG_SHUTDOWN
307 };
308
309 struct hmsg_hdr {
310 enum hmsg_type type;
311 int16_t len;
312 pid_t pid;
313 } __attribute__ ((__packed__));
314
315 struct hmsg {
316 struct hmsg_hdr hdr;
317 void *data;
318 } __attribute__ ((__packed__));
319
320 #define HMSG_HEADER_SIZE sizeof(struct hmsg_hdr)
321 #define MAX_HMSGSIZE 8192
322
323 /* lldpd.c */
324 struct lldpd_hardware *lldpd_get_hardware(struct lldpd *, char *);
325 struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *);
326 void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
327 #ifdef ENABLE_DOT1
328 void lldpd_vlan_cleanup(struct lldpd_port *);
329 #endif
330 void lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
331 void lldpd_port_cleanup(struct lldpd_port *, int);
332 void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
333
334 /* lldp.c */
335 int lldp_send(PROTO_SEND_SIG);
336 int lldp_decode(PROTO_DECODE_SIG);
337
338 /* cdp.c */
339 #ifdef ENABLE_CDP
340 int cdpv1_send(PROTO_SEND_SIG);
341 int cdpv2_send(PROTO_SEND_SIG);
342 int cdpv1_guess(PROTO_GUESS_SIG);
343 int cdpv2_guess(PROTO_GUESS_SIG);
344 #endif
345 #if defined (ENABLE_CDP) || defined (ENABLE_FDP)
346 int cdp_decode(PROTO_DECODE_SIG);
347 #endif
348 #ifdef ENABLE_FDP
349 int fdp_send(PROTO_SEND_SIG);
350 #endif
351
352 #ifdef ENABLE_SONMP
353 /* sonmp.c */
354 int sonmp_send(PROTO_SEND_SIG);
355 int sonmp_decode(PROTO_DECODE_SIG);
356 #endif
357
358 #ifdef ENABLE_EDP
359 /* edp.c */
360 int edp_send(PROTO_SEND_SIG);
361 int edp_decode(PROTO_DECODE_SIG);
362 #endif
363
364 /* ctl.c */
365 int ctl_create(char *);
366 int ctl_connect(char *);
367 void ctl_cleanup(char *);
368 int ctl_accept(struct lldpd *, int);
369 int ctl_close(struct lldpd *, int);
370 void ctl_msg_init(struct hmsg *, enum hmsg_type);
371 int ctl_msg_send(int, struct hmsg *);
372 int ctl_msg_recv(int, struct hmsg *);
373 int ctl_msg_pack_list(char *, void *, unsigned int, struct hmsg *, void **);
374 int ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg *, void **);
375 int ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg *, void **);
376 int ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void **);
377
378 /* interfaces.c */
379 void lldpd_ifh_eth(struct lldpd *, struct ifaddrs *);
380 void lldpd_ifh_vlan(struct lldpd *, struct ifaddrs *);
381 void lldpd_ifh_mgmt(struct lldpd *, struct ifaddrs *);
382
383 /* dmi.c */
384 #ifdef ENABLE_LLDPMED
385 char *dmi_hw();
386 char *dmi_fw();
387 char *dmi_sn();
388 char *dmi_manuf();
389 char *dmi_model();
390 char *dmi_asset();
391 #endif
392
393 /* log.c */
394 void log_init(int);
395 void log_warn(const char *, ...);
396 #define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__, ##__VA_ARGS__)
397 void log_warnx(const char *, ...);
398 #define LLOG_WARNX(x,...) log_warnx("%s: " x, __FUNCTION__, ##__VA_ARGS__)
399 void log_info(const char *, ...);
400 #define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__, ##__VA_ARGS__)
401 void log_debug(const char *, ...);
402 #define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__, ##__VA_ARGS__)
403 void fatal(const char *);
404 void fatalx(const char *);
405
406 /* agent.c */
407 void agent_shutdown();
408 void agent_init(struct lldpd *, int);
409
410 /* agent_priv.c */
411 void agent_priv_register_domain();
412
413 /* strlcpy.c */
414 size_t strlcpy(char *, const char *, size_t);
415
416 /* client.c */
417 struct client_handle {
418 enum hmsg_type type;
419 void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*);
420 };
421
422 void client_handle_client(struct lldpd *, struct lldpd_client *,
423 char *, int);
424 void client_handle_none(struct lldpd *, struct hmsg *,
425 struct hmsg *);
426 void client_handle_get_interfaces(struct lldpd *, struct hmsg *,
427 struct hmsg *);
428 void client_handle_port_related(struct lldpd *, struct hmsg *,
429 struct hmsg *);
430 void client_handle_shutdown(struct lldpd *, struct hmsg *,
431 struct hmsg *);
432
433 /* priv.c */
434 void priv_init(char*);
435 int priv_ctl_create();
436 void priv_ctl_cleanup();
437 char *priv_gethostbyname();
438 int priv_open(char*);
439 int priv_ethtool(char*, struct ethtool_cmd*);
440 int priv_iface_eth_init(struct lldpd_hardware *);
441 int priv_iface_multicast(const char *, u_int8_t *, int);
442 int priv_snmp_socket(struct sockaddr_un *);
443
444 /* privsep_fdpass.c */
445 int receive_fd(int);
446 void send_fd(int, int);
447
448 #endif /* _LLDPD_H */