From: Vincent Bernat Date: Thu, 15 Mar 2012 20:32:30 +0000 (+0100) Subject: cdp: allow to send several IP addresses X-Git-Tag: 0.6.0~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1e5d0cd3a2003cc76f08ad3e15bb13f4f635935;p=thirdparty%2Flldpd.git cdp: allow to send several IP addresses --- diff --git a/src/cdp.c b/src/cdp.c index b66b8ba5..fd6df4aa 100644 --- a/src/cdp.c +++ b/src/cdp.c @@ -38,7 +38,7 @@ cdp_send(struct lldpd *global, char *capstr; #endif u_int16_t checksum; - int length; + int length, i; u_int32_t cap; u_int8_t *packet; u_int8_t *pos, *pos_len_eh, *pos_llc, *pos_cdp, *pos_checksum, *tlv, *end; @@ -96,21 +96,36 @@ cdp_send(struct lldpd *global, goto toobig; /* Adresses */ - TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) { - if (mgmt->m_family == LLDPD_AF_IPV4) { - if (!( - POKE_START_CDP_TLV(CDP_TLV_ADDRESSES) && - POKE_UINT32(1) && /* We ship only one address */ - POKE_UINT8(1) && /* Type: NLPID */ - POKE_UINT8(1) && /* Length: 1 */ - POKE_UINT8(CDP_ADDRESS_PROTO_IP) && /* IP */ - POKE_UINT16(sizeof(struct in_addr)) && /* Address length */ - POKE_BYTES(&mgmt->m_addr, sizeof(struct in_addr)) && - POKE_END_CDP_TLV)) { - goto toobig; + /* See: + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm#xtocid12 + * + * It seems that Cisco implies that CDP supports IPv6 using + * 802.2 address format with 0xAAAA03 0x000000 0x0800, but + * 0x0800 is the Ethernet protocol type for IPv4. Therefore, + * we support only IPv4. */ + i = 0; + TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) + if (mgmt->m_family == LLDPD_AF_IPV4) i++; + if (i > 0) { + if (!( + POKE_START_CDP_TLV(CDP_TLV_ADDRESSES) && + POKE_UINT32(i))) + goto toobig; + TAILQ_FOREACH(mgmt, &chassis->c_mgmt, m_entries) { + switch (mgmt->m_family) { + case LLDPD_AF_IPV4: + if (!( + POKE_UINT8(1) && /* Type: NLPID */ + POKE_UINT8(1) && /* Length: 1 */ + POKE_UINT8(CDP_ADDRESS_PROTO_IP) && /* IP */ + POKE_UINT16(sizeof(struct in_addr)) && /* Address length */ + POKE_BYTES(&mgmt->m_addr, sizeof(struct in_addr)))) + goto toobig; + break; } - break; } + if (!(POKE_END_CDP_TLV)) + goto toobig; } /* Port ID */ diff --git a/tests/check_cdp.c b/tests/check_cdp.c index 4a6c2c89..ab40cc1d 100644 --- a/tests/check_cdp.c +++ b/tests/check_cdp.c @@ -158,14 +158,20 @@ Cisco Discovery Protocol Device ID: Second chassis Addresses Type: Addresses (0x0002) - Length: 17 - Number of addresses: 1 + Length: 26 + Number of addresses: 2 IP address: 172.17.142.36 Protocol type: NLPID Protocol length: 1 Protocol: IP Address length: 4 IP address: 172.17.142.36 + IP address: 172.17.142.38 + Protocol type: NLPID + Protocol length: 1 + Protocol: IP + Address length: 4 + IP address: 172.17.142.38 Port ID: Gigabit Ethernet 5/8 Type: Port ID (0x0003) Length: 24 @@ -192,21 +198,22 @@ Cisco Discovery Protocol */ char pkt1[] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc, 0x5e, 0x10, - 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x6f, 0xaa, 0xaa, + 0x8e, 0xe7, 0x84, 0xad, 0x00, 0x78, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x0c, 0x20, 0x00, 0x02, 0xb4, - 0x59, 0x26, 0x00, 0x01, 0x00, 0x12, 0x53, 0x65, + 0xc8, 0x67, 0x00, 0x01, 0x00, 0x12, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x63, 0x68, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x00, 0x02, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xcc, 0x00, - 0x04, 0xac, 0x11, 0x8e, 0x24, 0x00, 0x03, 0x00, - 0x18, 0x47, 0x69, 0x67, 0x61, 0x62, 0x69, 0x74, - 0x20, 0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x20, 0x35, 0x2f, 0x38, 0x00, 0x04, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x05, 0x00, - 0x17, 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, 0x73, - 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x09, - 0x4c, 0x69, 0x6e, 0x75, 0x78 }; + 0x73, 0x73, 0x69, 0x73, 0x00, 0x02, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0xcc, 0x00, + 0x04, 0xac, 0x11, 0x8e, 0x24, 0x01, 0x01, 0xcc, + 0x00, 0x04, 0xac, 0x11, 0x8e, 0x26, 0x00, 0x03, + 0x00, 0x18, 0x47, 0x69, 0x67, 0x61, 0x62, 0x69, + 0x74, 0x20, 0x45, 0x74, 0x68, 0x65, 0x72, 0x6e, + 0x65, 0x74, 0x20, 0x35, 0x2f, 0x38, 0x00, 0x04, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x05, + 0x00, 0x17, 0x43, 0x68, 0x61, 0x73, 0x73, 0x69, + 0x73, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, + 0x09, 0x4c, 0x69, 0x6e, 0x75, 0x78 }; struct packet *pkt; /* Populate port and chassis */ @@ -222,12 +229,16 @@ Cisco Discovery Protocol chassis.c_cap_available = chassis.c_cap_enabled = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE; TAILQ_INIT(&chassis.c_mgmt); - in_addr_t addr = inet_addr("172.17.142.36"); - struct lldpd_mgmt *mgmt = lldpd_alloc_mgmt(LLDPD_AF_IPV4, - &addr, sizeof(in_addr_t), 0); - if (mgmt == NULL) + in_addr_t addr1 = inet_addr("172.17.142.36"); + in_addr_t addr2 = inet_addr("172.17.142.38"); + struct lldpd_mgmt *mgmt1 = lldpd_alloc_mgmt(LLDPD_AF_IPV4, + &addr1, sizeof(in_addr_t), 0); + struct lldpd_mgmt *mgmt2 = lldpd_alloc_mgmt(LLDPD_AF_IPV4, + &addr2, sizeof(in_addr_t), 0); + if (mgmt1 == NULL || mgmt2 == NULL) ck_abort(); - TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt, m_entries); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt1, m_entries); + TAILQ_INSERT_TAIL(&chassis.c_mgmt, mgmt2, m_entries); /* Build packet */ n = cdpv2_send(NULL, &hardware); @@ -364,9 +375,9 @@ Cisco Discovery Protocol ck_assert_int_eq(nchassis->c_id_len, 2); fail_unless(memcmp(nchassis->c_id, "R1", 2) == 0); ck_assert_str_eq(nchassis->c_name, "R1"); - ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_addr.inet.s_addr, + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_addr.inet.s_addr, (u_int32_t)inet_addr("192.168.10.1")); - ck_assert_int_eq(nchassis->c_mgmt.tqh_first->m_iface, 0); + ck_assert_int_eq(TAILQ_FIRST(&nchassis->c_mgmt)->m_iface, 0); ck_assert_int_eq(nport->p_id_subtype, LLDP_PORTID_SUBTYPE_IFNAME); ck_assert_int_eq(nport->p_id_len, strlen("Ethernet0"));