]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
cdp: allow to send several IP addresses
authorVincent Bernat <bernat@luffy.cx>
Thu, 15 Mar 2012 20:32:30 +0000 (21:32 +0100)
committerVincent Bernat <bernat@luffy.cx>
Thu, 15 Mar 2012 21:17:06 +0000 (22:17 +0100)
src/cdp.c
tests/check_cdp.c

index b66b8ba5afa66cab0616e4365870129cea77f5e7..fd6df4aa789ea63a8b7ab8d0db143f0e85c757c8 100644 (file)
--- 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 */
index 4a6c2c8945af79b90b5e049539eab116f0d7989c..ab40cc1da6f0f0c10a2b854bec2ae9bcdbd0efd5 100644 (file)
@@ -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"));