]> git.ipfire.org Git - thirdparty/lldpd.git/blobdiff - src/lldpd.c
Lower log level for problem when getting bridge info
[thirdparty/lldpd.git] / src / lldpd.c
index 661432ff4bc90fb0db8500bfcc5b0cbd7e10f981..27a4bbcb83cc3de148085d5b5074763fcf6738bf 100644 (file)
 #include <net-snmp/agent/snmp_vars.h>
 #endif /* USE_SNMP */
 
-void            usage(void);
+static void             usage(void);
 
-int                     lldpd_iface_init(struct lldpd *, struct lldpd_hardware *);
-int                     lldpd_iface_init_vlan(struct lldpd *, struct lldpd_vif *);
-void                    lldpd_iface_init_mtu(struct lldpd *, struct lldpd_hardware *);
-int                     lldpd_iface_close(struct lldpd *, struct lldpd_hardware *);
-void                    lldpd_iface_multicast(struct lldpd *, const char *, int);
+static int              lldpd_iface_init(struct lldpd *, struct lldpd_hardware *);
+static int              lldpd_iface_init_vlan(struct lldpd *, struct lldpd_vif *);
+static void             lldpd_iface_init_mtu(struct lldpd *, struct lldpd_hardware *);
+static int              lldpd_iface_close(struct lldpd *, struct lldpd_hardware *);
+static void             lldpd_iface_multicast(struct lldpd *, const char *, int);
 
 /* "ether proto 0x88cc and ether dst 01:80:c2:00:00:0e" */
 #define LLDPD_FILTER_LLDP_F                                            \
@@ -64,7 +64,7 @@ void                   lldpd_iface_multicast(struct lldpd *, const char *, int);
         { 0x15, 0, 1, 0x00000180 },                                    \
         { 0x6, 0, 0, 0x0000ffff },                                     \
         { 0x6, 0, 0, 0x00000000 },
-struct sock_filter lldpd_filter_lldp_f[] = { LLDPD_FILTER_LLDP_F };
+static struct sock_filter lldpd_filter_lldp_f[] = { LLDPD_FILTER_LLDP_F };
 #ifdef ENABLE_FDP
 /* "ether dst 01:e0:52:cc:cc:cc" */
 #define LLDPD_FILTER_FDP_F                     \
@@ -74,7 +74,7 @@ struct sock_filter lldpd_filter_lldp_f[] = { LLDPD_FILTER_LLDP_F };
         { 0x15, 0, 1, 0x000001e0 },            \
         { 0x6, 0, 0, 0x0000ffff },             \
         { 0x6, 0, 0, 0x00000000 },
-struct sock_filter lldpd_filter_fdp_f[] = { LLDPD_FILTER_FDP_F };
+static struct sock_filter lldpd_filter_fdp_f[] = { LLDPD_FILTER_FDP_F };
 #endif /* ENABLE_FDP */
 #ifdef ENABLE_CDP
 /* "ether dst 01:00:0c:cc:cc:cc" */
@@ -85,7 +85,7 @@ struct sock_filter lldpd_filter_fdp_f[] = { LLDPD_FILTER_FDP_F };
         { 0x15, 0, 1, 0x00000100 },            \
         { 0x6, 0, 0, 0x0000ffff },             \
         { 0x6, 0, 0, 0x00000000 },
-struct sock_filter lldpd_filter_cdp_f[] = { LLDPD_FILTER_CDP_F };
+static struct sock_filter lldpd_filter_cdp_f[] = { LLDPD_FILTER_CDP_F };
 #endif /* ENABLE_CDP */
 #ifdef ENABLE_SONMP
 /* "ether dst 01:00:81:00:01:00" */
@@ -96,7 +96,7 @@ struct sock_filter lldpd_filter_cdp_f[] = { LLDPD_FILTER_CDP_F };
         { 0x15, 0, 1, 0x00000100 },            \
         { 0x6, 0, 0, 0x0000ffff },             \
         { 0x6, 0, 0, 0x00000000 },
-struct sock_filter lldpd_filter_sonmp_f[] = { LLDPD_FILTER_SONMP_F };
+static struct sock_filter lldpd_filter_sonmp_f[] = { LLDPD_FILTER_SONMP_F };
 #endif /* ENABLE_SONMP */
 #ifdef ENABLE_EDP
 /* "ether dst 00:e0:2b:00:00:00" */
@@ -107,8 +107,8 @@ struct sock_filter lldpd_filter_sonmp_f[] = { LLDPD_FILTER_SONMP_F };
        { 0x15, 0, 1, 0x000000e0 },     \
        { 0x6, 0, 0, 0x0000ffff },      \
        { 0x6, 0, 0, 0x00000000 },
