interfaces_setup_multicast(struct lldpd *cfg, const char *name,
int remove)
{
- int i, rc;
+ int rc;
+ size_t i, j;
+ const u_int8_t *mac;
+ const u_int8_t zero[ETHER_ADDR_LEN] = {};
- for (i=0; cfg->g_protocols[i].mode != 0; i++) {
+ for (i = 0; cfg->g_protocols[i].mode != 0; i++) {
if (!cfg->g_protocols[i].enabled) continue;
- if ((rc = priv_iface_multicast(name,
- cfg->g_protocols[i].mac, !remove)) != 0) {
- errno = rc;
- if (errno != ENOENT)
- log_debug("interfaces",
- "unable to %s %s address to multicast filter for %s (%s)",
- (remove)?"delete":"add",
- cfg->g_protocols[i].name,
- name, strerror(rc));
+ for (mac = cfg->g_protocols[i].mac1, j = 0;
+ j < 3;
+ mac += ETHER_ADDR_LEN,
+ j++) {
+ if (memcmp(mac, zero, ETHER_ADDR_LEN) == 0) break;
+ if ((rc = priv_iface_multicast(name,
+ mac, !remove)) != 0) {
+ errno = rc;
+ if (errno != ENOENT)
+ log_debug("interfaces",
+ "unable to %s %s address to multicast filter for %s (%s)",
+ (remove)?"delete":"add",
+ cfg->g_protocols[i].name,
+ name, strerror(rc));
+ }
}
}
}
static struct protocol protos[] =
{
{ LLDPD_MODE_LLDP, 1, "LLDP", 'l', lldp_send, lldp_decode, NULL,
- LLDP_MULTICAST_ADDR },
+ LLDP_ADDR_NEAREST_BRIDGE,
+ LLDP_ADDR_NEAREST_NONTPMR_BRIDGE,
+ LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE },
#ifdef ENABLE_CDP
{ LLDPD_MODE_CDPV1, 0, "CDPv1", 'c', cdpv1_send, cdp_decode, cdpv1_guess,
CDP_MULTICAST_ADDR },
if (!cfg->g_protocols[i].enabled)
continue;
if (cfg->g_protocols[i].guess == NULL) {
- if (memcmp(frame, cfg->g_protocols[i].mac, ETHER_ADDR_LEN) == 0) {
+ if (memcmp(frame, cfg->g_protocols[i].mac1, ETHER_ADDR_LEN) == 0 ||
+ memcmp(frame, cfg->g_protocols[i].mac2, ETHER_ADDR_LEN) == 0 ||
+ memcmp(frame, cfg->g_protocols[i].mac3, ETHER_ADDR_LEN) == 0) {
log_debug("decode", "guessed protocol is %s (from MAC address)",
cfg->g_protocols[i].name);
return cfg->g_protocols[i].mode;
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)
#endif
int priv_iface_init(int, char *);
int asroot_iface_init_os(int, char *, int *);
-int priv_iface_multicast(const char *, u_int8_t *, 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*);
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
struct lldpd_mgmt *mgmt;
int proto;
- u_int8_t mcastaddr[] = LLDP_MULTICAST_ADDR;
+ u_int8_t mcastaddr[] = LLDP_ADDR_NEAREST_BRIDGE;
#ifdef ENABLE_DOT1
const u_int8_t dot1[] = LLDP_TLV_ORG_DOT1;
struct lldpd_vlan *vlan;
{
struct lldpd_chassis *chassis;
struct lldpd_port *port;
- const char lldpaddr[] = LLDP_MULTICAST_ADDR;
+ char lldpaddr[ETHER_ADDR_LEN];
const char dot1[] = LLDP_TLV_ORG_DOT1;
const char dot3[] = LLDP_TLV_ORG_DOT3;
const char med[] = LLDP_TLV_ORG_MED;
log_warnx("lldp", "too short frame received on %s", hardware->h_ifname);
goto malformed;
}
- if (PEEK_CMP(lldpaddr, ETHER_ADDR_LEN) != 0) {
+ PEEK_BYTES(lldpaddr, ETHER_ADDR_LEN);
+ if (memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_BRIDGE, ETHER_ADDR_LEN) &&
+ memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_NONTPMR_BRIDGE, ETHER_ADDR_LEN) &&
+ memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE, ETHER_ADDR_LEN)) {
log_info("lldp", "frame not targeted at LLDP multicast address received on %s",
hardware->h_ifname);
goto malformed;