]> git.ipfire.org Git - thirdparty/lldpd.git/blobdiff - src/lldpd.h
Allow to specify the AgentX socket to use (instead of the default one).
[thirdparty/lldpd.git] / src / lldpd.h
index ab650071d69642b180a5361ace18c57fbec333a1..aa26938f520ab85acc21377c39bb5d226a8587fb 100644 (file)
 #define _LLDPD_H
 
 #if HAVE_CONFIG_H
- #include <config.h>
+#  include <config.h>
 #endif
 
 #define _GNU_SOURCE 1
 #include <stdlib.h>
 #include <string.h>
 #include <sys/queue.h>
+#ifdef HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
 #ifndef INCLUDE_LINUX_IF_H
-#include <net/if.h>
+#  include <net/if.h>
 #else
-#include <arpa/inet.h>
-#include <linux/if.h>
+#  include <arpa/inet.h>
+#  include <linux/if.h>
+#endif
+#if HAVE_GETIFADDRS
+#  include <ifaddrs.h>
 #endif
 #include <net/ethernet.h>
 #include <netinet/in.h>
 #include <linux/ethtool.h>
+#include <sys/un.h>
 
 #include "compat.h"
 #include "lldp.h"
 #if defined (ENABLE_CDP) || defined (ENABLE_FDP)
-#include "cdp.h"
+#  include "cdp.h"
 #endif
 #ifdef ENABLE_SONMP
-#include "sonmp.h"
+#  include "sonmp.h"
 #endif
 #ifdef ENABLE_EDP
-#include "edp.h"
+#  include "edp.h"
 #endif
 
 #define SYSFS_CLASS_NET "/sys/class/net/"
@@ -65,10 +72,33 @@ struct lldpd_vlan {
        char                    *v_name;
        u_int16_t                v_vid;
 };