+static struct sock_filter lldpd_filter_edp_f[] = { LLDPD_FILTER_EDP_F };
 #endif /* ENABLE_EDP */
-struct sock_filter lldpd_filter_edp_f[] = { LLDPD_FILTER_EDP_F };
 #define LLDPD_FILTER_ANY_F             \
        { 0x28, 0, 0, 0x0000000c },     \
        { 0x15, 0, 4, 0x000088cc },     \
@@ -129,9 +129,9 @@ struct sock_filter lldpd_filter_edp_f[] = { LLDPD_FILTER_EDP_F };
        { 0x15, 0, 1, 0x000001e0 },     \
        { 0x6, 0, 0, 0x0000ffff },      \
        { 0x6, 0, 0, 0x00000000 },
-struct sock_filter lldpd_filter_any_f[] = { LLDPD_FILTER_ANY_F };
+static struct sock_filter lldpd_filter_any_f[] = { LLDPD_FILTER_ANY_F };
 
-struct protocol protos[] =
+static struct protocol protos[] =
 {
        { LLDPD_MODE_LLDP, 1, "LLDP", ' ', lldp_send, lldp_decode, NULL,
          LLDP_MULTICAST_ADDR, lldpd_filter_lldp_f, sizeof(lldpd_filter_lldp_f) },
@@ -157,24 +157,25 @@ struct protocol protos[] =
          {0,0,0,0,0,0}, lldpd_filter_any_f, sizeof(lldpd_filter_any_f) }
 };
 
-int                     lldpd_iface_switchto(struct lldpd *, short int,
+static int              lldpd_iface_switchto(struct lldpd *, short int,
                            struct lldpd_hardware *);
+static
 struct lldpd_hardware  *lldpd_port_add(struct lldpd *, struct ifaddrs *);
-void                    lldpd_loop(struct lldpd *);
-void                    lldpd_shutdown(int);
-void                    lldpd_exit();
-void                    lldpd_send_all(struct lldpd *);
-void                    lldpd_recv_all(struct lldpd *);
-int                     lldpd_guess_type(struct lldpd *, char *, int);
-void                    lldpd_decode(struct lldpd *, char *, int,
+static void             lldpd_loop(struct lldpd *);
+static void             lldpd_shutdown(int);
+static void             lldpd_exit();
+static void             lldpd_send_all(struct lldpd *);
+static void             lldpd_recv_all(struct lldpd *);
+static int              lldpd_guess_type(struct lldpd *, char *, int);
+static void             lldpd_decode(struct lldpd *, char *, int,
                            struct lldpd_hardware *, int);
 #ifdef ENABLE_LLDPMED
-void                    lldpd_med(struct lldpd_chassis *);
+static void             lldpd_med(struct lldpd_chassis *);
 #endif
 
-char   **saved_argv;
+static char            **saved_argv;
 
-void
+static void
 usage(void)
 {
        extern const char       *__progname;
@@ -183,7 +184,7 @@ usage(void)
        exit(1);
 }
 
-void
+static void
 lldpd_iface_init_mtu(struct lldpd *global, struct lldpd_hardware *hardware)
 {
        struct ifreq ifr;
@@ -195,10 +196,10 @@ lldpd_iface_init_mtu(struct lldpd *global, struct lldpd_hardware *hardware)
                LLOG_WARN("unable to get MTU of %s, using 1500", hardware->h_ifname);
                hardware->h_mtu = 1500;
        } else
-               hardware->h_mtu = ifr.ifr_mtu;
+               hardware->h_mtu = hardware->h_lport.p_mfs = ifr.ifr_mtu;
 }
 
-int
+static int
 lldpd_iface_init_vlan(struct lldpd *global, struct lldpd_vif *vif)
 {
        int status;
@@ -227,7 +228,7 @@ lldpd_iface_init_vlan(struct lldpd *global, struct lldpd_vif *vif)
        return 0;
 }
 
-int
+static int
 lldpd_iface_init(struct lldpd *global, struct lldpd_hardware *hardware)
 {
        int master;             /* Bond device */
@@ -277,7 +278,7 @@ lldpd_iface_init(struct lldpd *global, struct lldpd_hardware *hardware)
        return 0;
 }
 
-void
+static void
 lldpd_iface_multicast(struct lldpd *global, const char *name, int remove)
 {
        int i, rc;
@@ -296,7 +297,7 @@ lldpd_iface_multicast(struct lldpd *global, const char *name, int remove)
        }
 }
 
-int
+static int
 lldpd_iface_close(struct lldpd *global, struct lldpd_hardware *hardware)
 {
        char listen[IFNAMSIZ];
@@ -320,7 +321,7 @@ lldpd_iface_close(struct lldpd *global, struct lldpd_hardware *hardware)
        return 0;
 }
 
