]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/lldpd.h
Remove "listen on VLAN" feature.
[thirdparty/lldpd.git] / src / lldpd.h
CommitLineData
43c02e7b
VB
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
d38eae28 21# include <config.h>
43c02e7b
VB
22#endif
23
24#define _GNU_SOURCE 1
25#include <stdlib.h>
26#include <string.h>
27#include <sys/queue.h>
d38eae28
VB
28#ifdef HAVE_SYS_TYPES_H
29# include <sys/types.h>
30#endif
43c02e7b 31#ifndef INCLUDE_LINUX_IF_H
d38eae28 32# include <net/if.h>
43c02e7b 33#else
d38eae28
VB
34# include <arpa/inet.h>
35# include <linux/if.h>
43c02e7b 36#endif
b7997528 37#if HAVE_GETIFADDRS
d38eae28 38# include <ifaddrs.h>
43c02e7b
VB
39#endif
40#include <net/ethernet.h>
41#include <netinet/in.h>
4afe659e 42#include <linux/ethtool.h>
2acc1418 43#include <sys/un.h>
43c02e7b
VB
44
45#include "compat.h"
46#include "lldp.h"
4bad1937 47#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
d38eae28 48# include "cdp.h"
4bad1937
VB
49#endif
50#ifdef ENABLE_SONMP
d38eae28 51# include "sonmp.h"
4bad1937
VB
52#endif
53#ifdef ENABLE_EDP
d38eae28 54# include "edp.h"
4bad1937 55#endif
43c02e7b 56
89840df0
VB
57#define SYSFS_CLASS_NET "/sys/class/net/"
58#define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
43c02e7b
VB
59#define LLDPD_TTL 120
60#define LLDPD_TX_DELAY 30
61#define LLDPD_TX_MSGDELAY 1
62#define LLDPD_CTL_SOCKET "/var/run/lldpd.socket"
63#define LLDPD_PID_FILE "/var/run/lldpd.pid"
64
65#define UNIX_PATH_MAX 108
66
67#define USING_AGENTX_SUBAGENT_MODULE 1
68
a1347cd8 69#ifdef ENABLE_DOT1
43c02e7b
VB
70struct lldpd_vlan {
71 TAILQ_ENTRY(lldpd_vlan) v_entries;
72 char *v_name;
73 u_int16_t v_vid;
74};
0c8f36f3 75#define STRUCT_LLDPD_VLAN "(Lsw)"
a1347cd8 76#endif
43c02e7b 77
e3a44efb 78#ifdef ENABLE_LLDPMED
0c8f36f3 79#define STRUCT_LLDPD_MED_POLICY "(bbbwbb)"
e3a44efb
VB
80struct lldpd_med_policy {
81 u_int8_t type;
82 u_int8_t unknown;
83 u_int8_t tagged;
84 u_int16_t vid;
85 u_int8_t priority;
86 u_int8_t dscp;
e3a44efb
VB
87};
88
0c8f36f3 89#define STRUCT_LLDPD_MED_LOC "(bC)"
e3a44efb
VB
90struct lldpd_med_loc {
91 u_int8_t format;
92 char *data;
93 int data_len;
e3a44efb 94};
6d08df0e
VB
95
96#define STRUCT_LLDPD_MED_POWER "(bbbw)"
97struct lldpd_med_power {
98 u_int8_t devicetype; /* PD or PSE */
99 u_int8_t source;
100 u_int8_t priority;
101 u_int16_t val;
102};
e3a44efb
VB
103#endif
104
43c02e7b 105struct lldpd_chassis {
75068724
VB
106 TAILQ_ENTRY(lldpd_chassis) c_entries;
107 u_int16_t c_refcount; /* Reference count by ports */
108 u_int16_t c_index; /* Monotonic index */
109 u_int8_t c_protocol; /* Protocol used to get this chassis */
43c02e7b
VB
110 u_int8_t c_id_subtype;
111 char *c_id;
112 int c_id_len;
113 char *c_name;
114 char *c_descr;
115
116 u_int16_t c_cap_available;
117 u_int16_t c_cap_enabled;
118
119 u_int16_t c_ttl;
120
121 struct in_addr c_mgmt;
122 u_int32_t c_mgmt_if;
89840df0
VB
123
124#ifdef ENABLE_LLDPMED
34602f3b 125#define STRUCT_LLDPD_CHASSIS_MED "wbsssssss"
40ecae87 126 u_int16_t c_med_cap_available;
89840df0
VB
127 u_int8_t c_med_type;
128 char *c_med_hw;
129 char *c_med_fw;
130 char *c_med_sw;
131 char *c_med_sn;
132 char *c_med_manuf;
133 char *c_med_model;
134 char *c_med_asset;
89840df0 135#else
a1347cd8 136#define STRUCT_LLDPD_CHASSIS_MED ""
89840df0 137#endif
1531f7f3
VB
138
139};
75068724 140#define STRUCT_LLDPD_CHASSIS "(LwwbbCsswwwll" STRUCT_LLDPD_CHASSIS_MED ")"
43c02e7b
VB
141
142struct lldpd_port {
75068724
VB
143 TAILQ_ENTRY(lldpd_port) p_entries;
144 struct lldpd_chassis *p_chassis; /* Attached chassis */
145 time_t p_lastchange; /* Time of last change of values */
146 time_t p_lastupdate; /* Time of last update received */
147 struct lldpd_frame *p_lastframe; /* Frame received during last update */
148 u_int8_t p_protocol; /* Protocol used to get this port */
43c02e7b
VB
149 u_int8_t p_id_subtype;
150 char *p_id;
151 int p_id_len;
152 char *p_descr;
548109b2 153 u_int16_t p_mfs;
43c02e7b 154
a1347cd8 155#ifdef ENABLE_DOT3
1531f7f3 156#define STRUCT_LLDPD_PORT_DOT3 "lbbww"
43c02e7b
VB
157 /* Dot3 stuff */
158 u_int32_t p_aggregid;
159 u_int8_t p_autoneg_support;
160 u_int8_t p_autoneg_enabled;
161 u_int16_t p_autoneg_advertised;
162 u_int16_t p_mau_type;
a1347cd8
VB
163#else
164#define STRUCT_LLDPD_PORT_DOT3 ""
165#endif
1531f7f3 166
740593ff
VB
167#ifdef ENABLE_LLDPMED
168#define STRUCT_LLDPD_PORT_MED "w" \
169 STRUCT_LLDPD_MED_POLICY \
170 STRUCT_LLDPD_MED_POLICY \
171 STRUCT_LLDPD_MED_POLICY \
172 STRUCT_LLDPD_MED_POLICY \
173 STRUCT_LLDPD_MED_POLICY \
174 STRUCT_LLDPD_MED_POLICY \
175 STRUCT_LLDPD_MED_POLICY \
176 STRUCT_LLDPD_MED_POLICY \
177 STRUCT_LLDPD_MED_LOC \
178 STRUCT_LLDPD_MED_LOC \
179 STRUCT_LLDPD_MED_LOC \
6d08df0e 180 STRUCT_LLDPD_MED_POWER
740593ff
VB
181 u_int16_t p_med_cap_enabled;
182 struct lldpd_med_policy p_med_policy[LLDPMED_APPTYPE_LAST];
183 struct lldpd_med_loc p_med_location[LLDPMED_LOCFORMAT_LAST];
6d08df0e 184 struct lldpd_med_power p_med_power;
740593ff
VB
185#else
186#define STRUCT_LLDPD_PORT_MED ""
187#endif
188
a1347cd8 189#ifdef ENABLE_DOT1
75b3469d
VB
190#define STRUCT_LLDPD_PORT_DOT1 "wPP"
191 u_int16_t p_pvid;
1531f7f3 192 TAILQ_HEAD(, lldpd_vlan) p_vlans;
a1347cd8
VB
193#else
194#define STRUCT_LLDPD_PORT_DOT1 ""
195#endif
1531f7f3
VB
196};
197
84853b92 198#define STRUCT_LLDPD_PORT "(LPttPbbCsw" \
740593ff
VB
199 STRUCT_LLDPD_PORT_DOT3 \
200 STRUCT_LLDPD_PORT_MED \
201 STRUCT_LLDPD_PORT_DOT1 ")"
43c02e7b
VB
202
203struct lldpd_frame {
204 int size;
b5c7ce8d 205 unsigned char frame[1];
43c02e7b
VB
206};
207
6e75df87
VB
208struct lldpd_hardware;
209struct lldpd;
210struct lldpd_ops {
211 int(*send)(struct lldpd *,
212 struct lldpd_hardware*,
213 char *, size_t); /* Function to send a frame */
214 int(*recv)(struct lldpd *,
215 struct lldpd_hardware*,
216 int, char *, size_t); /* Function to receive a frame */
217 int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
218};
219
44002d66
VB
220/* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
221 * means if an interface becomes enslaved, it will be considered as a new
222 * interface. The same applies for renaming and we include the index in case of
223 * renaming to an existing interface. */
43c02e7b
VB
224struct lldpd_hardware {
225 TAILQ_ENTRY(lldpd_hardware) h_entries;
226
6e75df87
VB
227 fd_set h_recvfds; /* FD for reception */
228 int h_sendfd; /* FD for sending, only used by h_ops */
229 struct lldpd_ops *h_ops; /* Hardware-dependent functions */
230 void *h_data; /* Hardware-dependent data */
43c02e7b 231
43c02e7b 232 int h_mtu;
6e75df87
VB
233 int h_flags; /* Packets will be sent only
234 if IFF_RUNNING. Will be
235 removed if this is left
236 to 0. */
237 int h_ifindex; /* Interface index, used by SNMP */
238 char h_ifname[IFNAMSIZ]; /* Should be unique */
43c02e7b
VB
239 u_int8_t h_lladdr[ETHER_ADDR_LEN];
240
241 u_int64_t h_tx_cnt;
242 u_int64_t h_rx_cnt;
243 u_int64_t h_rx_discarded_cnt;
244 u_int64_t h_rx_ageout_cnt;
37387046 245 u_int64_t h_rx_unrecognized_cnt;
43c02e7b 246
75068724
VB
247 struct lldpd_port h_lport; /* Port attached to this hardware port */
248 TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
43c02e7b
VB
249};
250
251struct lldpd_interface {
252 TAILQ_ENTRY(lldpd_interface) next;
253 char *name;
254};
0c8f36f3 255#define STRUCT_LLDPD_INTERFACE "(Ls)"
43c02e7b 256
77507b69 257#define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
43c02e7b
VB
258#define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
259#define PROTO_GUESS_SIG char *, int
260
43c02e7b 261struct protocol {
f2dcb180
VB
262#define LLDPD_MODE_LLDP 1
263#define LLDPD_MODE_CDPV1 2
264#define LLDPD_MODE_CDPV2 3
265#define LLDPD_MODE_SONMP 4
266#define LLDPD_MODE_EDP 5
267#define LLDPD_MODE_FDP 6
43c02e7b
VB
268 int mode; /* > 0 mode identifier (unique per protocol) */
269 int enabled; /* Is this protocol enabled? */
270 char *name; /* Name of protocol */
271 char arg; /* Argument to enable this protocol */
272 int(*send)(PROTO_SEND_SIG); /* How to send a frame */
273 int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
274 int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
275 u_int8_t mac[ETH_ALEN]; /* Destination MAC address used by this protocol */
43c02e7b
VB
276};
277
77d7090e
VB
278#define CALLBACK_SIG struct lldpd*, struct lldpd_callback*
279struct lldpd_callback {
280 TAILQ_ENTRY(lldpd_callback) next;
281 int fd; /* FD that will trigger this callback */
282 void(*function)(CALLBACK_SIG); /* Function called */
283 void *data; /* Optional data for this callback*/
284};
285
43c02e7b
VB
286struct lldpd {
287 int g_sock;
288 int g_delay;
289
290 struct protocol *g_protocols;
740593ff
VB
291#ifdef ENABLE_LLDPMED
292 int g_noinventory;
293#endif
de1b1b3a 294 int g_advertise_version;
43c02e7b
VB
295
296 time_t g_lastsent;
297 int g_lastrid;
298#ifdef USE_SNMP
299 int g_snmp;
300#endif /* USE_SNMP */
301
302 /* Unix socket handling */
303 int g_ctl;
77d7090e
VB
304
305 TAILQ_HEAD(, lldpd_callback) g_callbacks;
43c02e7b
VB
306
307 char *g_mgmt_pattern;
308
40ce835b
ST
309 char *g_descr_override;
310
77507b69 311#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
75068724 312 TAILQ_HEAD(, lldpd_chassis) g_chassis;
43c02e7b
VB
313 TAILQ_HEAD(, lldpd_hardware) g_hardware;
314};
315
6e75df87
VB
316typedef void(*lldpd_ifhandlers)(struct lldpd *, struct ifaddrs *);
317
43c02e7b
VB
318enum hmsg_type {
319 HMSG_NONE,
320 HMSG_GET_INTERFACES,
84853b92 321 HMSG_GET_NB_PORTS,
43c02e7b 322 HMSG_GET_PORT,
84853b92 323 HMSG_GET_CHASSIS,
43c02e7b 324 HMSG_GET_VLANS,
740593ff 325 HMSG_SET_LOCATION,
86f24df3 326 HMSG_SET_POLICY,
009ddd23 327 HMSG_SET_POWER,
43c02e7b
VB
328 HMSG_SHUTDOWN
329};
330
331struct hmsg_hdr {
332 enum hmsg_type type;
333 int16_t len;
334 pid_t pid;
335} __attribute__ ((__packed__));
336
337struct hmsg {
338 struct hmsg_hdr hdr;
339 void *data;
340} __attribute__ ((__packed__));
341
342#define HMSG_HEADER_SIZE sizeof(struct hmsg_hdr)
343#define MAX_HMSGSIZE 8192
344
345/* lldpd.c */
44002d66
VB
346struct lldpd_hardware *lldpd_get_hardware(struct lldpd *,
347 char *, int, struct lldpd_ops *);
6e75df87
VB
348struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *);
349void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
a1347cd8 350#ifdef ENABLE_DOT1
43c02e7b 351void lldpd_vlan_cleanup(struct lldpd_port *);
a1347cd8 352#endif
43c02e7b 353void lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
9898ac07 354void lldpd_port_cleanup(struct lldpd*, struct lldpd_port *, int);
77507b69 355void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
77d7090e
VB
356int lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
357void lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));
2acc1418 358int lldpd_main(int, char **);
43c02e7b
VB
359
360/* lldp.c */
361int lldp_send(PROTO_SEND_SIG);
362int lldp_decode(PROTO_DECODE_SIG);
363
364/* cdp.c */
4bad1937 365#ifdef ENABLE_CDP
43c02e7b
VB
366int cdpv1_send(PROTO_SEND_SIG);
367int cdpv2_send(PROTO_SEND_SIG);
43c02e7b
VB
368int cdpv1_guess(PROTO_GUESS_SIG);
369int cdpv2_guess(PROTO_GUESS_SIG);
4bad1937
VB
370#endif
371#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
372int cdp_decode(PROTO_DECODE_SIG);
373#endif
374#ifdef ENABLE_FDP
375int fdp_send(PROTO_SEND_SIG);
376#endif
43c02e7b 377
4bad1937 378#ifdef ENABLE_SONMP
43c02e7b
VB
379/* sonmp.c */
380int sonmp_send(PROTO_SEND_SIG);
381int sonmp_decode(PROTO_DECODE_SIG);
4bad1937 382#endif
43c02e7b 383
4bad1937 384#ifdef ENABLE_EDP
43c02e7b
VB
385/* edp.c */
386int edp_send(PROTO_SEND_SIG);
387int edp_decode(PROTO_DECODE_SIG);
4bad1937 388#endif
43c02e7b
VB
389
390/* ctl.c */
b5562b23 391int ctl_create(char *);
43c02e7b 392int ctl_connect(char *);
b5562b23 393void ctl_cleanup(char *);
77d7090e 394void ctl_accept(struct lldpd *, struct lldpd_callback *);
43c02e7b
VB
395void ctl_msg_init(struct hmsg *, enum hmsg_type);
396int ctl_msg_send(int, struct hmsg *);
397int ctl_msg_recv(int, struct hmsg *);
398int ctl_msg_pack_list(char *, void *, unsigned int, struct hmsg *, void **);
399int ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg *, void **);
400int ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg *, void **);
401int ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void **);
402
6e75df87 403/* interfaces.c */
849954d7 404void lldpd_ifh_bond(struct lldpd *, struct ifaddrs *);
6e75df87 405void lldpd_ifh_eth(struct lldpd *, struct ifaddrs *);
5994b27d 406#ifdef ENABLE_DOT1
6e75df87 407void lldpd_ifh_vlan(struct lldpd *, struct ifaddrs *);
5994b27d 408#endif
6e75df87
VB
409void lldpd_ifh_mgmt(struct lldpd *, struct ifaddrs *);
410
411/* dmi.c */
89840df0 412#ifdef ENABLE_LLDPMED
6f1046d1
VB
413char *dmi_hw(void);
414char *dmi_fw(void);
415char *dmi_sn(void);
416char *dmi_manuf(void);
417char *dmi_model(void);
418char *dmi_asset(void);
89840df0 419#endif
43c02e7b
VB
420
421/* log.c */
6bb9c4e0 422void log_init(int, const char *);
e51da5ec 423void log_warn(const char *, ...) __attribute__ ((format (printf, 1, 2)));
563e2dfc 424#define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
e51da5ec 425void log_warnx(const char *, ...) __attribute__ ((format (printf, 1, 2)));
563e2dfc 426#define LLOG_WARNX(x,...) log_warnx("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
e51da5ec 427void log_info(const char *, ...) __attribute__ ((format (printf, 1, 2)));
563e2dfc 428#define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
e51da5ec 429void log_debug(const char *, ...) __attribute__ ((format (printf, 1, 2)));
563e2dfc 430#define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
43c02e7b
VB
431void fatal(const char *);
432void fatalx(const char *);
433
434/* agent.c */
6f1046d1 435void agent_shutdown(void);
bbea66e1 436void agent_init(struct lldpd *, char *, int);
43c02e7b 437
d72a05d4 438/* agent_priv.c */
6f1046d1 439void agent_priv_register_domain(void);
43c02e7b 440
a552a72e
VB
441/* client.c */
442struct client_handle {
443 enum hmsg_type type;
444 void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*);
445};
446
77d7090e
VB
447void client_handle_client(struct lldpd *, struct lldpd_callback *,
448 char *, int);
a552a72e
VB
449void client_handle_none(struct lldpd *, struct hmsg *,
450 struct hmsg *);
451void client_handle_get_interfaces(struct lldpd *, struct hmsg *,
452 struct hmsg *);
740593ff 453void client_handle_port_related(struct lldpd *, struct hmsg *,
a552a72e
VB
454 struct hmsg *);
455void client_handle_shutdown(struct lldpd *, struct hmsg *,
456 struct hmsg *);
457
b5562b23 458/* priv.c */
a2993d83 459void priv_init(char*);
6f1046d1
VB
460int priv_ctl_create(void);
461void priv_ctl_cleanup(void);
462char *priv_gethostbyname(void);
a7502371
VB
463int priv_open(char*);
464int priv_ethtool(char*, struct ethtool_cmd*);
849954d7 465int priv_iface_init(const char *);
ef76f920 466int priv_iface_multicast(const char *, u_int8_t *, int);
d72a05d4 467int priv_snmp_socket(struct sockaddr_un *);
4afe659e
VB
468
469/* privsep_fdpass.c */
470int receive_fd(int);
471void send_fd(int, int);
b5562b23 472
43c02e7b 473#endif /* _LLDPD_H */