#ifndef _LLDPD_H
#define _LLDPD_H
-#define _GNU_SOURCE 1
#if HAVE_CONFIG_H
# include <config.h>
#include "lldp-tlv.h"
#if defined (ENABLE_CDP) || defined (ENABLE_FDP)
-# include "cdp.h"
+# include "protocols/cdp.h"
#endif
#ifdef ENABLE_SONMP
-# include "sonmp.h"
+# include "protocols/sonmp.h"
#endif
#ifdef ENABLE_EDP
-# include "edp.h"
+# include "protocols/edp.h"
#endif
+
+
#include "../compat/compat.h"
#include "../marshal.h"
#include "../log.h"
#define SYSFS_CLASS_NET "/sys/class/net/"
#define SYSFS_CLASS_DMI "/sys/class/dmi/id/"
-#define LLDPD_TTL 120
#define LLDPD_TX_INTERVAL 30
+#define LLDPD_TX_HOLD 4
+#define LLDPD_TTL LLDPD_TX_INTERVAL * LLDPD_TX_HOLD
#define LLDPD_TX_MSGDELAY 1
-#define LLDPD_PID_FILE "/var/run/lldpd.pid"
+#define LLDPD_MAX_NEIGHBORS 32
+#define LLDPD_FAST_TX_INTERVAL 1
+#define LLDPD_FAST_INIT 4
#define USING_AGENTX_SUBAGENT_MODULE 1
#define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
#define PROTO_GUESS_SIG char *, int
+#define ALIGNED_CAST(TYPE, ATTR) ((TYPE) (void *) (ATTR))
+
struct protocol {
int mode; /* > 0 mode identifier (unique per protocol) */
int enabled; /* Is this protocol enabled? */
int(*send)(PROTO_SEND_SIG); /* How to send a frame */
int(*decode)(PROTO_DECODE_SIG); /* How to decode a frame */
int(*guess)(PROTO_GUESS_SIG); /* Can be NULL, use MAC address in this case */
- u_int8_t mac[ETHER_ADDR_LEN]; /* Destination MAC address used by this protocol */
+ u_int8_t mac1[ETHER_ADDR_LEN]; /* Destination MAC address used by this protocol */
+ u_int8_t mac2[ETHER_ADDR_LEN]; /* Destination MAC address used by this protocol */
+ u_int8_t mac3[ETHER_ADDR_LEN]; /* Destination MAC address used by this protocol */
};
#define SMART_HIDDEN(port) (port->p_hidden_in)
-struct lldpd {
- int g_sock;
- struct event_base *g_base;
-#ifdef USE_SNMP
-#endif
-
- struct lldpd_config g_config;
-
- struct protocol *g_protocols;
- int g_lastrid;
- struct event *g_main_loop;
-#ifdef USE_SNMP
- int g_snmp;
- struct event *g_snmp_timeout;
- void *g_snmp_fds;
- char *g_snmp_agentx;
-#endif /* USE_SNMP */
-
- /* Unix socket handling */
- int g_ctl;
- struct event *g_ctl_event;
- struct event *g_iface_event; /* Triggered when there is an interface change */
- struct event *g_iface_timer_event; /* Triggered one second after last interface change */
-
- char *g_lsb_release;
-
-#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
- TAILQ_HEAD(, lldpd_chassis) g_chassis;
- TAILQ_HEAD(, lldpd_hardware) g_hardware;
-};
+struct lldpd;
/* lldpd.c */
struct lldpd_hardware *lldpd_get_hardware(struct lldpd *,
- char *, int, struct lldpd_ops *);
+ char *, int);
struct lldpd_hardware *lldpd_alloc_hardware(struct lldpd *, char *, int);
void lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
struct lldpd_mgmt *lldpd_alloc_mgmt(int family, void *addr, size_t addrsize, u_int32_t iface);
void lldpd_recv(struct lldpd *, struct lldpd_hardware *, int);
void lldpd_send(struct lldpd_hardware *);
void lldpd_loop(struct lldpd *);
-int lldpd_main(int, char **);
+int lldpd_main(int, char **, char **);
void lldpd_update_localports(struct lldpd *);
+void lldpd_update_localchassis(struct lldpd *);
+void lldpd_cleanup(struct lldpd *);
/* frame.c */
u_int16_t frame_checksum(const u_int8_t *, int, int);
/* event.c */
void levent_loop(struct lldpd *);
+void levent_shutdown(struct lldpd *);
void levent_hardware_init(struct lldpd_hardware *);
void levent_hardware_add_fd(struct lldpd_hardware *, int);
void levent_hardware_release(struct lldpd_hardware *);
void levent_ctl_notify(char *, int, struct lldpd_port *);
void levent_send_now(struct lldpd *);
-void levent_iface_subscribe(struct lldpd *, int);
+void levent_update_now(struct lldpd *);
+int levent_iface_subscribe(struct lldpd *, int);
void levent_schedule_pdu(struct lldpd_hardware *);
+void levent_schedule_cleanup(struct lldpd *);
+int levent_make_socket_nonblocking(int);
+int levent_make_socket_blocking(int);
+#ifdef HOST_OS_LINUX
+void levent_recv_error(int, const char*);
+#endif
/* lldp.c */
+int lldp_send_shutdown(PROTO_SEND_SIG);
int lldp_send(PROTO_SEND_SIG);
int lldp_decode(PROTO_DECODE_SIG);
#ifdef USE_SNMP
/* agent.c */
void agent_shutdown(void);
-void agent_init(struct lldpd *, char *);
+void agent_init(struct lldpd *, const char *);
void agent_notify(struct lldpd_hardware *, int, struct lldpd_port *);
#endif
+#ifdef ENABLE_PRIVSEP
/* agent_priv.c */
void agent_priv_register_domain(void);
+#endif
/* client.c */
int
int*);
/* priv.c */
-void priv_init(char*, int, uid_t, gid_t);
-void priv_ctl_cleanup(void);
-char *priv_gethostbyname(void);
+void priv_init(const char*, int, uid_t, gid_t);
+void priv_wait(void);
+void priv_ctl_cleanup(const char *ctlname);
+char *priv_gethostname(void);
#ifdef HOST_OS_LINUX
int priv_open(char*);
-int priv_ethtool(char*, void*, size_t);
+void asroot_open(void);
#endif
-int priv_iface_init(int);
-int priv_iface_multicast(const char *, u_int8_t *, int);
+int priv_iface_init(int, char *);
+int asroot_iface_init_os(int, char *, int *);
+int priv_iface_multicast(const char *, const u_int8_t *, int);
+int priv_iface_description(const char *, const char *);
+int asroot_iface_description_os(const char *, const char *);
+int priv_iface_promisc(const char*);
+int asroot_iface_promisc_os(const char *);
int priv_snmp_socket(struct sockaddr_un *);
-/* privsep_fdpass.c */
-int receive_fd(int);
-void send_fd(int, int);
+enum priv_cmd {
+ PRIV_PING,
+ PRIV_DELETE_CTL_SOCKET,
+ PRIV_GET_HOSTNAME,
+ PRIV_OPEN,
+ PRIV_IFACE_INIT,
+ PRIV_IFACE_MULTICAST,
+ PRIV_IFACE_DESCRIPTION,
+ PRIV_IFACE_PROMISC,
+ PRIV_SNMP_SOCKET,
+};
+
+/* priv-seccomp.c */
+#if defined USE_SECCOMP && defined ENABLE_PRIVSEP
+int priv_seccomp_init(int, int);
+#endif
+
+/* privsep_io.c */
+enum priv_context {
+ PRIV_PRIVILEGED,
+ PRIV_UNPRIVILEGED
+};
+int may_read(enum priv_context, void *, size_t);
+void must_read(enum priv_context, void *, size_t);
+void must_write(enum priv_context, const void *, size_t);
+void priv_privileged_fd(int);
+void priv_unprivileged_fd(int);
+int priv_fd(enum priv_context);
+int receive_fd(enum priv_context);
+void send_fd(enum priv_context, int);
/* interfaces-*.c */
first byte is 1. if not, this can only be an EDP packet:
tcpdump -dd "(ether[0] & 1 = 1 and
- ((ether proto 0x88cc and ether dst 01:80:c2:00:00:0e) or
+ ((ether proto 0x88cc and (ether dst 01:80:c2:00:00:0e or
+ ether dst 01:80:c2:00:00:03 or
+ ether dst 01:80:c2:00:00:00)) or
(ether dst 01:e0:52:cc:cc:cc) or
(ether dst 01:00:0c:cc:cc:cc) or
(ether dst 01:00:81:00:01:00))) or
#define LLDPD_FILTER_F \
{ 0x30, 0, 0, 0x00000000 }, \
{ 0x54, 0, 0, 0x00000001 }, \
- { 0x15, 0, 14, 0x00000001 }, \
+ { 0x15, 0, 16, 0x00000001 }, \
{ 0x28, 0, 0, 0x0000000c }, \
- { 0x15, 0, 4, 0x000088cc }, \
+ { 0x15, 0, 6, 0x000088cc }, \
{ 0x20, 0, 0, 0x00000002 }, \
- { 0x15, 0, 2, 0xc200000e }, \
+ { 0x15, 2, 0, 0xc200000e }, \
+ { 0x15, 1, 0, 0xc2000003 }, \
+ { 0x15, 0, 2, 0xc2000000 }, \
{ 0x28, 0, 0, 0x00000000 }, \
{ 0x15, 12, 13, 0x00000180 }, \
{ 0x20, 0, 0, 0x00000002 }, \
{ 0x15, 0, 3, 0x2b000000 }, \
{ 0x28, 0, 0, 0x00000000 }, \
{ 0x15, 0, 1, 0x000000e0 }, \
- { 0x6, 0, 0, 0x0000ffff }, \
- { 0x6, 0, 0, 0x00000000 },
+ { 0x6, 0, 0, 0x00040000 }, \
+ { 0x6, 0, 0, 0x00000000 }
/* This function is responsible to refresh information about interfaces. It is
* OS specific but should be present for each OS. It can use the functions in
#define IFACE_WIRELESS_T (1 << 4) /* Wireless interface */
struct interfaces_device {
TAILQ_ENTRY(interfaces_device) next;
+ int ignore; /* Ignore this interface */
int index; /* Index */
char *name; /* Name */
char *alias; /* Alias */
#ifdef HOST_OS_LINUX
int lower_idx; /* Index to lower interface */
int upper_idx; /* Index to upper interface */
- int txqueue; /* Transmit queue length */
#endif
};
struct interfaces_address {
struct interfaces_device_list *,
const char *);
+void interfaces_helper_promisc(struct lldpd *,
+ struct lldpd_hardware *);
void interfaces_helper_whitelist(struct lldpd *,
struct interfaces_device_list *);
void interfaces_helper_chassis(struct lldpd *,
struct interfaces_device_list *);
+void interfaces_helper_add_hardware(struct lldpd *,
+ struct lldpd_hardware *);
void interfaces_helper_physical(struct lldpd *,
struct interfaces_device_list *,
struct lldpd_ops *,
int(*init)(struct lldpd *, struct lldpd_hardware *));
-void interfaces_helper_port_name_desc(struct lldpd_hardware *,
+void interfaces_helper_port_name_desc(struct lldpd *,
+ struct lldpd_hardware *,
struct interfaces_device *);
void interfaces_helper_mgmt(struct lldpd *,
struct interfaces_address_list *);
void interfaces_helper_vlan(struct lldpd *,
struct interfaces_device_list *);
#endif
+int interfaces_send_helper(struct lldpd *,
+ struct lldpd_hardware *, char *, size_t);
void interfaces_setup_multicast(struct lldpd *, const char *, int);
+int interfaces_routing_enabled(struct lldpd *);
+void interfaces_cleanup(struct lldpd *);
#ifdef HOST_OS_LINUX
/* netlink.c */
-struct interfaces_device_list *netlink_get_interfaces(void);
-struct interfaces_address_list *netlink_get_addresses(void);
-int netlink_subscribe_changes(void);
+struct interfaces_device_list *netlink_get_interfaces(struct lldpd *);
+struct interfaces_address_list *netlink_get_addresses(struct lldpd *);
+void netlink_cleanup(struct lldpd *);
+struct lldpd_netlink;
#endif
+#ifndef HOST_OS_LINUX
+int ifbpf_phys_init(struct lldpd *, struct lldpd_hardware *);
+#endif
+
+/* pattern.c */
+int pattern_match(char *, char *, int);
+
+struct lldpd {
+ int g_sock;
+ struct event_base *g_base;
+#ifdef USE_SNMP
+#endif
+
+ struct lldpd_config g_config;
+
+ struct protocol *g_protocols;
+ int g_lastrid;
+ struct event *g_main_loop;
+ struct event *g_cleanup_timer;
+#ifdef USE_SNMP
+ int g_snmp;
+ struct event *g_snmp_timeout;
+ void *g_snmp_fds;
+ const char *g_snmp_agentx;
+#endif /* USE_SNMP */
+
+ /* Unix socket handling */
+ const char *g_ctlname;
+ int g_ctl;
+ struct event *g_iface_event; /* Triggered when there is an interface change */
+ struct event *g_iface_timer_event; /* Triggered one second after last interface change */
+ void(*g_iface_cb)(struct lldpd *); /* Called when there is an interface change */
+
+ char *g_lsb_release;
+
+#ifdef HOST_OS_LINUX
+ struct lldpd_netlink *g_netlink;
+#endif
+
+ struct lldpd_port *g_default_local_port;
+#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
+ TAILQ_HEAD(, lldpd_chassis) g_chassis;
+ TAILQ_HEAD(, lldpd_hardware) g_hardware;
+};
+
#endif /* _LLDPD_H */