]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-cdp.c
There's no link-layer header on Linux ARPHRD_ATM packets; there's
[tcpdump] / print-cdp.c
index e0b86257fb7e0a2b1431fb47868f407a000cfea1..caa8f1ef30d872ba49e753c537596d86ef0d49fc 100644 (file)
@@ -26,7 +26,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.8 2001-06-15 20:52:12 fenner Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.11 2001-09-17 21:57:56 fenner Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -54,7 +54,7 @@ void
 cdp_print(const u_char *p, u_int length, u_int caplen,
          const u_char *esrc, const u_char *edst)
 {
-       int i;
+       u_int i;
        int type, len;
 
        /* Cisco Discovery Protocol */
@@ -142,13 +142,29 @@ trunc:
        printf("[|cdp]");
 }
 
+/*
+ * Protocol type values.
+ *
+ * PT_NLPID means that the protocol type field contains an OSI NLPID.
+ *
+ * PT_IEEE_802_2 means that the protocol type field contains an IEEE 802.2
+ * LLC header that specifies that the payload is for that protocol.
+ */
+#define PT_NLPID               1       /* OSI NLPID */
+#define PT_IEEE_802_2          2       /* IEEE 802.2 LLC header */
+
 static int
 cdp_print_addr(const u_char * p, int l)
 {
-       int pl, al, num;
+       int pt, pl, al, num;
        const u_char *endp = p + l;
+#ifdef INET6
+       static u_char prot_ipv6[] = {
+               0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd
+       };
+#endif
 
-       num = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+       num = EXTRACT_32BITS(p);
        p += 4;
 
        printf(" (%d): ", num);
@@ -156,35 +172,66 @@ cdp_print_addr(const u_char * p, int l)
        while (p < endp && num >= 0) {
                if (p + 2 > endp)
                        goto trunc;
-               pl = p[1];
+               pt = p[0];              /* type of "protocol" field */
+               pl = p[1];              /* length of "protocol" field */
                p += 2;
 
-               /* special case: IPv4, protocol type=0xcc, addr. length=4 */
-               if (p + 3 > endp)
+               if (p + pl + 2 > endp)
                        goto trunc;
-               if (pl == 1 && *p == 0xcc && p[1] == 0 && p[2] == 4) {
+               al = EXTRACT_16BITS(&p[pl]);    /* address length */
+
+               if (pt == PT_NLPID && pl == 1 && *p == 0xcc && al == 4) {
+                       /*
+                        * IPv4: protocol type = NLPID, protocol length = 1
+                        * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4),
+                        * address length = 4
+                        */
                        p += 3;
 
                        if (p + 4 > endp)
                                goto trunc;
-                       printf("IPv4 %u.%u.%u.%u ", p[0], p[1], p[2], p[3]);
+                       printf("IPv4 %u.%u.%u.%u", p[0], p[1], p[2], p[3]);
                        p += 4;
-               } else {        /* generic case: just print raw data */
+               }
+#ifdef INET6
+               else if (pt == PT_IEEE_802_2 && pl == 8 &&
+                   memcmp(p, prot_ipv6, 8) == 0 && al == 16) {
+                       /*
+                        * IPv6: protocol type = IEEE 802.2 header,
+                        * protocol length = 8 (size of LLC+SNAP header),
+                        * protocol = LLC+SNAP header with the IPv6
+                        * Ethertype, address length = 16
+                        */
+                       p += 10; 
+                       if (p + al > endp)
+                               goto trunc;
+
+                       printf("IPv6 %s", ip6addr_string(p));
+                       p += al;
+               }
+#endif
+               else {
+                       /*
+                        * Generic case: just print raw data
+                        */
                        if (p + pl > endp)
                                goto trunc;
                        printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl);
                        while (pl-- > 0)
                                printf(" %02x", *p++);
-                       al = (*p << 8) + *(p + 1);
-                       if (p + 2 + al > endp)
+                       if (p + 2 > endp)
                                goto trunc;
+                       al = (*p << 8) + *(p + 1);
                        printf(", al=%d, a=", al);
                        p += 2;
+                       if (p + al > endp)
+                               goto trunc;
                        while (al-- > 0)
                                printf(" %02x", *p++);
                }
-               printf("  ");
                num--;
+               if (num)
+                       printf(" ");
        }
 
        return 0;