-int
+static int
 lldpd_iface_switchto(struct lldpd *cfg, short int filter, struct lldpd_hardware *hardware)
 {
        struct sock_fprog prog;
@@ -367,6 +368,11 @@ lldpd_vlan_cleanup(struct lldpd_port *port)
 void
 lldpd_port_cleanup(struct lldpd_port *port)
 {
+#ifdef ENABLE_LLDPMED
+       int i;
+       for (i=0; i < LLDPMED_LOCFORMAT_LAST; i++)
+               free(port->p_med_location[i].data);
+#endif
 #ifdef ENABLE_DOT1
        lldpd_vlan_cleanup(port);
 #endif
@@ -458,7 +464,7 @@ lldpd_cleanup(struct lldpd *cfg)
        }
 }
 
-struct lldpd_vif *
+static struct lldpd_vif *
 lldpd_port_add_vlan(struct lldpd *cfg, struct ifaddrs *ifa)
 {
        struct lldpd_vif *vif;
@@ -512,7 +518,7 @@ lldpd_port_add_vlan(struct lldpd *cfg, struct ifaddrs *ifa)
        return vif;
 }
 
-struct lldpd_hardware *
+static struct lldpd_hardware *
 lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
 {
 #if defined (ENABLE_DOT1) || defined (ENABLE_DOT3)
@@ -542,6 +548,11 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
                hardware->h_raw_real = -1;
                hardware->h_start_probe = 0;
                hardware->h_proto_macs = (u_int8_t*)calloc(cfg->g_multi+1, ETH_ALEN);
+#ifdef ENABLE_LLDPMED
+               hardware->h_lport.p_med_cap_enabled = LLDPMED_CAP_CAP;
+               if (!cfg->g_noinventory)
+                       hardware->h_lport.p_med_cap_enabled |= LLDPMED_CAP_IV;
+#endif
 #ifdef ENABLE_DOT1
                TAILQ_INIT(&hardware->h_lport.p_vlans);
        } else {
@@ -555,6 +566,7 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
        strlcpy(hardware->h_ifname, ifa->ifa_name, sizeof(hardware->h_ifname));
        lladdr = (u_int8_t*)(((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr);
        memcpy(&hardware->h_lladdr, lladdr, sizeof(hardware->h_lladdr));
+       iface_get_permanent_mac(cfg, hardware);
        port->p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR;
        if ((port->p_id = calloc(1, sizeof(hardware->h_lladdr))) == NULL)
                fatal(NULL);
@@ -698,7 +710,7 @@ lldpd_port_add(struct lldpd *cfg, struct ifaddrs *ifa)
        return (hardware);
 }
 
-int
+static int
 lldpd_guess_type(struct lldpd *cfg, char *frame, int s)
 {
        int i;
@@ -718,7 +730,7 @@ lldpd_guess_type(struct lldpd *cfg, char *frame, int s)
        return -1;
 }
 
-void
+static void
 lldpd_decode(struct lldpd *cfg, char *frame, int s,
     struct lldpd_hardware *hardware, int bond)
 {
@@ -966,7 +978,7 @@ cleanup:
        return;
 }
 
-void
+static void
 lldpd_recv_all(struct lldpd *cfg)
 {
        struct lldpd_hardware *hardware;
@@ -997,7 +1009,8 @@ lldpd_recv_all(struct lldpd *cfg)
                
                TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
                        /* Ignore if interface is down */
-                       if ((hardware->h_flags & IFF_UP) == 0)
+                       if (((hardware->h_flags & IFF_UP) == 0) ||
+                           ((hardware->h_flags & IFF_RUNNING) == 0))
                                continue;
                        FD_SET(hardware->h_raw, &rfds);
                        if (nfds < hardware->h_raw)
@@ -1011,7 +1024,8 @@ lldpd_recv_all(struct lldpd *cfg)
                        }
                }
                TAILQ_FOREACH(vif, &cfg->g_vif, vif_entries) {
-                       if ((vif->vif_flags & IFF_UP) == 0)
+                       if (((vif->vif_flags & IFF_UP) == 0) ||
+                           ((vif->vif_flags & IFF_RUNNING) == 0))
                                continue;
                        FD_SET(vif->vif_raw, &rfds);
                        if (nfds < vif->vif_raw)
@@ -1175,30 +1189,7 @@ lldpd_recv_all(struct lldpd *cfg)
        } while ((rc != 0) || (time(NULL) - cfg->g_lastsent < cfg->g_delay));
 }
 
