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;
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 */
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
*/
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 */
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);
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"));