-#define STRUCT_LLDPD_VLAN "Lsw"
+#define STRUCT_LLDPD_VLAN "(Lsw)"
+#endif
+
+#ifdef ENABLE_LLDPMED
+#define STRUCT_LLDPD_MED_POLICY "(bbbwbb)"
+struct lldpd_med_policy {
+       u_int8_t                 type;
+       u_int8_t                 unknown;
+       u_int8_t                 tagged;
+       u_int16_t                vid;
+       u_int8_t                 priority;
+       u_int8_t                 dscp;
+};
+
+#define STRUCT_LLDPD_MED_LOC "(bC)"
+struct lldpd_med_loc {
+       u_int8_t                 format;
+       char                    *data;
+       int                      data_len;
+};
 #endif
 
 struct lldpd_chassis {
+       TAILQ_ENTRY(lldpd_chassis) c_entries;
+       u_int16_t                c_refcount; /* Reference count by ports */
+       u_int16_t                c_index;    /* Monotonic index */
+       u_int8_t                 c_protocol; /* Protocol used to get this chassis */
        u_int8_t                 c_id_subtype;
        char                    *c_id;
        int                      c_id_len;
@@ -84,7 +114,8 @@ struct lldpd_chassis {
        u_int32_t                c_mgmt_if;
 
 #ifdef ENABLE_LLDPMED
-       u_int16_t                c_med_cap;
+#define STRUCT_LLDPD_CHASSIS_MED "wbsssssss"
+       u_int16_t                c_med_cap_available;
        u_int8_t                 c_med_type;
        char                    *c_med_hw;
        char                    *c_med_fw;
@@ -93,74 +124,113 @@ struct lldpd_chassis {
        char                    *c_med_manuf;
        char                    *c_med_model;
        char                    *c_med_asset;
-#endif
-
-};
-#ifdef ENABLE_LLDPMED
-#define STRUCT_LLDPD_CHASSIS_MED "wbsssssss"
 #else
 #define STRUCT_LLDPD_CHASSIS_MED ""
 #endif
-#define STRUCT_LLDPD_CHASSIS "bCsswwwll" STRUCT_LLDPD_CHASSIS_MED
+
+};
+#define STRUCT_LLDPD_CHASSIS "(LwwbbCsswwwll" STRUCT_LLDPD_CHASSIS_MED ")"
 
 struct lldpd_port {
+       TAILQ_ENTRY(lldpd_port)  p_entries;
+       struct lldpd_chassis    *p_chassis;    /* Attached chassis */
+       time_t                   p_lastchange; /* Time of last change of values */
+       time_t                   p_lastupdate; /* Time of last update received */
+       struct lldpd_frame      *p_lastframe;  /* Frame received during last update */
+       u_int8_t                 p_protocol;   /* Protocol used to get this port */
        u_int8_t                 p_id_subtype;
        char                    *p_id;
        int                      p_id_len;
        char                    *p_descr;
+       u_int16_t                p_mfs;
 
 #ifdef ENABLE_DOT3
+#define STRUCT_LLDPD_PORT_DOT3 "lbbww"
        /* Dot3 stuff */
        u_int32_t                p_aggregid;
        u_int8_t                 p_autoneg_support;
        u_int8_t                 p_autoneg_enabled;
        u_int16_t                p_autoneg_advertised;
        u_int16_t                p_mau_type;
+#else
+#define STRUCT_LLDPD_PORT_DOT3 ""
 #endif
 
-#ifdef ENABLE_DOT1
-       TAILQ_HEAD(, lldpd_vlan) p_vlans;
-#endif
-};
-
-#ifdef ENABLE_DOT3
-#define STRUCT_LLDPD_PORT_DOT3 "lbbww"
+#ifdef ENABLE_LLDPMED
+#define STRUCT_LLDPD_PORT_MED "w"      \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_POLICY        \
+       STRUCT_LLDPD_MED_LOC           \
+       STRUCT_LLDPD_MED_LOC           \
+       STRUCT_LLDPD_MED_LOC           \
+       "bbbw"
+       u_int16_t                p_med_cap_enabled;
+       struct lldpd_med_policy  p_med_policy[LLDPMED_APPTYPE_LAST];
+       struct lldpd_med_loc     p_med_location[LLDPMED_LOCFORMAT_LAST];
+       u_int8_t                 p_med_pow_devicetype; /* PD or PSE */
+       u_int8_t                 p_med_pow_source;
+       u_int8_t                 p_med_pow_priority;
+       u_int16_t                p_med_pow_val;
 #else
-#define STRUCT_LLDPD_PORT_DOT3 ""
+#define STRUCT_LLDPD_PORT_MED ""
 #endif
+
 #ifdef ENABLE_DOT1
-#define STRUCT_LLDPD_PORT_DOT1 "PP"
+#define STRUCT_LLDPD_PORT_DOT1 "wPP"
+       u_int16_t                p_pvid;
+       TAILQ_HEAD(, lldpd_vlan) p_vlans;
 #else
 #define STRUCT_LLDPD_PORT_DOT1 ""
 #endif
-#define STRUCT_LLDPD_PORT "bCs" STRUCT_LLDPD_PORT_DOT3 STRUCT_LLDPD_PORT_DOT1
+};
+
+#define STRUCT_LLDPD_PORT "(LPttPbbCsw"                                \
+       STRUCT_LLDPD_PORT_DOT3                                  \
+       STRUCT_LLDPD_PORT_MED                                   \
+       STRUCT_LLDPD_PORT_DOT1 ")"
 
 struct lldpd_frame {
        int size;
-       unsigned char frame[];
+       unsigned char frame[1];
+};
+
+struct lldpd_hardware;
+struct lldpd;
+struct lldpd_ops {
+       int(*send)(struct lldpd *,
+                  struct lldpd_hardware*,
+                  char *, size_t); /* Function to send a frame */
+       int(*recv)(struct lldpd *,
+                  struct lldpd_hardware*,
+                  int, char *, size_t); /* Function to receive a frame */
+       int(*cleanup)(struct lldpd *, struct lldpd_hardware *); /* Cleanup function. */
 };
 