-void static
-get_random_ether(u_int8_t *lladdr)
-{
-       /* We use a simple law to generate random bytes of the MAC address and
-        * initialize (or re-initialize) the seed using microseconds part of
-        * gettimeofday. */
-       static u_int64_t next = 0;
-       u_int8_t random;
-       int i = 0;
-       struct timeval tv;
-       if (next == 0) {
-               gettimeofday(&tv, NULL);
-               next = tv.tv_usec;
-       }
-       do {
-               next = next * 1103515245 + 12345;
-               random = (next/65536)%256;
-               memcpy(lladdr + i, &random, 1);
-       } while (++i < ETHER_ADDR_LEN);
-       lladdr[0] &= 0xfe;      /* clear multicast bit */
-       lladdr[0] |= 0x02;      /* set local assignment bit (IEEE802) */
-}
-
-void
+static void
 lldpd_send_all(struct lldpd *cfg)
 {
        struct lldpd_hardware *hardware;
@@ -1208,17 +1199,18 @@ lldpd_send_all(struct lldpd *cfg)
        cfg->g_lastsent = time(NULL);
        TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
                /* Ignore if interface is down */
-               if ((hardware->h_flags & IFF_UP) == 0)
+               if (((hardware->h_flags & IFF_UP) == 0) ||
+                   ((hardware->h_flags & IFF_RUNNING) == 0))
                        continue;
 
-               /* When sending on inactive slaves, just send using a random address */
+               /* When sending on inactive slaves, just send using a 0:0:0:0:0:0 address */
                altermac = 0;
                if ((hardware->h_raw_real > 0) &&
                    (!iface_is_slave_active(cfg, hardware->h_master,
                        hardware->h_ifname))) {
                        altermac = 1;
                        memcpy(saved_lladdr, hardware->h_lladdr, ETHER_ADDR_LEN);
-                       get_random_ether(hardware->h_lladdr);
+                       memset(hardware->h_lladdr, 0, ETHER_ADDR_LEN);
                }
 
                for (i=0; cfg->g_protocols[i].mode != 0; i++) {
@@ -1235,7 +1227,7 @@ lldpd_send_all(struct lldpd *cfg)
 }
 
 #ifdef ENABLE_LLDPMED
-void
+static void
 lldpd_med(struct lldpd_chassis *chassis)
 {
        free(chassis->c_med_hw);
@@ -1253,7 +1245,7 @@ lldpd_med(struct lldpd_chassis *chassis)
 }
 #endif
 
-void
+static void
 lldpd_loop(struct lldpd *cfg)
 {
        struct ifaddrs *ifap, *ifa;
@@ -1381,7 +1373,7 @@ lldpd_loop(struct lldpd *cfg)
        lldpd_recv_all(cfg);
 }
 
-void
+static void
 lldpd_shutdown(int sig)
 {
        LLOG_INFO("signal received, exiting");
@@ -1389,9 +1381,9 @@ lldpd_shutdown(int sig)
 }
 
 /* For signal handling */
-struct lldpd *gcfg = NULL;
+static struct lldpd *gcfg = NULL;
 
-void
+static void
 lldpd_exit()
 {
        struct lldpd_hardware *hardware;
@@ -1449,26 +1441,25 @@ main(int argc, char *argv[])
                case 'm':
                        mgmtp = optarg;
                        break;
-               case 'M':
 #ifdef ENABLE_LLDPMED
+               case 'M':
                        lldpmed = atoi(optarg);
                        if ((lldpmed < 1) || (lldpmed > 4)) {
                                fprintf(stderr, "-M requires an argument between 1 and 4\n");
                                usage();
                        }
-#else
-                       fprintf(stderr, "LLDP-MED support is not built-in\n");
-                       usage();
-#endif
                        break;
                case 'i':
-#ifdef ENABLE_LLDPMED
                        noinventory = 1;
+                       break;
 #else
+               case 'M':
+               case 'i':
+               case 'P':
                        fprintf(stderr, "LLDP-MED support is not built-in\n");
                        usage();
-#endif
                        break;
+#endif
                case 'p':
                        probe = atoi(optarg);
                        break;
@@ -1493,7 +1484,7 @@ main(int argc, char *argv[])
                                usage();
                }
        }
-
+       
        log_init(debug);
 
        if (!debug) {
@@ -1536,10 +1527,9 @@ main(int argc, char *argv[])
                if (lldpmed == LLDPMED_CLASS_III)
                        cfg->g_lchassis.c_cap_available |= LLDP_CAP_TELEPHONE;
                cfg->g_lchassis.c_med_type = lldpmed;
-               cfg->g_lchassis.c_med_cap = LLDPMED_CAP_CAP;
-               if (!noinventory)
-                       cfg->g_lchassis.c_med_cap |= LLDPMED_CAP_IV;
-               cfg->g_med_noinventory = noinventory;
+               cfg->g_lchassis.c_med_cap_available = LLDPMED_CAP_CAP |
+                   LLDPMED_CAP_IV | LLDPMED_CAP_LOCATION;
+               cfg->g_noinventory = noinventory;
        }
 #endif