From f7db0dd82b3d831de77ae5dfb60f086e782e6053 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Tue, 9 Dec 2008 18:00:39 +0100 Subject: [PATCH] When sending on inactive slaves, use a random MAC address --- src/lldpd.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/lldpd.c b/src/lldpd.c index 9f6dd1f7..f29c9d6b 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -1171,23 +1171,50 @@ 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 lldpd_send_all(struct lldpd *cfg) { struct lldpd_hardware *hardware; - int i; + u_int8_t saved_lladdr[ETHER_ADDR_LEN]; + int i, altermac; + 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) continue; - /* Don't send on inactive slaves */ + + /* When sending on inactive slaves, just send using a random address */ + altermac = 0; if ((hardware->h_raw_real > 0) && (!iface_is_slave_active(cfg, hardware->h_master, hardware->h_ifname))) { - LLOG_DEBUG("%s is inactive, don't send anything", - hardware->h_ifname); - continue; + altermac = 1; + memcpy(saved_lladdr, hardware->h_lladdr, ETHER_ADDR_LEN); + get_random_ether(hardware->h_lladdr); } for (i=0; cfg->g_protocols[i].mode != 0; i++) { @@ -1197,6 +1224,9 @@ lldpd_send_all(struct lldpd *cfg) (cfg->g_protocols[i].mode == LLDPD_MODE_LLDP)) cfg->g_protocols[i].send(cfg, &cfg->g_lchassis, hardware); } + /* Restore MAC if needed */ + if (altermac) + memcpy(hardware->h_lladdr, saved_lladdr, ETHER_ADDR_LEN); } } -- 2.39.5