+/* An interface is uniquely identified by h_ifindex, h_ifname and h_ops. This
+ * means if an interface becomes enslaved, it will be considered as a new
+ * interface. The same applies for renaming and we include the index in case of
+ * renaming to an existing interface. */
 struct lldpd_hardware {
        TAILQ_ENTRY(lldpd_hardware)      h_entries;
 
-#define INTERFACE_OPENED(x) ((x)->h_raw != -1)
-       
-       int                      h_raw;
-       int                      h_raw_real; /* For bonding */
-       int                      h_master;   /* For bonding */
+       fd_set                   h_recvfds; /* FD for reception */
+       int                      h_sendfd;  /* FD for sending, only used by h_ops */
+       struct lldpd_ops        *h_ops;     /* Hardware-dependent functions */
+       void                    *h_data;    /* Hardware-dependent data */
 
-#define LLDPD_MODE_ANY 0
-#define LLDPD_MODE_LLDP 1
-#define LLDPD_MODE_CDPV1 2
-#define LLDPD_MODE_CDPV2 3
-#define LLDPD_MODE_SONMP 4
-#define LLDPD_MODE_EDP 5
-#define LLDPD_MODE_FDP 6
-       int                      h_mode;
-
-       int                      h_flags;
        int                      h_mtu;
-       char                     h_ifname[IFNAMSIZ];
+       int                      h_flags; /* Packets will be sent only
+                                            if IFF_RUNNING. Will be
+                                            removed if this is left
+                                            to 0. */
+       int                      h_ifindex; /* Interface index, used by SNMP */
+       char                     h_ifname[IFNAMSIZ]; /* Should be unique */
        u_int8_t                 h_lladdr[ETHER_ADDR_LEN];
 
        u_int64_t                h_tx_cnt;
@@ -169,53 +239,27 @@ struct lldpd_hardware {
        u_int64_t                h_rx_ageout_cnt;
        u_int64_t                h_rx_unrecognized_cnt;
 
-       u_int8_t                *h_proto_macs;
-       time_t                   h_start_probe;
-
-       struct lldpd_port        h_lport;
-       time_t                   h_llastchange;
-       struct lldpd_frame      *h_llastframe;
-
-       time_t                   h_rlastchange;
-       time_t                   h_rlastupdate;
-       int                      h_rid;
-       struct lldpd_frame      *h_rlastframe;
-       struct lldpd_port       *h_rport;
-       struct lldpd_chassis    *h_rchassis;
-};
-
-/* lldpd_vif can be casted to lldpd_hardware on some cases */
-struct lldpd_vif {
-       TAILQ_ENTRY(lldpd_vif)   vif_entries;
-       int                      vif_raw;
-       int                      vif_raw_real; /* Not used */
-       int                      vif_master;   /* Not used */
-       int                      vif_mode;     /* Not used */
-       int                      vif_flags;
-       int                      vif_mtu;
-       char                     vif_ifname[IFNAMSIZ];
-
-       /* No more compatibility with struct lldpd_hardware from here */
-       struct lldpd_hardware   *vif_real;
+       struct lldpd_port        h_lport;  /* Port attached to this hardware port */
+       TAILQ_HEAD(, lldpd_port) h_rports; /* Remote ports */
 };
 
 struct lldpd_interface {
        TAILQ_ENTRY(lldpd_interface) next;
        char                    *name;
 };
-#define STRUCT_LLDPD_INTERFACE "Ls"
+#define STRUCT_LLDPD_INTERFACE "(Ls)"
 
-struct lldpd_client {
-       TAILQ_ENTRY(lldpd_client) next;
-       int fd;
-};
-
-#define PROTO_SEND_SIG struct lldpd *, struct lldpd_chassis *, struct lldpd_hardware *
+#define PROTO_SEND_SIG struct lldpd *, struct lldpd_hardware *
 #define PROTO_DECODE_SIG struct lldpd *, char *, int, struct lldpd_hardware *, struct lldpd_chassis **, struct lldpd_port **
 #define PROTO_GUESS_SIG char *, int
 
-struct lldpd;
 struct protocol {
+#define LLDPD_MODE_LLDP 1
+#define LLDPD_MODE_CDPV1 2
+#define LLDPD_MODE_CDPV2 3
+#define LLDPD_MODE_SONMP 4
+#define LLDPD_MODE_EDP 5
+#define LLDPD_MODE_FDP 6
        int              mode;          /* > 0 mode identifier (unique per protocol) */
        int              enabled;       /* Is this protocol enabled? */
        char            *name;          /* Name of protocol */
@@ -224,8 +268,14 @@ struct protocol {
        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[ETH_ALEN];  /* Destination MAC address used by this protocol */
-       struct sock_filter *filter;     /* BPF filter */
-       size_t           filterlen;     /* Size of BPF filter */
+};
+
+#define CALLBACK_SIG struct lldpd*, struct lldpd_callback*
+struct lldpd_callback {
+       TAILQ_ENTRY(lldpd_callback) next;
+       int      fd;          /* FD that will trigger this callback */
+       void(*function)(CALLBACK_SIG); /* Function called */
+       void    *data;          /* Optional data for this callback*/
 };
 
 struct lldpd {
@@ -233,9 +283,13 @@ struct lldpd {
        int                      g_delay;
 
        struct protocol         *g_protocols;
-       int                      g_multi; /* Set to 1 if multiple protocols */
-       int                      g_probe_time;
+#ifdef ENABLE_LISTENVLAN
        int                      g_listen_vlans;
+#endif
+#ifdef ENABLE_LLDPMED
+       int                      g_noinventory;
+#endif
+       int                      g_advertise_version;
 
        time_t                   g_lastsent;
        int                      g_lastrid;
@@ -245,22 +299,26 @@ struct lldpd {
 
        /* Unix socket handling */
        int                      g_ctl;
-       TAILQ_HEAD(, lldpd_client) g_clients;
 
-       char                    *g_mgmt_pattern;
+       TAILQ_HEAD(, lldpd_callback) g_callbacks;
 
-       struct lldpd_chassis     g_lchassis;
+       char                    *g_mgmt_pattern;
 
+#define LOCAL_CHASSIS(cfg) ((struct lldpd_chassis *)(TAILQ_FIRST(&cfg->g_chassis)))
+       TAILQ_HEAD(, lldpd_chassis) g_chassis;
        TAILQ_HEAD(, lldpd_hardware) g_hardware;
-       TAILQ_HEAD(, lldpd_vif)  g_vif;
 };
 
+typedef void(*lldpd_ifhandlers)(struct lldpd *, struct ifaddrs *);
+
 enum hmsg_type {
        HMSG_NONE,
        HMSG_GET_INTERFACES,
-       HMSG_GET_CHASSIS,
+       HMSG_GET_NB_PORTS,
        HMSG_GET_PORT,
+       HMSG_GET_CHASSIS,
        HMSG_GET_VLANS,
+       HMSG_SET_LOCATION,
        HMSG_SHUTDOWN
 };
 
@@ -279,13 +337,19 @@ struct hmsg {
 #define MAX_HMSGSIZE           8192
 
 /* lldpd.c */
-void    lldpd_cleanup(struct lldpd *);
+struct lldpd_hardware  *lldpd_get_hardware(struct lldpd *,
+    char *, int, struct lldpd_ops *);
+struct lldpd_hardware  *lldpd_alloc_hardware(struct lldpd *, char *);
+void    lldpd_hardware_cleanup(struct lldpd*, struct lldpd_hardware *);
 #ifdef ENABLE_DOT1
 void    lldpd_vlan_cleanup(struct lldpd_port *);
 #endif
 void    lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
-void    lldpd_port_cleanup(struct lldpd_port *);
-void    lldpd_chassis_cleanup(struct lldpd_chassis *);
+void    lldpd_port_cleanup(struct lldpd_port *, int);
+void    lldpd_chassis_cleanup(struct lldpd_chassis *, int);
+int     lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
+void    lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));
+int     lldpd_main(int, char **);
 
 /* lldp.c */
 int     lldp_send(PROTO_SEND_SIG);
@@ -321,8 +385,7 @@ int  edp_decode(PROTO_DECODE_SIG);
 int     ctl_create(char *);
 int     ctl_connect(char *);
 void    ctl_cleanup(char *);
-int     ctl_accept(struct lldpd *, int);
-int     ctl_close(struct lldpd *, int);
+void    ctl_accept(struct lldpd *, struct lldpd_callback *);
 void    ctl_msg_init(struct hmsg *, enum hmsg_type);
 int     ctl_msg_send(int, struct hmsg *);
 int     ctl_msg_recv(int, struct hmsg *);
@@ -331,50 +394,43 @@ int        ctl_msg_unpack_list(char *, void *, unsigned int, struct hmsg *, void **);
 int     ctl_msg_pack_structure(char *, void *, unsigned int, struct hmsg *, void **);
 int     ctl_msg_unpack_structure(char *, void *, unsigned int, struct hmsg *, void **);
 
-/* features.c */
-int     iface_is_bridge(struct lldpd *, const char *);
-int     iface_is_bridged(struct lldpd *, const char *);
-int     iface_is_wireless(struct lldpd *, const char *);
-int     iface_is_vlan(struct lldpd *, const char *);
-int     iface_is_bond(struct lldpd *, const char *);
-int     iface_is_bond_slave(struct lldpd *,
-           const char *, const char *);
-int     iface_is_enslaved(struct lldpd *, const char *);
+/* interfaces.c */
+void    lldpd_ifh_bond(struct lldpd *, struct ifaddrs *);
+void    lldpd_ifh_eth(struct lldpd *, struct ifaddrs *);
+#ifdef ENABLE_DOT1
+void    lldpd_ifh_vlan(struct lldpd *, struct ifaddrs *);
+#endif
+void    lldpd_ifh_mgmt(struct lldpd *, struct ifaddrs *);
+
+/* dmi.c */
 #ifdef ENABLE_LLDPMED
-char   *dmi_hw();
-char   *dmi_fw();
-char   *dmi_sn();
-char   *dmi_manuf();
-char   *dmi_model();
-char   *dmi_asset();
+char   *dmi_hw(void);
+char   *dmi_fw(void);
+char   *dmi_sn(void);
+char   *dmi_manuf(void);
+char   *dmi_model(void);
+char   *dmi_asset(void);
 #endif
 
 /* log.c */
-void             log_init(int);
-void             log_warn(const char *, ...);
-#define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__, ##__VA_ARGS__)
-void             log_warnx(const char *, ...);
-#define LLOG_WARNX(x,...) log_warnx("%s: " x,  __FUNCTION__, ##__VA_ARGS__)
-void             log_info(const char *, ...);
-#define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__, ##__VA_ARGS__)
-void             log_debug(const char *, ...);
-#define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__, ##__VA_ARGS__)
+void             log_init(int, const char *);
+void             log_warn(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#define LLOG_WARN(x,...) log_warn("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
+void             log_warnx(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#define LLOG_WARNX(x,...) log_warnx("%s: " x,  __FUNCTION__ , ## __VA_ARGS__)
+void             log_info(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#define LLOG_INFO(x,...) log_info("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
+void             log_debug(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+#define LLOG_DEBUG(x,...) log_debug("%s: " x, __FUNCTION__ , ## __VA_ARGS__)
 void             fatal(const char *);
 void             fatalx(const char *);
 
 /* agent.c */
-void            agent_shutdown();
-void            agent_init(struct lldpd *, int);
+void            agent_shutdown(void);
+void            agent_init(struct lldpd *, char *, int);
 
 /* agent_priv.c */
-void            agent_priv_register_domain();
-
-/* strlcpy.c */
-size_t strlcpy(char *, const char *, size_t);
-
-/* iov.c */
-void            iov_dump(struct lldpd_frame **, struct iovec *, int);
-u_int16_t       iov_checksum(struct iovec *, int, int);
+void            agent_priv_register_domain(void);
 
 /* client.c */
 struct client_handle {
@@ -382,26 +438,26 @@ struct client_handle {
        void (*handle)(struct lldpd*, struct hmsg*, struct hmsg*);
 };
 
-void    client_handle_client(struct lldpd *, struct lldpd_client *,
-           char *, int);
+void    client_handle_client(struct lldpd *, struct lldpd_callback *,
+    char *, int);
 void    client_handle_none(struct lldpd *, struct hmsg *,
            struct hmsg *);
 void    client_handle_get_interfaces(struct lldpd *, struct hmsg *,
            struct hmsg *);
-void    client_handle_get_port_related(struct lldpd *, struct hmsg *,
+void    client_handle_port_related(struct lldpd *, struct hmsg *,
            struct hmsg *);
 void    client_handle_shutdown(struct lldpd *, struct hmsg *,
            struct hmsg *);
 
 /* priv.c */
 void    priv_init(char*);
-int     priv_ctl_create();
-void    priv_ctl_cleanup();
-char           *priv_gethostbyname();
+int     priv_ctl_create(void);
+void    priv_ctl_cleanup(void);
+char           *priv_gethostbyname(void);
 int             priv_open(char*);
 int             priv_ethtool(char*, struct ethtool_cmd*);
-int             priv_iface_init(struct lldpd_hardware *, int);
-int     priv_iface_multicast(char *, u_int8_t *, int);
+int             priv_iface_init(const char *);
+int     priv_iface_multicast(const char *, u_int8_t *, int);
 int     priv_snmp_socket(struct sockaddr_un *);
 
 /* privsep_fdpass.c */