Import tcpdump-4.3.0. vendor/TCPDUMP
authorPeter Avalos <pavalos@dragonflybsd.org>
Wed, 11 Jul 2012 01:22:41 +0000 (18:22 -0700)
committerPeter Avalos <pavalos@dragonflybsd.org>
Wed, 11 Jul 2012 01:22:41 +0000 (18:22 -0700)
See CHANGES for details.

30 files changed:
contrib/tcpdump/CHANGES
contrib/tcpdump/VERSION
contrib/tcpdump/bgp.h [changed mode: 0755->0644]
contrib/tcpdump/decode_prefix.h
contrib/tcpdump/ethertype.h
contrib/tcpdump/forces.h
contrib/tcpdump/ipproto.c [changed mode: 0755->0644]
contrib/tcpdump/l2vpn.c [changed mode: 0755->0644]
contrib/tcpdump/l2vpn.h [changed mode: 0755->0644]
contrib/tcpdump/netdissect.h
contrib/tcpdump/nlpid.c [changed mode: 0755->0644]
contrib/tcpdump/print-802_11.c
contrib/tcpdump/print-bgp.c
contrib/tcpdump/print-ether.c
contrib/tcpdump/print-forces.c
contrib/tcpdump/print-icmp6.c
contrib/tcpdump/print-igmp.c
contrib/tcpdump/print-ip.c
contrib/tcpdump/print-ip6opts.c
contrib/tcpdump/print-ldp.c
contrib/tcpdump/print-lldp.c
contrib/tcpdump/print-lwapp.c
contrib/tcpdump/print-ospf6.c
contrib/tcpdump/print-pim.c
contrib/tcpdump/print-pppoe.c
contrib/tcpdump/print-rrcp.c
contrib/tcpdump/print-syslog.c [changed mode: 0755->0644]
contrib/tcpdump/print-tipc.c [new file with mode: 0644]
contrib/tcpdump/tcpdump.1.in
contrib/tcpdump/tcpdump.c

index 2fa51b9..0031431 100644 (file)
@@ -1,3 +1,19 @@
+Friday  April 3, 2011.  mcr@sandelman.ca.
+  Summary for 4.3.0 tcpdump release
+        fixes for forces: SPARSE data (per RFC 5810)
+        some more test cases added
+        updates to documentation on -l, -U and -w flags.
+        Fix printing of BGP optional headers.
+        Tried to include DLT_PFSYNC support, failed due to headers required.
+        added TIPC support.
+        Fix LLDP Network Policy bit definitions.
+        fixes for IGMPv3's Max Response Time: it is in units of 0.1 second.
+        SIGUSR1 can be used rather than SIGINFO for stats
+        permit -n flag to affect print-ip for protocol numbers
+        ND_OPT_ADVINTERVAL is in milliseconds, not seconds
+        Teach PPPoE parser about RFC 4638
+
+
 Friday  December 9, 2011.  guy@alum.mit.edu.
   Summary for 4.2.1 tcpdump release
        Only build the Babel printer if IPv6 is enabled.
old mode 100755 (executable)
new mode 100644 (file)
index b738471..8bb4a76 100644 (file)
@@ -33,9 +33,9 @@
 #ifndef tcpdump_decode_prefix_h
 #define tcpdump_decode_prefix_h
 
-extern int decode_prefix4(const u_char *pptr, char *buf, u_int buflen);
+extern int decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen);
 #ifdef INET6
-extern int decode_prefix6(const u_char *pd, char *buf, u_int buflen);
+extern int decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen);
 #endif
 
 #endif
index fc5e515..8c06339 100644 (file)
 #ifndef ETHERTYPE_AARP
 #define ETHERTYPE_AARP         0x80f3
 #endif
+#ifndef        ETHERTYPE_TIPC
+#define        ETHERTYPE_TIPC          0x88ca
+#endif
 #ifndef        ETHERTYPE_8021Q
 #define        ETHERTYPE_8021Q         0x8100
 #endif
index ed497d4..d41475f 100644 (file)
@@ -308,7 +308,7 @@ static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = {
        /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print},
        /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print},
        /* F_OP_GETRESP */
-           {TTLV_T2, B_FULLD | B_RESTV, " GetResp", recpdoptlv_print},
+           {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print},
        /* F_OP_GETPRESP */
            {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print},
        /* F_OP_REPORT */
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 0c66dfa..821949f 100644 (file)
@@ -280,6 +280,7 @@ extern int esp_print(netdissect_options *,
                     register const u_char *bp, int len, register const u_char *bp2,
                     int *nhdr, int *padlen);
 extern void arp_print(netdissect_options *,const u_char *, u_int, u_int);
+extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int);
 extern void icmp6_print(netdissect_options *ndo, const u_char *,
                         u_int, const u_char *, int);
 extern void isakmp_print(netdissect_options *,const u_char *,
old mode 100755 (executable)
new mode 100644 (file)
index 24ab625..6f2231d 100644 (file)
@@ -485,7 +485,7 @@ static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
 #define NUM_AUTH_ALGS  (sizeof auth_alg_text / sizeof auth_alg_text[0])
 
 static const char *status_text[] = {
-       "Succesful",                                            /*  0 */
+       "Successful",                                           /*  0 */
        "Unspecified failure",                                  /*  1 */
        "Reserved",                                             /*  2 */
        "Reserved",                                             /*  3 */
index 6460a59..c1e382f 100644 (file)
@@ -93,8 +93,7 @@ struct bgp_opt {
        /* variable length */
 };
 #define BGP_OPT_SIZE           2       /* some compilers may pad to 4 bytes */
-
-#define BGP_UPDATE_MINSIZE      23
+#define BGP_CAP_HEADER_SIZE    2       /* some compilers may pad to 4 bytes */
 
 struct bgp_notification {
        u_int8_t bgpn_marker[16];
@@ -115,19 +114,10 @@ struct bgp_route_refresh {
 };                    /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh)      */ 
 #define BGP_ROUTE_REFRESH_SIZE          23
 
-struct bgp_attr {
-       u_int8_t bgpa_flags;
-       u_int8_t bgpa_type;
-       union {
-               u_int8_t len;
-               u_int16_t elen;
-       } bgpa_len;
-#define bgp_attr_len(p) \
-       (((p)->bgpa_flags & 0x10) ? \
-               EXTRACT_16BITS(&(p)->bgpa_len.elen) : (p)->bgpa_len.len)
-#define bgp_attr_off(p) \
-       (((p)->bgpa_flags & 0x10) ? 4 : 3)
-};
+#define bgp_attr_lenlen(flags, p) \
+       (((flags) & 0x10) ? 2 : 1)
+#define bgp_attr_len(flags, p) \
+       (((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p))
 
 #define BGPTYPE_ORIGIN                 1
 #define BGPTYPE_AS_PATH                        2
@@ -493,38 +483,49 @@ as_printf (char *str, int size, u_int asnum)
        return str;
 }
 
+#define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
+
 int
-decode_prefix4(const u_char *pptr, char *buf, u_int buflen)
+decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
 {
        struct in_addr addr;
-       u_int plen;
+       u_int plen, plenbytes;
 
        TCHECK(pptr[0]);
+       ITEMCHECK(1);
        plen = pptr[0];
        if (32 < plen)
                return -1;
+       itemlen -= 1;
 
        memset(&addr, 0, sizeof(addr));
-       TCHECK2(pptr[1], (plen + 7) / 8);
-       memcpy(&addr, &pptr[1], (plen + 7) / 8);
+       plenbytes = (plen + 7) / 8;
+       TCHECK2(pptr[1], plenbytes);
+       ITEMCHECK(plenbytes);
+       memcpy(&addr, &pptr[1], plenbytes);
        if (plen % 8) {
-               ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
+               ((u_char *)&addr)[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
        snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen);
-       return 1 + (plen + 7) / 8;
+       return 1 + plenbytes;
 
 trunc:
        return -2;
+
+badtlv:
+       return -3;
 }
 
 static int
-decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen)
+decode_labeled_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
 {
        struct in_addr addr;
-       u_int plen;
+       u_int plen, plenbytes;
 
-       TCHECK(pptr[0]);
+       /* prefix length and label = 4 bytes */
+       TCHECK2(pptr[0], 4);
+       ITEMCHECK(4);
        plen = pptr[0];   /* get prefix length */
 
         /* this is one of the weirdnesses of rfc3107
@@ -542,12 +543,15 @@ decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen)
 
        if (32 < plen)
                return -1;
+       itemlen -= 4;
 
        memset(&addr, 0, sizeof(addr));
-       TCHECK2(pptr[4], (plen + 7) / 8);
-       memcpy(&addr, &pptr[4], (plen + 7) / 8);
+       plenbytes = (plen + 7) / 8;
+       TCHECK2(pptr[4], plenbytes);
+       ITEMCHECK(plenbytes);
+       memcpy(&addr, &pptr[4], plenbytes);
        if (plen % 8) {
-               ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
+               ((u_char *)&addr)[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
         /* the label may get offsetted by 4 bits so lets shift it right */
@@ -557,10 +561,13 @@ decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen)
                  EXTRACT_24BITS(pptr+1)>>4,
                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
 
-       return 4 + (plen + 7) / 8;
+       return 4 + plenbytes;
 
 trunc:
        return -2;
+
+badtlv:
+       return -3;
 }
 
 /*
@@ -1041,37 +1048,46 @@ trunc:
 
 #ifdef INET6
 int
-decode_prefix6(const u_char *pd, char *buf, u_int buflen)
+decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen)
 {
        struct in6_addr addr;
-       u_int plen;
+       u_int plen, plenbytes;
 
        TCHECK(pd[0]);
+       ITEMCHECK(1);
        plen = pd[0];
        if (128 < plen)
                return -1;
+       itemlen -= 1;
 
        memset(&addr, 0, sizeof(addr));
-       TCHECK2(pd[1], (plen + 7) / 8);
-       memcpy(&addr, &pd[1], (plen + 7) / 8);
+       plenbytes = (plen + 7) / 8;
+       TCHECK2(pd[1], plenbytes);
+       ITEMCHECK(plenbytes);
+       memcpy(&addr, &pd[1], plenbytes);
        if (plen % 8) {
-               addr.s6_addr[(plen + 7) / 8 - 1] &=
+               addr.s6_addr[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
        snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen);
-       return 1 + (plen + 7) / 8;
+       return 1 + plenbytes;
 
 trunc:
        return -2;
+
+badtlv:
+       return -3;
 }
 
 static int
-decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen)
+decode_labeled_prefix6(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
 {
        struct in6_addr addr;
-       u_int plen;
+       u_int plen, plenbytes;
 
-       TCHECK(pptr[0]);
+       /* prefix length and label = 4 bytes */
+       TCHECK2(pptr[0], 4);
+       ITEMCHECK(4);
        plen = pptr[0]; /* get prefix length */
 
        if (24 > plen)
@@ -1081,12 +1097,14 @@ decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen)
 
        if (128 < plen)
                return -1;
+       itemlen -= 4;
 
        memset(&addr, 0, sizeof(addr));
-       TCHECK2(pptr[4], (plen + 7) / 8);
-       memcpy(&addr, &pptr[4], (plen + 7) / 8);
+       plenbytes = (plen + 7) / 8;
+       TCHECK2(pptr[4], plenbytes);
+       memcpy(&addr, &pptr[4], plenbytes);
        if (plen % 8) {
-               addr.s6_addr[(plen + 7) / 8 - 1] &=
+               addr.s6_addr[plenbytes - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
         /* the label may get offsetted by 4 bits so lets shift it right */
@@ -1096,10 +1114,13 @@ decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen)
                  EXTRACT_24BITS(pptr+1)>>4,
                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
 
-       return 4 + (plen + 7) / 8;
+       return 4 + plenbytes;
 
 trunc:
        return -2;
+
+badtlv:
+       return -3;
 }
 
 static int
@@ -1266,7 +1287,7 @@ trunc:
 }
 
 static int
-bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
+bgp_attr_print(u_int atype, const u_char *pptr, u_int len)
 {
        int i;
        u_int16_t af;
@@ -1276,7 +1297,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
             u_int32_t i;
         } bw;
        int advance;
-       int tlen;
+       u_int tlen;
        const u_char *tptr;
        char buf[MAXHOSTNAMELEN + 100];
        char tokbuf[TOKBUFSIZE];
@@ -1285,7 +1306,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
         tptr = pptr;
         tlen=len;
 
-       switch (attr->bgpa_type) {
+       switch (atype) {
        case BGPTYPE_ORIGIN:
                if (len != 1)
                        printf("invalid len");
@@ -1321,7 +1342,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                  * 2 bytes first, and it does not pass, assume that ASs are
                  * encoded in 4 bytes format and move on.
                  */
-                as_size = bgp_attr_get_as_size(attr->bgpa_type, pptr, len);
+                as_size = bgp_attr_get_as_size(atype, pptr, len);
 
                while (tptr < pptr + len) {
                        TCHECK(tptr[0]);
@@ -1657,20 +1678,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                     case (AFNUM_INET<<8 | SAFNUM_UNICAST):
                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
                     case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
-                        advance = decode_prefix4(tptr, buf, sizeof(buf));
+                        advance = decode_prefix4(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
                     case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
-                        advance = decode_labeled_prefix4(tptr, buf, sizeof(buf));
+                        advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
@@ -1718,20 +1743,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                     case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
                     case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
-                        advance = decode_prefix6(tptr, buf, sizeof(buf));
+                        advance = decode_prefix6(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
                     case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
-                        advance = decode_labeled_prefix6(tptr, buf, sizeof(buf));
+                        advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
@@ -1821,20 +1850,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                     case (AFNUM_INET<<8 | SAFNUM_UNICAST):
                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
                     case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
-                        advance = decode_prefix4(tptr, buf, sizeof(buf));
+                        advance = decode_prefix4(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
                     case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
-                        advance = decode_labeled_prefix4(tptr, buf, sizeof(buf));
+                        advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
@@ -1853,20 +1886,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                     case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
                     case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
-                        advance = decode_prefix6(tptr, buf, sizeof(buf));
+                        advance = decode_prefix6(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
                     case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
-                        advance = decode_labeled_prefix6(tptr, buf, sizeof(buf));
+                        advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf));
                         if (advance == -1)
                             printf("\n\t    (illegal prefix length)");
                         else if (advance == -2)
                             goto trunc;
+                        else if (advance == -3)
+                            break; /* bytes left, but not enough */
                         else
                             printf("\n\t      %s", buf);
                         break;
@@ -2097,40 +2134,50 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
         }
         case BGPTYPE_ATTR_SET:
                 TCHECK2(tptr[0], 4);
+                if (len < 4)
+                       goto trunc;
                printf("\n\t    Origin AS: %s",
                    as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)));
                tptr+=4;
                 len -=4;
 
-                while (len >= 2 ) {
-                    int alen;
-                    struct bgp_attr bgpa;
+                while (len) {
+                    u_int aflags, atype, alenlen, alen;
                     
-                    TCHECK2(tptr[0], sizeof(bgpa));
-                    memcpy(&bgpa, tptr, sizeof(bgpa));
-                    alen = bgp_attr_len(&bgpa);
-                    tptr += bgp_attr_off(&bgpa);
-                    len -= bgp_attr_off(&bgpa);
+                    TCHECK2(tptr[0], 2);
+                    if (len < 2)
+                        goto trunc;
+                    aflags = *tptr;
+                    atype = *(tptr + 1);
+                    tptr += 2;
+                    len -= 2;
+                    alenlen = bgp_attr_lenlen(aflags, tptr);
+                    TCHECK2(tptr[0], alenlen);
+                    if (len < alenlen)
+                        goto trunc;
+                    alen = bgp_attr_len(aflags, tptr);
+                    tptr += alenlen;
+                    len -= alenlen;
                     
                     printf("\n\t      %s (%u), length: %u",
                            tok2strbuf(bgp_attr_values,
-                                     "Unknown Attribute", bgpa.bgpa_type,
-                                     tokbuf, sizeof(tokbuf)),
-                           bgpa.bgpa_type,
+                                      "Unknown Attribute", atype,
+                                      tokbuf, sizeof(tokbuf)),
+                           atype,
                            alen);
                     
-                    if (bgpa.bgpa_flags) {
+                    if (aflags) {
                         printf(", Flags [%s%s%s%s",
-                               bgpa.bgpa_flags & 0x80 ? "O" : "",
-                               bgpa.bgpa_flags & 0x40 ? "T" : "",
-                               bgpa.bgpa_flags & 0x20 ? "P" : "",
-                               bgpa.bgpa_flags & 0x10 ? "E" : "");
-                        if (bgpa.bgpa_flags & 0xf)
-                            printf("+%x", bgpa.bgpa_flags & 0xf);
+                               aflags & 0x80 ? "O" : "",
+                               aflags & 0x40 ? "T" : "",
+                               aflags & 0x20 ? "P" : "",
+                               aflags & 0x10 ? "E" : "");
+                        if (aflags & 0xf)
+                            printf("+%x", aflags & 0xf);
                         printf("]: ");
                     }
                     /* FIXME check for recursion */
-                    if (!bgp_attr_print(&bgpa, tptr, alen))
+                    if (!bgp_attr_print(atype, tptr, alen))
                         return 0;
                     tptr += alen;
                     len -= alen;
@@ -2140,7 +2187,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
 
        default:
            TCHECK2(*pptr,len);
-            printf("\n\t    no Attribute %u decoder",attr->bgpa_type); /* we have no decoder for the attribute */
+            printf("\n\t    no Attribute %u decoder",atype); /* we have no decoder for the attribute */
             if (vflag <= 1)
                 print_unknown_data(pptr,"\n\t    ",len);
             break;
@@ -2156,14 +2203,97 @@ trunc:
 }
 
 static void
+bgp_capabilities_print(const u_char *opt, int caps_len)
+{
+       char tokbuf[TOKBUFSIZE];
+       char tokbuf2[TOKBUFSIZE];
+       int cap_type, cap_len, tcap_len, cap_offset;
+        int i = 0;
+
+        while (i < caps_len) {
+                TCHECK2(opt[i], BGP_CAP_HEADER_SIZE);
+                cap_type=opt[i];
+                cap_len=opt[i+1];
+                tcap_len=cap_len;
+                printf("\n\t      %s (%u), length: %u",
+                       tok2strbuf(bgp_capcode_values, "Unknown",
+                                  cap_type, tokbuf, sizeof(tokbuf)),
+                       cap_type,
+                       cap_len);
+                TCHECK2(opt[i+2], cap_len);
+                switch (cap_type) {
+                case BGP_CAPCODE_MP:
+                    printf("\n\t\tAFI %s (%u), SAFI %s (%u)",
+                           tok2strbuf(af_values, "Unknown",
+                                      EXTRACT_16BITS(opt+i+2),
+                                      tokbuf, sizeof(tokbuf)),
+                           EXTRACT_16BITS(opt+i+2),
+                           tok2strbuf(bgp_safi_values, "Unknown",
+                                      opt[i+5],
+                                      tokbuf, sizeof(tokbuf)),
+                           opt[i+5]);
+                    break;
+                case BGP_CAPCODE_RESTART:
+                    printf("\n\t\tRestart Flags: [%s], Restart Time %us",
+                           ((opt[i+2])&0x80) ? "R" : "none",
+                           EXTRACT_16BITS(opt+i+2)&0xfff);
+                    tcap_len-=2;
+                    cap_offset=4;
+                    while(tcap_len>=4) {
+                        printf("\n\t\t  AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
+                               tok2strbuf(af_values,"Unknown",
+                                          EXTRACT_16BITS(opt+i+cap_offset),
+                                          tokbuf, sizeof(tokbuf)),
+                               EXTRACT_16BITS(opt+i+cap_offset),
+                               tok2strbuf(bgp_safi_values,"Unknown",
+                                          opt[i+cap_offset+2],
+                                          tokbuf2, sizeof(tokbuf2)),
+                               opt[i+cap_offset+2],
+                               ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" );
+                        tcap_len-=4;
+                        cap_offset+=4;
+                    }
+                    break;
+                case BGP_CAPCODE_RR:
+                case BGP_CAPCODE_RR_CISCO:
+                    break;
+                case BGP_CAPCODE_AS_NEW:
+
+                    /*
+                     * Extract the 4 byte AS number encoded.
+                     */
+                    if (cap_len == 4) {
+                        printf("\n\t\t 4 Byte AS %s",
+                            as_printf(astostr, sizeof(astostr),
+                            EXTRACT_32BITS(opt + i + 2)));
+                    }
+                    break;
+                default:
+                    printf("\n\t\tno decoder for Capability %u",
+                           cap_type);
+                    if (vflag <= 1)
+                        print_unknown_data(&opt[i+2],"\n\t\t",cap_len);
+                    break;
+                }
+                if (vflag > 1 && cap_len > 0) {
+                    print_unknown_data(&opt[i+2],"\n\t\t",cap_len);
+                }
+                i += BGP_CAP_HEADER_SIZE + cap_len;
+        }
+        return;
+
+trunc:
+       printf("[|BGP]");
+}
+
+static void
 bgp_open_print(const u_char *dat, int length)
 {
        struct bgp_open bgpo;
        struct bgp_opt bgpopt;
        const u_char *opt;
-       int i,cap_type,cap_len,tcap_len,cap_offset;
+       int i;
        char tokbuf[TOKBUFSIZE];
-       char tokbuf2[TOKBUFSIZE];
 
        TCHECK2(dat[0], BGP_OPEN_SIZE);
        memcpy(&bgpo, dat, BGP_OPEN_SIZE);
@@ -2188,96 +2318,31 @@ bgp_open_print(const u_char *dat, int length)
                TCHECK2(opt[i], BGP_OPT_SIZE);
                memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE);
                if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
-                        printf("\n\t     Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len);
+                       printf("\n\t     Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len);
                        break;
                }
 
                printf("\n\t    Option %s (%u), length: %u",
-                       tok2strbuf(bgp_opt_values,"Unknown",
+                      tok2strbuf(bgp_opt_values,"Unknown",
                                  bgpopt.bgpopt_type,
                                  tokbuf, sizeof(tokbuf)),
-                       bgpopt.bgpopt_type,
-                       bgpopt.bgpopt_len);
-
-                /* now lets decode the options we know*/
-                switch(bgpopt.bgpopt_type) {
-                case BGP_OPT_CAP:
-                    cap_type=opt[i+BGP_OPT_SIZE];
-                    cap_len=opt[i+BGP_OPT_SIZE+1];
-                    tcap_len=cap_len;
-                    printf("\n\t      %s (%u), length: %u",
-                           tok2strbuf(bgp_capcode_values, "Unknown",
-                                     cap_type, tokbuf, sizeof(tokbuf)),
-                           cap_type,
-                           cap_len);
-                    switch(cap_type) {
-                    case BGP_CAPCODE_MP:
-                        printf("\n\t\tAFI %s (%u), SAFI %s (%u)",
-                               tok2strbuf(af_values, "Unknown",
-                                         EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2),
-                                         tokbuf, sizeof(tokbuf)),
-                               EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2),
-                               tok2strbuf(bgp_safi_values, "Unknown",
-                                         opt[i+BGP_OPT_SIZE+5],
-                                         tokbuf, sizeof(tokbuf)),
-                               opt[i+BGP_OPT_SIZE+5]);
-                        break;
-                    case BGP_CAPCODE_RESTART:
-                        printf("\n\t\tRestart Flags: [%s], Restart Time %us",
-                               ((opt[i+BGP_OPT_SIZE+2])&0x80) ? "R" : "none",
-                               EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2)&0xfff);
-                        tcap_len-=2;
-                        cap_offset=4;
-                        while(tcap_len>=4) {
-                            printf("\n\t\t  AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
-                                   tok2strbuf(af_values,"Unknown",
-                                             EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset),
-                                             tokbuf, sizeof(tokbuf)),
-                                   EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset),
-                                   tok2strbuf(bgp_safi_values,"Unknown",
-                                             opt[i+BGP_OPT_SIZE+cap_offset+2],
-                                             tokbuf2, sizeof(tokbuf2)),
-                                   opt[i+BGP_OPT_SIZE+cap_offset+2],
-                                   ((opt[i+BGP_OPT_SIZE+cap_offset+3])&0x80) ? "yes" : "no" );
-                            tcap_len-=4;
-                            cap_offset+=4;
-                        }
-                        break;
-                    case BGP_CAPCODE_RR:
-                    case BGP_CAPCODE_RR_CISCO:
-                        break;
-                    case BGP_CAPCODE_AS_NEW:
-
-                        /*
-                         * Extract the 4 byte AS number encoded.
-                         */
-                        TCHECK2(opt[i + BGP_OPT_SIZE + 2], cap_len);
-                        if (cap_len == 4) {
-                           printf("\n\t\t 4 Byte AS %s",
-                               as_printf(astostr, sizeof(astostr),
-                               EXTRACT_32BITS(opt + i + BGP_OPT_SIZE + 2)));
-                        }
-                        break;
-                    default:
-                        TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len);
-                        printf("\n\t\tno decoder for Capability %u",
-                               cap_type);
-                        if (vflag <= 1)
-                            print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len);
-                        break;
-                    }
-                    if (vflag > 1) {
-                        TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len);
-                        print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len);
-                    }
-                    break;
-                case BGP_OPT_AUTH:
-                default:
-                       printf("\n\t      no decoder for option %u",
-                           bgpopt.bgpopt_type);
-                       break;
-                }
+                      bgpopt.bgpopt_type,
+                      bgpopt.bgpopt_len);
+
+               /* now let's decode the options we know*/
+               switch(bgpopt.bgpopt_type) {
 
+               case BGP_OPT_CAP:
+                       bgp_capabilities_print(&opt[i+BGP_OPT_SIZE],
+                           bgpopt.bgpopt_len);
+                       break;
+
+               case BGP_OPT_AUTH:
+               default:
+                      printf("\n\t      no decoder for option %u",
+                          bgpopt.bgpopt_type);
+                      break;
+               }
                i += BGP_OPT_SIZE + bgpopt.bgpopt_len;
        }
        return;
@@ -2289,107 +2354,163 @@ static void
 bgp_update_print(const u_char *dat, int length)
 {
        struct bgp bgp;
-       struct bgp_attr bgpa;
        const u_char *p;
+       int withdrawn_routes_len;
        int len;
        int i;
        char tokbuf[TOKBUFSIZE];
+#ifndef INET6
+       char buf[MAXHOSTNAMELEN + 100];
+       int wpfx;
+#endif
 
        TCHECK2(dat[0], BGP_SIZE);
+       if (length < BGP_SIZE)
+               goto trunc;
        memcpy(&bgp, dat, BGP_SIZE);
        p = dat + BGP_SIZE;     /*XXX*/
+       length -= BGP_SIZE;
 
        /* Unfeasible routes */
-       len = EXTRACT_16BITS(p);
-       if (len) {
+       TCHECK2(p[0], 2);
+       if (length < 2)
+               goto trunc;
+       withdrawn_routes_len = EXTRACT_16BITS(p);
+       p += 2;
+       length -= 2;
+       if (withdrawn_routes_len) {
                /*
                 * Without keeping state from the original NLRI message,
                 * it's not possible to tell if this a v4 or v6 route,
                 * so only try to decode it if we're not v6 enabled.
                 */
+               TCHECK2(p[0], withdrawn_routes_len);
+               if (length < withdrawn_routes_len)
+                       goto trunc;
 #ifdef INET6
-               printf("\n\t  Withdrawn routes: %d bytes", len);
+               printf("\n\t  Withdrawn routes: %d bytes", withdrawn_routes_len);
+               p += withdrawn_routes_len;
+               length -= withdrawn_routes_len;
 #else
-               char buf[MAXHOSTNAMELEN + 100];
-               int wpfx;
+               if (withdrawn_routes_len < 2)
+                       goto trunc;
+               length -= 2;
+               withdrawn_routes_len -= 2;
 
-               TCHECK2(p[2], len);
-               i = 2;
 
                printf("\n\t  Withdrawn routes:");
 
-               while(i < 2 + len) {
-                       wpfx = decode_prefix4(&p[i], buf, sizeof(buf));
+               while(withdrawn_routes_len > 0) {
+                       wpfx = decode_prefix4(p, withdrawn_routes_len, buf, sizeof(buf));
                        if (wpfx == -1) {
                                printf("\n\t    (illegal prefix length)");
                                break;
                        } else if (wpfx == -2)
                                goto trunc;
+                       else if (wpfx == -3)
+                               goto trunc; /* bytes left, but not enough */
                        else {
-                               i += wpfx;
                                printf("\n\t    %s", buf);
+                               p += wpfx;
+                               length -= wpfx;
+                               withdrawn_routes_len -= wpfx;
                        }
                }
 #endif
        }
-       p += 2 + len;
 
        TCHECK2(p[0], 2);
+       if (length < 2)
+               goto trunc;
        len = EXTRACT_16BITS(p);
+       p += 2;
+       length -= 2;
 
-        if (len == 0 && length == BGP_UPDATE_MINSIZE) {
+        if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
+            /* No withdrawn routes, no path attributes, no NLRI */
             printf("\n\t  End-of-Rib Marker (empty NLRI)");
             return;
         }
 
        if (len) {
                /* do something more useful!*/
-               i = 2;
-               while (i < 2 + len) {
-                       int alen, aoff;
-
-                       TCHECK2(p[i], sizeof(bgpa));
-                       memcpy(&bgpa, &p[i], sizeof(bgpa));
-                       alen = bgp_attr_len(&bgpa);
-                       aoff = bgp_attr_off(&bgpa);
-
-                      printf("\n\t  %s (%u), length: %u",
+               while (len) {
+                       int aflags, atype, alenlen, alen;
+
+                       TCHECK2(p[0], 2);
+                       if (len < 2)
+                           goto trunc;
+                       if (length < 2)
+                           goto trunc;
+                       aflags = *p;
+                       atype = *(p + 1);
+                       p += 2;
+                       len -= 2;
+                       length -= 2;
+                       alenlen = bgp_attr_lenlen(aflags, p);
+                       TCHECK2(p[0], alenlen);
+                       if (len < alenlen)
+                           goto trunc;
+                       if (length < alenlen)
+                           goto trunc;
+                       alen = bgp_attr_len(aflags, p);
+                       p += alenlen;
+                       len -= alenlen;
+                       length -= alenlen;
+
+                       printf("\n\t  %s (%u), length: %u",
                               tok2strbuf(bgp_attr_values, "Unknown Attribute",
-                                        bgpa.bgpa_type,
+                                        atype,
                                         tokbuf, sizeof(tokbuf)),
-                              bgpa.bgpa_type,
+                              atype,
                               alen);
 
-                       if (bgpa.bgpa_flags) {
+                       if (aflags) {
                                printf(", Flags [%s%s%s%s",
-                                       bgpa.bgpa_flags & 0x80 ? "O" : "",
-                                       bgpa.bgpa_flags & 0x40 ? "T" : "",
-                                       bgpa.bgpa_flags & 0x20 ? "P" : "",
-                                       bgpa.bgpa_flags & 0x10 ? "E" : "");
-                               if (bgpa.bgpa_flags & 0xf)
-                                       printf("+%x", bgpa.bgpa_flags & 0xf);
+                                       aflags & 0x80 ? "O" : "",
+                                       aflags & 0x40 ? "T" : "",
+                                       aflags & 0x20 ? "P" : "",
+                                       aflags & 0x10 ? "E" : "");
+                               if (aflags & 0xf)
+                                       printf("+%x", aflags & 0xf);
                                printf("]: ");
                        }
-                       if (!bgp_attr_print(&bgpa, &p[i + aoff], alen))
+                       if (len < alen)
+                               goto trunc;
+                       if (length < alen)
                                goto trunc;
-                       i += aoff + alen;
+                       if (!bgp_attr_print(atype, p, alen))
+                               goto trunc;
+                       p += alen;
+                       len -= alen;
+                       length -= alen;
                }
        } 
-       p += 2 + len;
 
-       if (dat + length > p) {
+       if (length) {
+               /*
+                * XXX - what if they're using the "Advertisement of
+                * Multiple Paths in BGP" feature:
+                *
+                * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/
+                *
+                * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06
+                */
                printf("\n\t  Updated routes:");
-               while (dat + length > p) {
+               while (length) {
                        char buf[MAXHOSTNAMELEN + 100];
-                       i = decode_prefix4(p, buf, sizeof(buf));
+                       i = decode_prefix4(p, length, buf, sizeof(buf));
                        if (i == -1) {
                                printf("\n\t    (illegal prefix length)");
                                break;
                        } else if (i == -2)
                                goto trunc;
+                       else if (i == -3)
+                               goto trunc; /* bytes left, but not enough */
                        else {
                                printf("\n\t    %s", buf);
                                p += i;
+                               length -= i;
                        }
                }
        }
index 7650572..e2f487c 100644 (file)
@@ -37,7 +37,6 @@ static const char rcsid[] _U_ =
 #include "extract.h"
 #include "addrtoname.h"
 #include "ethertype.h"
-
 #include "ether.h"
 
 const struct tok ethertype_values[] = { 
@@ -84,6 +83,7 @@ const struct tok ethertype_values[] = {
     { ETHERTYPE_CFM_OLD,        "CFM (old)" },
     { ETHERTYPE_CFM,            "CFM" },
     { ETHERTYPE_LLDP,           "LLDP" },
+    { ETHERTYPE_TIPC,           "TIPC"},       
     { 0, NULL}
 };
 
@@ -408,6 +408,10 @@ ethertype_print(netdissect_options *ndo,
                mpls_print(/*ndo,*/p, length);
                return (1);
 
+       case ETHERTYPE_TIPC:
+               tipc_print(ndo, p, length, caplen);
+               return (1);
+
        case ETHERTYPE_LAT:
        case ETHERTYPE_SCA:
        case ETHERTYPE_MOPRC:
index 033580e..438aa27 100644 (file)
@@ -113,24 +113,24 @@ sdatailv_print(register const u_char * pptr, register u_int len,
                printf("Error: BAD SPARSEDATA-TLV!\n");
                return -1;
        }
-       rlen = len - ILV_HDRL;
+       rlen = len;
        indent += 1;
        while (rlen != 0) {
+               char *ib = indent_pr(indent, 1);
+               register const u_char *tdp = (u_char *) ILV_DATA(ilv);
                TCHECK(*ilv);
                invilv = ilv_valid(ilv, rlen);
                if (invilv) {
-                       printf("Error: BAD ILV!\n");
-                       return -1;
-               }
-               if (vflag >= 3) {
-                       register const u_char *tdp = (u_char *) ILV_DATA(ilv);
-                       char *ib = indent_pr(indent, 1);
-                       printf("\n%s SPARSEDATA: type %x length %d\n", &ib[1],
-                              EXTRACT_32BITS(&ilv->type),
-                              EXTRACT_32BITS(&ilv->length));
                        printf("%s[", &ib[1]);
                        hex_print_with_offset(ib, tdp, rlen, 0);
                        printf("\n%s]\n", &ib[1]);
+                       return -1;
+               }
+               if (vflag >= 3) {
+                       int ilvl = EXTRACT_32BITS(&ilv->length);
+                       printf("\n%s ILV: type %x length %d\n", &ib[1],
+                              EXTRACT_32BITS(&ilv->type), ilvl);
+                       hex_print_with_offset("\t\t[", tdp, ilvl-ILV_HDRL, 0);
                }
 
                ilv = GO_NXT_ILV(ilv, rlen);
@@ -216,7 +216,6 @@ pdatacnt_print(register const u_char * pptr, register u_int len,
               u_int16_t IDcnt, u_int16_t op_msk, int indent)
 {
        u_int i;
-       int rc;
        u_int32_t id;
        char *ib = indent_pr(indent, 0);
 
@@ -282,9 +281,10 @@ pdatacnt_print(register const u_char * pptr, register u_int len,
 
                        chk_op_type(type, op_msk, ops->op_msk);
 
-                       rc = ops->print((const u_char *)pdtlv,
+                       if (ops->print((const u_char *)pdtlv,
                                        tll + pad + TLV_HDRL, op_msk,
-                                       indent + 2);
+                                       indent + 2) == -1)
+                               return -1;
                        len -= (TLV_HDRL + pad + tll);
                } else {
                        printf("Invalid path data content type 0x%x len %d\n",
@@ -404,7 +404,6 @@ recpdoptlv_print(register const u_char * pptr, register u_int len,
 {
        const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
        int tll;
-       int rc = 0;
        int invtlv;
        u_int16_t type;
        register const u_char *dp;
@@ -434,7 +433,8 @@ recpdoptlv_print(register const u_char * pptr, register u_int len,
                             EXTRACT_16BITS(&pdtlv->length),
                             EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL);
 
-               rc = pdata_print(dp, tll, op_msk, indent + 1);
+               if (pdata_print(dp, tll, op_msk, indent + 1) == -1)
+                       return -1;
                pdtlv = GO_NXT_TLV(pdtlv, len);
        }
 
@@ -1016,7 +1016,7 @@ void forces_print(register const u_char * pptr, register u_int len)
        if (vflag >= 1) {
                printf("\n\tForCES Version %d len %uB flags 0x%08x ",
                       ForCES_V(fhdr), mlen, flg_raw);
-               printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64,
+               printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64,
                       ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)),
                       ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)),
                       EXTRACT_64BITS(fhdr->fm_cor));
index ce1046e..176c15c 100644 (file)
@@ -752,7 +752,7 @@ icmp6_opt_print(const u_char *bp, int resid)
                case ND_OPT_ADVINTERVAL:
                        opa = (struct nd_opt_advinterval *)op;
                        TCHECK(opa->nd_opt_adv_interval);
-                       printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
+                       printf(" %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
                        break;
                case ND_OPT_HOMEAGENT_INFO:
                        oph = (struct nd_opt_homeagent_info *)op;
index 6522bc3..4087ee0 100644 (file)
@@ -227,7 +227,11 @@ print_igmpv3_query(register const u_char *bp, register u_int len)
     }
     if (mrc != 100) {
        (void)printf(" [max resp time ");
-       relts_print(mrt);
+        if (mrt < 600) {
+            (void)printf("%.1fs", mrt * 0.1);
+        } else {
+            relts_print(mrt / 10);
+        }
        (void)printf("]");
     }
     TCHECK2(bp[4], 4);
index 1fa7aab..494eb29 100644 (file)
@@ -350,7 +350,7 @@ again:
                ipds->nh = enh & 0xff;
                goto again;
        }
-       
+
        case IPPROTO_IPCOMP:
        {
                int enh;
@@ -370,25 +370,25 @@ again:
        case IPPROTO_DCCP:
                dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
                break;
-               
+
        case IPPROTO_TCP:
                /* pass on the MF bit plus the offset to detect fragments */
                tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
                          ipds->off & (IP_MF|IP_OFFMASK));
                break;
-               
+
        case IPPROTO_UDP:
                /* pass on the MF bit plus the offset to detect fragments */
                udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
                          ipds->off & (IP_MF|IP_OFFMASK));
                break;
-               
+
        case IPPROTO_ICMP:
                /* pass on the MF bit plus the offset to detect fragments */
                icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
                           ipds->off & (IP_MF|IP_OFFMASK));
                break;
-               
+
        case IPPROTO_PIGP:
                /*
                 * XXX - the current IANA protocol number assignments
@@ -405,11 +405,11 @@ again:
                 */
                igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
                break;
-               
+
        case IPPROTO_EIGRP:
                eigrp_print(ipds->cp, ipds->len);
                break;
-               
+
        case IPPROTO_ND:
                ND_PRINT((ndo, " nd %d", ipds->len));
                break;
@@ -434,7 +434,7 @@ again:
                        return;
                }
                break;
-               
+
 #ifdef INET6
        case IPPROTO_IPV6:
                /* ip6-in-ip encapsulation */
@@ -482,7 +482,7 @@ again:
                break;
 
        default:
-               if ((proto = getprotobynumber(ipds->nh)) != NULL)
+               if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
                        ND_PRINT((ndo, " %s", proto->p_name));
                else
                        ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
@@ -490,7 +490,7 @@ again:
                break;
        }
 }
-              
+
 void
 ip_print_inner(netdissect_options *ndo,
               const u_char *bp,
@@ -597,7 +597,7 @@ ip_print(netdissect_options *ndo,
             }
 
             if (ipds->ip->ip_ttl >= 1)
-                (void)printf(", ttl %u", ipds->ip->ip_ttl);    
+                (void)printf(", ttl %u", ipds->ip->ip_ttl);
 
            /*
             * for the firewall guys, print id, offset.
@@ -661,11 +661,11 @@ ip_print(netdissect_options *ndo,
            if (ipds->off & 0x1fff) {
                (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),
                             ipaddr_string(&ipds->ip->ip_dst));
-               if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
+               if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
                    (void)printf(" %s", proto->p_name);
                else
                    (void)printf(" ip-proto-%d", ipds->ip->ip_p);
-           } 
+           }
        }
 }
 
index 7a4bf55..2121b46 100644 (file)
@@ -141,6 +141,8 @@ ip6_opt_print(const u_char *bp, int len)
     int i;
     int optlen = 0;
 
+    if (len == 0)
+        return;
     for (i = 0; i < len; i += optlen) {
        if (bp[i] == IP6OPT_PAD1)
            optlen = 1;
@@ -271,10 +273,11 @@ ip6_opt_print(const u_char *bp, int len)
                printf("(type %d: trunc)", bp[i]);
                goto trunc;
            }
-           printf("(opt_type 0x%02x: len=%d) ", bp[i], bp[i + 1]);
+           printf("(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]);
            break;
        }
     }
+    printf(" ");
 
 #if 0
 end:
index 1243104..262c9bd 100644 (file)
@@ -180,7 +180,7 @@ static const struct tok ldp_tlv_values[] = {
 #define LDP_FEC_WILDCARD       0x01
 #define LDP_FEC_PREFIX         0x02
 #define LDP_FEC_HOSTADDRESS    0x03
-/* From draft-martini-l2circuit-trans-mpls-13.txt */
+/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
 #define LDP_FEC_MARTINI_VC     0x80
 
 static const struct tok ldp_fec_values[] = {
@@ -238,6 +238,9 @@ int ldp_tlv_print(register const u_char *);
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  */
 
+#define TLV_TCHECK(minlen) \
+    TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv;
+
 int
 ldp_tlv_print(register const u_char *tptr) {
 
@@ -273,6 +276,7 @@ ldp_tlv_print(register const u_char *tptr) {
     switch(tlv_type) {
 
     case LDP_TLV_COMMON_HELLO:
+        TLV_TCHECK(4);
         printf("\n\t      Hold Time: %us, Flags: [%s Hello%s]",
                EXTRACT_16BITS(tptr),
                (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
@@ -280,18 +284,22 @@ ldp_tlv_print(register const u_char *tptr) {
         break;
 
     case LDP_TLV_IPV4_TRANSPORT_ADDR:
+        TLV_TCHECK(4);
         printf("\n\t      IPv4 Transport Address: %s", ipaddr_string(tptr));
         break;
 #ifdef INET6
     case LDP_TLV_IPV6_TRANSPORT_ADDR:
+        TLV_TCHECK(16);
         printf("\n\t      IPv6 Transport Address: %s", ip6addr_string(tptr));
         break;
 #endif
     case LDP_TLV_CONFIG_SEQ_NUMBER:
+        TLV_TCHECK(4);
         printf("\n\t      Sequence Number: %u", EXTRACT_32BITS(tptr));
         break;
 
     case LDP_TLV_ADDRESS_LIST:
+        TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
        af = EXTRACT_16BITS(tptr);
        tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
         tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
@@ -300,6 +308,7 @@ ldp_tlv_print(register const u_char *tptr) {
         switch (af) {
         case AFNUM_INET:
            while(tlv_tlen >= sizeof(struct in_addr)) {
+               TCHECK2(*tptr, sizeof(struct in_addr));
                printf(" %s",ipaddr_string(tptr));
                tlv_tlen-=sizeof(struct in_addr);
                tptr+=sizeof(struct in_addr);                
@@ -308,6 +317,7 @@ ldp_tlv_print(register const u_char *tptr) {
 #ifdef INET6
         case AFNUM_INET6:
            while(tlv_tlen >= sizeof(struct in6_addr)) {
+               TCHECK2(*tptr, sizeof(struct in6_addr));
                printf(" %s",ip6addr_string(tptr));
                tlv_tlen-=sizeof(struct in6_addr);
                tptr+=sizeof(struct in6_addr);                
@@ -321,6 +331,7 @@ ldp_tlv_print(register const u_char *tptr) {
        break;
 
     case LDP_TLV_COMMON_SESSION:
+       TLV_TCHECK(8);
        printf("\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
               EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
               (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
@@ -329,50 +340,86 @@ ldp_tlv_print(register const u_char *tptr) {
        break;
 
     case LDP_TLV_FEC:
+        TLV_TCHECK(1);
         fec_type = *tptr;
        printf("\n\t      %s FEC (0x%02x)",
               tok2str(ldp_fec_values, "Unknown", fec_type),
               fec_type);
 
        tptr+=1;
+       tlv_tlen-=1;
        switch(fec_type) {
 
        case LDP_FEC_WILDCARD:
            break;
        case LDP_FEC_PREFIX:
+           TLV_TCHECK(2);
            af = EXTRACT_16BITS(tptr);
-           tptr+=2;
+           tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+           tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
            if (af == AFNUM_INET) {
-               i=decode_prefix4(tptr,buf,sizeof(buf));
-               printf(": IPv4 prefix %s",buf);
+               i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf));
+               if (i == -2)
+                   goto trunc;
+               if (i == -3)
+                   printf(": IPv4 prefix (goes past end of TLV)");
+               else if (i == -1)
+                   printf(": IPv4 prefix (invalid length)");
+               else
+                   printf(": IPv4 prefix %s",buf);
            }
 #ifdef INET6
            else if (af == AFNUM_INET6) {
-               i=decode_prefix6(tptr,buf,sizeof(buf));
-               printf(": IPv6 prefix %s",buf);
+               i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf));
+               if (i == -2)
+                   goto trunc;
+               if (i == -3)
+                   printf(": IPv4 prefix (goes past end of TLV)");
+               else if (i == -1)
+                   printf(": IPv6 prefix (invalid length)");
+               else
+                   printf(": IPv6 prefix %s",buf);
            }
 #endif
+           else
+               printf(": Address family %u prefix", af);
            break;
        case LDP_FEC_HOSTADDRESS:
            break;
        case LDP_FEC_MARTINI_VC:
-            if (!TTEST2(*tptr, 11))
-                goto trunc;
+            /*
+            * According to RFC 4908, the VC info Length field can be zero,
+            * in which case not only are there no interface parameters,
+            * there's no VC ID.
+            */
+            TLV_TCHECK(7);
             vc_info_len = *(tptr+2);
 
+            if (vc_info_len == 0) {
+                printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
+                       tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
+                       EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
+                       EXTRACT_32BITS(tptr+3),
+                       vc_info_len);
+                break;
+            }
+
+            /* Make sure we have the VC ID as well */
+            TLV_TCHECK(11);
            printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
                   tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
                   EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
                    EXTRACT_32BITS(tptr+3),
                   EXTRACT_32BITS(tptr+7),
                    vc_info_len);
+            if (vc_info_len < 4)
+                goto trunc; /* minimum 4, for the VC ID */
+            vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
 
-            if (vc_info_len == 0) /* infinite loop protection */
-                break;
-
+            /* Skip past the fixed information and the VC ID */
             tptr+=11;
-            if (!TTEST2(*tptr, vc_info_len))
-                goto trunc;
+            tlv_tlen-=11;
+            TLV_TCHECK(vc_info_len);
 
             while (vc_info_len > 2) {
                 vc_info_tlv_type = *tptr;
@@ -421,10 +468,12 @@ ldp_tlv_print(register const u_char *tptr) {
        break;
 
     case LDP_TLV_GENERIC_LABEL:
+       TLV_TCHECK(4);
        printf("\n\t      Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
        break;
 
     case LDP_TLV_STATUS:
+       TLV_TCHECK(8);
        ui = EXTRACT_32BITS(tptr);
        tptr+=4;
        printf("\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
@@ -438,6 +487,7 @@ ldp_tlv_print(register const u_char *tptr) {
        break;
 
     case LDP_TLV_FT_SESSION:
+       TLV_TCHECK(8);
        ft_flags = EXTRACT_16BITS(tptr);
        printf("\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
               ft_flags&0x8000 ? "" : "No ",
@@ -456,6 +506,7 @@ ldp_tlv_print(register const u_char *tptr) {
        break;
 
     case LDP_TLV_MTU:
+       TLV_TCHECK(2);
        printf("\n\t      MTU: %u", EXTRACT_16BITS(tptr));
        break;
 
@@ -486,6 +537,10 @@ ldp_tlv_print(register const u_char *tptr) {
 trunc:
     printf("\n\t\t packet exceeded snapshot");
     return 0;
+
+badtlv:
+    printf("\n\t\t TLV contents go past end of TLV");
+    return(tlv_len+4); /* Type & Length fields not included */
 }
 
 void
@@ -546,8 +601,7 @@ ldp_msg_print(register const u_char *pptr) {
 
     while(tlen>0) {
         /* did we capture enough for fully decoding the msg header ? */
-        if (!TTEST2(*tptr, sizeof(struct ldp_msg_header)))
-            goto trunc;
+        TCHECK2(*tptr, sizeof(struct ldp_msg_header));
 
         ldp_msg_header = (const struct ldp_msg_header *)tptr;
         msg_len=EXTRACT_16BITS(ldp_msg_header->length);
@@ -570,8 +624,7 @@ ldp_msg_print(register const u_char *pptr) {
         msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */
 
         /* did we capture enough for fully decoding the message ? */
-        if (!TTEST2(*tptr, msg_len))
-            goto trunc;
+        TCHECK2(*tptr, msg_len);
         hexdump=FALSE;
 
         switch(msg_type) {
index 0ee2f95..8735e58 100644 (file)
@@ -385,9 +385,9 @@ static const struct tok lldp_tia_application_type_values[] = {
     { 0, NULL}
 };
 
-#define LLDP_TIA_NETWORK_POLICY_U_BIT           (1 << 5)
+#define LLDP_TIA_NETWORK_POLICY_X_BIT           (1 << 5)
 #define LLDP_TIA_NETWORK_POLICY_T_BIT           (1 << 6)
-#define LLDP_TIA_NETWORK_POLICY_X_BIT           (1 << 7)
+#define LLDP_TIA_NETWORK_POLICY_U_BIT           (1 << 7)
 
 static const struct tok lldp_tia_network_policy_bits_values[] = {
     { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"},
index 984ebaa..154876f 100644 (file)
@@ -174,7 +174,7 @@ lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) {
     const struct lwapp_transport_header *lwapp_trans_header;
     const struct lwapp_control_header *lwapp_control_header;
     const u_char *tptr;
-    int hexdump,tlen;
+    int  tlen;
     int  msg_tlen;
 
     tptr=pptr;
@@ -247,7 +247,6 @@ lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) {
         /* did we capture enough for fully decoding the message */
         if (!TTEST2(*tptr, msg_tlen))
             goto trunc;
-        hexdump=FALSE;
 
        /* XXX - Decode sub messages for each message */
         switch(lwapp_control_header->msg_type) {
index 1100485..fb62b39 100644 (file)
@@ -160,17 +160,25 @@ trunc:
 }
 
 static int
-ospf6_print_lsaprefix(register const struct lsa6_prefix *lsapp)
+ospf6_print_lsaprefix(const u_int8_t *tptr, u_int lsa_length)
 {
+       const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr;
        u_int wordlen;
        struct in6_addr prefix;
 
-       TCHECK(*lsapp);
+       if (lsa_length < sizeof (*lsapp) - 4)
+               goto trunc;
+       lsa_length -= sizeof (*lsapp) - 4;
+       TCHECK2(*lsapp, sizeof (*lsapp) - 4);
        wordlen = (lsapp->lsa_p_len + 31) / 32;
        if (wordlen * 4 > sizeof(struct in6_addr)) {
                printf(" bogus prefixlen /%d", lsapp->lsa_p_len);
                goto trunc;
        }
+       if (lsa_length < wordlen * 4)
+               goto trunc;
+       lsa_length -= wordlen * 4;
+       TCHECK2(lsapp->lsa_p_prefix, wordlen * 4);
        memset(&prefix, 0, sizeof(prefix));
        memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4);
        printf("\n\t\t%s/%d", ip6addr_string(&prefix),
@@ -194,7 +202,6 @@ trunc:
 static int
 ospf6_print_lsa(register const struct lsa6 *lsap)
 {
-       register const u_char *ls_end, *ls_opt;
        register const struct rlalink6 *rlp;
 #if 0
        register const struct tos_metric *tosp;
@@ -210,34 +217,45 @@ ospf6_print_lsa(register const struct lsa6 *lsap)
        register const u_int32_t *lp;
 #endif
        register u_int prefixes;
-       register int bytelen, length, lsa_length;
+       register int bytelen;
+       register u_int length, lsa_length;
        u_int32_t flags32;
-        u_int8_t *tptr;
+       const u_int8_t *tptr;
 
        if (ospf6_print_lshdr(&lsap->ls_hdr))
                return (1);
        TCHECK(lsap->ls_hdr.ls_length);
         length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length);
+
+       /*
+        * The LSA length includes the length of the header;
+        * it must have a value that's at least that length.
+        * If it does, find the length of what follows the
+        * header.
+        */
+        if (length < sizeof(struct lsa6_hdr))
+               return (1);
         lsa_length = length - sizeof(struct lsa6_hdr);
-       ls_end = (u_char *)lsap + length;
         tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr);
 
        switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) {
        case LS_TYPE_ROUTER | LS_SCOPE_AREA:
+               if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options);
                TCHECK(lsap->lsa_un.un_rla.rla_options);
                 printf("\n\t      Options [%s]",
                        bittok2str(ospf6_option_values, "none",
                                   EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)));
-
-               TCHECK(lsap->lsa_un.un_rla.rla_flags);
                 printf(", RLA-Flags [%s]",
                        bittok2str(ospf6_rla_flag_values, "none",
                                   lsap->lsa_un.un_rla.rla_flags));
 
-
-               TCHECK(lsap->lsa_un.un_rla.rla_link);
                rlp = lsap->lsa_un.un_rla.rla_link;
-               while (rlp + 1 <= (struct rlalink6 *)ls_end) {
+               while (lsa_length != 0) {
+                       if (lsa_length < sizeof (*rlp))
+                               return (1);
+                       lsa_length -= sizeof (*rlp);
                        TCHECK(*rlp);
                        switch (rlp->link_type) {
 
@@ -276,13 +294,20 @@ ospf6_print_lsa(register const struct lsa6 *lsap)
                break;
 
        case LS_TYPE_NETWORK | LS_SCOPE_AREA:
+               if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options);
                TCHECK(lsap->lsa_un.un_nla.nla_options);
                 printf("\n\t      Options [%s]",
                        bittok2str(ospf6_option_values, "none",
                                   EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)));
+
                printf("\n\t      Connected Routers:");
                ap = lsap->lsa_un.un_nla.nla_router;
-               while ((u_char *)ap < ls_end) {
+               while (lsa_length != 0) {
+                       if (lsa_length < sizeof (*ap))
+                               return (1);
+                       lsa_length -= sizeof (*ap);
                        TCHECK(*ap);
                        printf("\n\t\t%s", ipaddr_string(ap));
                        ++ap;
@@ -290,18 +315,27 @@ ospf6_print_lsa(register const struct lsa6 *lsap)
                break;
 
        case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
+               if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric);
                TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric);
                printf(", metric %u",
                        EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
-               lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix;
-               while (lsapp + sizeof(lsapp) <= (struct lsa6_prefix *)ls_end) {
-                       bytelen = ospf6_print_lsaprefix(lsapp);
-                       if (bytelen)
+
+               tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix;
+               while (lsa_length != 0) {
+                       bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+                       if (bytelen < 0)
                                goto trunc;
-                       lsapp = (struct lsa6_prefix *)(((u_char *)lsapp) + bytelen);
+                       lsa_length -= bytelen;
+                       tptr += bytelen;
                }
                break;
-       case LS_SCOPE_AS | LS_TYPE_ASE:
+
+       case LS_TYPE_ASE | LS_SCOPE_AS:
+               if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric);
                TCHECK(lsap->lsa_un.un_asla.asla_metric);
                flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric);
                 printf("\n\t     Flags [%s]",
@@ -309,48 +343,63 @@ ospf6_print_lsa(register const struct lsa6 *lsap)
                printf(" metric %u",
                       EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) &
                       ASLA_MASK_METRIC);
-               lsapp = lsap->lsa_un.un_asla.asla_prefix;
-               bytelen = ospf6_print_lsaprefix(lsapp);
+
+               tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix;
+               lsapp = (struct lsa6_prefix *)tptr;
+               bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
                if (bytelen < 0)
                        goto trunc;
-               if ((ls_opt = (u_char *)(((u_char *)lsapp) + bytelen)) < ls_end) {
-                       struct in6_addr *fwdaddr6;
+               lsa_length -= bytelen;
+               tptr += bytelen;
 
-                       if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
-                               fwdaddr6 = (struct in6_addr *)ls_opt;
-                               TCHECK(*fwdaddr6);
-                               printf(" forward %s",
-                                      ip6addr_string(fwdaddr6));
-
-                               ls_opt += sizeof(struct in6_addr);
-                       }
-
-                       if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
-                               TCHECK(*(u_int32_t *)ls_opt);
-                               printf(" tag %s",
-                                      ipaddr_string((u_int32_t *)ls_opt));
+               if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
+                       struct in6_addr *fwdaddr6;
 
-                               ls_opt += sizeof(u_int32_t);
-                       }
+                       fwdaddr6 = (struct in6_addr *)tptr;
+                       if (lsa_length < sizeof (*fwdaddr6))
+                               return (1);
+                       lsa_length -= sizeof (*fwdaddr6);
+                       TCHECK(*fwdaddr6);
+                       printf(" forward %s",
+                              ip6addr_string(fwdaddr6));
+                       tptr += sizeof(*fwdaddr6);
+               }
 
-                       if (lsapp->lsa_p_metric) {
-                               TCHECK(*(u_int32_t *)ls_opt);
-                               printf(" RefLSID: %s",
-                                      ipaddr_string((u_int32_t *)ls_opt));
+               if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
+                       if (lsa_length < sizeof (u_int32_t))
+                               return (1);
+                       lsa_length -= sizeof (u_int32_t);
+                       TCHECK(*(u_int32_t *)tptr);
+                       printf(" tag %s",
+                              ipaddr_string((u_int32_t *)tptr));
+                       tptr += sizeof(u_int32_t);
+               }
 
-                               ls_opt += sizeof(u_int32_t);
-                       }
+               if (lsapp->lsa_p_metric) {
+                       if (lsa_length < sizeof (u_int32_t))
+                               return (1);
+                       lsa_length -= sizeof (u_int32_t);
+                       TCHECK(*(u_int32_t *)tptr);
+                       printf(" RefLSID: %s",
+                              ipaddr_string((u_int32_t *)tptr));
+                       tptr += sizeof(u_int32_t);
                }
                break;
 
        case LS_TYPE_LINK:
                /* Link LSA */
                llsap = &lsap->lsa_un.un_llsa;
-               TCHECK(llsap->llsa_options);
+               if (lsa_length < sizeof (llsap->llsa_priandopt))
+                       return (1);
+               lsa_length -= sizeof (llsap->llsa_priandopt);
+               TCHECK(llsap->llsa_priandopt);
                 printf("\n\t      Options [%s]",
                        bittok2str(ospf6_option_values, "none",
                                   EXTRACT_32BITS(&llsap->llsa_options)));
-               TCHECK(llsap->llsa_nprefix);
+
+               if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
+                       return (1);
+               lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
                 prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
                printf("\n\t      Priority %d, Link-local address %s, Prefixes %d:",
                        llsap->llsa_priority,
@@ -358,57 +407,63 @@ ospf6_print_lsa(register const struct lsa6 *lsap)
                        prefixes);
 
                tptr = (u_int8_t *)llsap->llsa_prefix;
-                while (prefixes > 0) {
-                    lsapp = (struct lsa6_prefix *)tptr;
-                    if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) {
-                        goto trunc;
-                    }
-                    prefixes--;
-                    tptr += bytelen;
-                }
+               while (prefixes > 0) {
+                       bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+                       if (bytelen < 0)
+                               goto trunc;
+                       prefixes--;
+                       lsa_length -= bytelen;
+                       tptr += bytelen;
+               }
                break;
 
        case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
                /* Intra-Area-Prefix LSA */
+               if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid);
                TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
                ospf6_print_ls_type(
                        EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype),
                        &lsap->lsa_un.un_intra_ap.intra_ap_lsid);
+
+               if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix))
+                       return (1);
+               lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
                TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
                 prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
                printf("\n\t      Prefixes %d:", prefixes);
 
-                tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
-
-                while (prefixes > 0) {
-                    lsapp = (struct lsa6_prefix *)tptr;
-                    if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) {
-                        goto trunc;
-                    }
-                    prefixes--;
-                    tptr += bytelen;
-                }
+               tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
+               while (prefixes > 0) {
+                       bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+                       if (bytelen < 0)
+                               goto trunc;
+                       prefixes--;
+                       lsa_length -= bytelen;
+                       tptr += bytelen;
+               }
                break;
 
         case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL:
                 if (ospf_print_grace_lsa(tptr, lsa_length) == -1) {
                     return 1;
                 }
-            
-            break;
+                break;
 
         case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL:
-            if (ospf_print_te_lsa(tptr, lsa_length) == -1) {
-                return 1;
-            }
-            break;
+                if (ospf_print_te_lsa(tptr, lsa_length) == -1) {
+                    return 1;
+                }
+                break;
 
        default:
-            if(!print_unknown_data(tptr,
-                                   "\n\t      ",
-                                   lsa_length)) {
-                return (1);
-            }
+                if(!print_unknown_data(tptr,
+                                       "\n\t      ",
+                                       lsa_length)) {
+                    return (1);
+                }
+                break;
        }
 
        return (0);
index 0f558af..e0cca12 100644 (file)
@@ -667,7 +667,7 @@ pimv2_print(register const u_char *bp, register u_int len, u_int cksum)
 
                        case PIMV2_HELLO_OPTION_LANPRUNEDELAY:
                                if (olen != 4) {
-                                       (void)printf("ERROR: Option Lenght != 4 Bytes (%u)", olen);
+                                       (void)printf("ERROR: Option Length != 4 Bytes (%u)", olen);
                                } else {
                                        char t_bit;
                                        u_int16_t lan_delay, override_interval;
@@ -690,7 +690,7 @@ pimv2_print(register const u_char *bp, register u_int len, u_int cksum)
                                     printf("%u", EXTRACT_32BITS(bp));
                                     break;
                                 default:
-                                    printf("ERROR: Option Lenght != 4 Bytes (%u)", olen);
+                                    printf("ERROR: Option Length != 4 Bytes (%u)", olen);
                                     break;
                                 }
                                 break;
index 7abc787..bcc976c 100644 (file)
@@ -70,6 +70,7 @@ enum {
        PPPOE_AC_COOKIE = 0x0104,
        PPPOE_VENDOR = 0x0105,
        PPPOE_RELAY_SID = 0x0110,
+       PPPOE_MAX_PAYLOAD = 0x0120,
        PPPOE_SERVICE_NAME_ERROR = 0x0201,
        PPPOE_AC_SYSTEM_ERROR = 0x0202,
        PPPOE_GENERIC_ERROR = 0x0203
@@ -83,6 +84,7 @@ static struct tok pppoetag2str[] = {
        { PPPOE_AC_COOKIE, "AC-Cookie" },
        { PPPOE_VENDOR, "Vendor-Specific" },
        { PPPOE_RELAY_SID, "Relay-Session-ID" },
+       { PPPOE_MAX_PAYLOAD, "PPP-Max-Payload" },
        { PPPOE_SERVICE_NAME_ERROR, "Service-Name-Error" },
        { PPPOE_AC_SYSTEM_ERROR, "AC-System-Error" },
        { PPPOE_GENERIC_ERROR, "Generic-Error" },
index 64cb7de..c5b1fdd 100644 (file)
@@ -102,11 +102,11 @@ rrcp_print(netdissect_options *ndo,
         ND_PRINT((ndo, "%s > %s, %s %s",
                etheraddr_string(ESRC(ep)),
                etheraddr_string(EDST(ep)),
-               tok2strbuf(proto_values,"RRCP-0x%02d",rrcp_proto,proto_str,sizeof(proto_str)),
+               tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)),
                ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"));
        if (rrcp_proto==1){
            ND_PRINT((ndo, ": %s",
-                    tok2strbuf(opcode_values,"unknown opcode (0x%02d)",rrcp_opcode,opcode_str,sizeof(opcode_str))));
+                    tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str))));
        }
        if (rrcp_opcode==1 || rrcp_opcode==2){
            ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6);
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/contrib/tcpdump/print-tipc.c b/contrib/tcpdump/print-tipc.c
new file mode 100644 (file)
index 0000000..8f2f769
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+    "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "ether.h"
+#include "ethertype.h"
+#include "extract.h"                   /* must come after interface.h */
+
+/*
+ * Transparent Inter-Process Communication (TIPC) protocol.
+ *
+ *     http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html
+ *     http://tipc.sourceforge.net/doc/tipc_message_formats.html
+ */
+
+#define TIPC_USER_LOW_IMPORTANCE       0
+#define TIPC_USER_MEDIUM_IMPORTANCE    1
+#define TIPC_USER_HIGH_IMPORTANCE      2
+#define TIPC_USER_CRITICAL_IMPORTANCE  3
+#define TIPC_USER_BCAST_PROTOCOL       5
+#define TIPC_USER_MSG_BUNDLER          6
+#define TIPC_USER_LINK_PROTOCOL                7
+#define TIPC_USER_CONN_MANAGER         8
+#define TIPC_USER_CHANGEOVER_PROTOCOL  10
+#define TIPC_USER_NAME_DISTRIBUTOR     11
+#define TIPC_USER_MSG_FRAGMENTER       12
+#define TIPC_USER_LINK_CONFIG          13
+
+#define TIPC_CONN_MSG                  0
+#define TIPC_DIRECT_MSG                        1
+#define TIPC_NAMED_MSG                 2
+#define TIPC_MCAST_MSG                 3
+
+#define TIPC_ZONE(addr)                (((addr) >> 24) & 0xFF)
+#define TIPC_CLUSTER(addr)     (((addr) >> 12) & 0xFFF)
+#define TIPC_NODE(addr)                (((addr) >> 0) & 0xFFF)
+
+struct tipc_pkthdr {
+       u_int32_t w0;
+       u_int32_t w1;
+};
+
+#define TIPC_VER(w0)           (((w0) >> 29) & 0x07)
+#define TIPC_USER(w0)          (((w0) >> 25) & 0x0F)
+#define TIPC_HSIZE(w0)         (((w0) >> 21) & 0x0F)
+#define TIPC_MSIZE(w0)         (((w0) >> 0) & 0xFFFF)
+#define TIPC_MTYPE(w1)         (((w1) >> 29) & 0x07)
+#define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF)
+#define TIPC_LINK_ACK(w2)      (((w2) >> 16) & 0xFFFF)
+#define TIPC_LINK_SEQ(w2)      (((w2) >> 0) & 0xFFFF)
+
+static const struct tok tipcuser_values[] = {
+    { TIPC_USER_LOW_IMPORTANCE,      "Low Importance Data payload" },
+    { TIPC_USER_MEDIUM_IMPORTANCE,   "Medium Importance Data payload" },
+    { TIPC_USER_HIGH_IMPORTANCE,     "High Importance Data payload" },
+    { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" },
+    { TIPC_USER_BCAST_PROTOCOL,      "Broadcast Link Protocol internal" },
+    { TIPC_USER_MSG_BUNDLER,         "Message Bundler Protocol internal" },
+    { TIPC_USER_LINK_PROTOCOL,       "Link State Protocol internal" },
+    { TIPC_USER_CONN_MANAGER,        "Connection Manager internal" },
+    { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" },
+    { TIPC_USER_NAME_DISTRIBUTOR,    "Name Table Update Protocol internal" },
+    { TIPC_USER_MSG_FRAGMENTER,      "Message Fragmentation Protocol internal" },
+    { TIPC_USER_LINK_CONFIG,         "Neighbor Detection Protocol internal" },
+    { 0, NULL }
+};
+
+static const struct tok tipcmtype_values[] = {
+    { TIPC_CONN_MSG,   "CONN_MSG" },
+    { TIPC_DIRECT_MSG, "MCAST_MSG" },
+    { TIPC_NAMED_MSG,  "NAMED_MSG" },
+    { TIPC_MCAST_MSG,  "DIRECT_MSG" },
+    { 0, NULL }
+};
+
+static const struct tok tipc_linkconf_mtype_values[] = {
+    { 0,   "Link request" },
+    { 1,   "Link response" },
+    { 0, NULL }
+};
+
+struct payload_tipc_pkthdr {
+       u_int32_t w0;
+       u_int32_t w1;
+       u_int32_t w2;
+       u_int32_t prev_node;
+       u_int32_t orig_port;
+       u_int32_t dest_port;
+       u_int32_t orig_node;
+       u_int32_t dest_node;
+       u_int32_t name_type;
+       u_int32_t w9;
+       u_int32_t wA;
+};
+
+struct  internal_tipc_pkthdr {
+       u_int32_t w0;
+       u_int32_t w1;
+       u_int32_t w2;
+       u_int32_t prev_node;
+       u_int32_t w4;
+       u_int32_t w5;
+       u_int32_t orig_node;
+       u_int32_t dest_node;
+       u_int32_t trans_seq;
+       u_int32_t w9;
+};
+
+#define TIPC_SEQ_GAP(w1)       (((w1) >> 16) & 0x1FFF)
+#define TIPC_BC_GAP_AFTER(w2)  (((w2) >> 16) & 0xFFFF)
+#define TIPC_BC_GAP_TO(w2)     (((w2) >> 0) & 0xFFFF)
+#define TIPC_LAST_SENT_FRAG(w4)        (((w4) >> 16) & 0xFFFF)
+#define TIPC_NEXT_SENT_FRAG(w4)        (((w4) >> 0) & 0xFFFF)
+#define TIPC_SESS_NO(w5)       (((w5) >> 16) & 0xFFFF)
+#define TIPC_MSG_CNT(w9)       (((w9) >> 16) & 0xFFFF)
+#define TIPC_LINK_TOL(w9)      (((w9) >> 0) & 0xFFFF)
+
+struct link_conf_tipc_pkthdr {
+       u_int32_t w0;
+       u_int32_t w1;
+       u_int32_t dest_domain;
+       u_int32_t prev_node;
+       u_int32_t ntwrk_id;
+       u_int32_t w5;
+       u_int8_t media_address[16];
+};
+
+#define TIPC_NODE_SIG(w1)      (((w1) >> 0) & 0xFFFF)
+#define TIPC_MEDIA_ID(w5)      (((w5) >> 0) & 0xFF)
+
+static void
+print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap)
+{
+       u_int32_t w0, w1, w2;
+       u_int user;
+       u_int hsize;
+       u_int msize;
+       u_int mtype;
+       u_int broadcast_ack;
+       u_int link_ack;
+       u_int link_seq;
+       u_int prev_node;
+       u_int orig_port;
+       u_int dest_port;
+       u_int orig_node;
+       u_int dest_node;
+
+       ND_TCHECK(ap->dest_port);
+       w0 = EXTRACT_32BITS(&ap->w0);
+       user = TIPC_USER(w0);
+       hsize = TIPC_HSIZE(w0);
+       msize = TIPC_MSIZE(w0);
+       w1 = EXTRACT_32BITS(&ap->w1);
+       mtype = TIPC_MTYPE(w1);
+       prev_node = EXTRACT_32BITS(&ap->prev_node);
+       orig_port = EXTRACT_32BITS(&ap->orig_port);
+       dest_port = EXTRACT_32BITS(&ap->dest_port);
+       if (hsize <= 6) {
+               ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+                   TIPC_VER(w0),
+                   TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+                   orig_port, dest_port,
+                   hsize*4, msize,
+                   tok2str(tipcuser_values, "unknown", user),
+                   tok2str(tipcmtype_values, "Unknown", mtype)));
+       } else {
+               ND_TCHECK(ap->dest_node);
+               orig_node = EXTRACT_32BITS(&ap->orig_node);
+               dest_node = EXTRACT_32BITS(&ap->dest_node);
+               ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+                   TIPC_VER(w0),
+                   TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
+                   orig_port,
+                   TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
+                   dest_port,
+                   hsize*4, msize,
+                   tok2str(tipcuser_values, "unknown", user),
+                   tok2str(tipcmtype_values, "Unknown", mtype)));
+
+               if (ndo->ndo_vflag) {
+                       broadcast_ack = TIPC_BROADCAST_ACK(w1);
+                       w2 = EXTRACT_32BITS(&ap->w2);
+                       link_ack = TIPC_LINK_ACK(w2);
+                       link_seq = TIPC_LINK_SEQ(w2);
+                       ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u",
+                           TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+                           broadcast_ack, link_ack, link_seq));
+               }
+       }
+       return;
+
+trunc:
+       ND_PRINT((ndo, "[|TIPC]"));
+}
+        
+static void
+print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap)
+{
+       u_int32_t w0, w1, w2, w4, w5, w9;
+       u_int user;
+       u_int hsize;
+       u_int msize;
+       u_int mtype;
+       u_int seq_gap;
+       u_int broadcast_ack;
+       u_int bc_gap_after;
+       u_int bc_gap_to;
+       u_int prev_node;
+       u_int last_sent_frag;
+       u_int next_sent_frag;
+       u_int sess_no;
+       u_int orig_node;
+       u_int dest_node;
+       u_int trans_seq;
+       u_int msg_cnt;
+       u_int link_tol;
+
+       ND_TCHECK(ap->dest_node);
+       w0 = EXTRACT_32BITS(&ap->w0);
+       user = TIPC_USER(w0);
+       hsize = TIPC_HSIZE(w0);
+       msize = TIPC_MSIZE(w0);
+       w1 = EXTRACT_32BITS(&ap->w1);
+       mtype = TIPC_MTYPE(w1);
+       orig_node = EXTRACT_32BITS(&ap->orig_node);
+       dest_node = EXTRACT_32BITS(&ap->dest_node);
+       ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)",
+           TIPC_VER(w0),
+           TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
+           TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
+           hsize*4, msize,
+           tok2str(tipcuser_values, "unknown", user),
+           tok2str(tipcmtype_values, "Unknown", mtype), w1));
+
+       if (ndo->ndo_vflag) {
+               ND_TCHECK(*ap);
+               seq_gap = TIPC_SEQ_GAP(w1);
+               broadcast_ack = TIPC_BROADCAST_ACK(w1);
+               w2 = EXTRACT_32BITS(&ap->w2);
+               bc_gap_after = TIPC_BC_GAP_AFTER(w2);
+               bc_gap_to = TIPC_BC_GAP_TO(w2);
+               prev_node = EXTRACT_32BITS(&ap->prev_node);
+               w4 = EXTRACT_32BITS(&ap->w4);
+               last_sent_frag = TIPC_LAST_SENT_FRAG(w4);
+               next_sent_frag = TIPC_NEXT_SENT_FRAG(w4);
+               w5 = EXTRACT_32BITS(&ap->w5);
+               sess_no = TIPC_SESS_NO(w5);
+               trans_seq = EXTRACT_32BITS(&ap->trans_seq);
+               w9 = EXTRACT_32BITS(&ap->w9);
+               msg_cnt = TIPC_MSG_CNT(w9);
+               link_tol = TIPC_LINK_TOL(w9);
+               ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u,  Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u",
+                   TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+                   sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to,
+                   last_sent_frag, next_sent_frag, trans_seq, msg_cnt,
+                   link_tol));
+       }
+       return;
+
+trunc:
+       ND_PRINT((ndo, "[|TIPC]"));
+}
+
+static void
+print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap)
+{
+       u_int32_t w0, w1, w5;
+       u_int user;
+       u_int hsize;
+       u_int msize;
+       u_int mtype;
+       u_int node_sig;
+       u_int prev_node;
+       u_int dest_domain;
+       u_int ntwrk_id;
+       u_int media_id;
+
+       ND_TCHECK(ap->prev_node);
+       w0 = EXTRACT_32BITS(&ap->w0);
+       user = TIPC_USER(w0);
+       hsize = TIPC_HSIZE(w0);
+       msize = TIPC_MSIZE(w0);
+       w1 = EXTRACT_32BITS(&ap->w1);
+       mtype = TIPC_MTYPE(w1);
+       prev_node = EXTRACT_32BITS(&ap->prev_node);
+       dest_domain = EXTRACT_32BITS(&ap->dest_domain);
+       prev_node = EXTRACT_32BITS(&ap->prev_node);
+
+       ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+           TIPC_VER(w0),
+           TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+           TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain),
+           hsize*4, msize,
+           tok2str(tipcuser_values, "unknown", user),
+           tok2str(tipc_linkconf_mtype_values, "Unknown", mtype)));
+       if (ndo->ndo_vflag) {
+               ND_TCHECK(ap->w5);
+               node_sig = TIPC_NODE_SIG(w1);
+               ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id);
+               w5 = EXTRACT_32BITS(&ap->w5);
+               media_id = TIPC_MEDIA_ID(w5);
+               ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u",
+                   node_sig, ntwrk_id, media_id));
+       }
+       return;
+
+trunc:
+       ND_PRINT((ndo, "[|TIPC]"));
+}
+
+void
+tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_,
+    u_int caplen _U_)
+{
+       const struct tipc_pkthdr *ap;
+       u_int32_t w0;
+       u_int user;
+
+       ap = (struct tipc_pkthdr *)bp;
+       ND_TCHECK(ap->w0);
+       w0 = EXTRACT_32BITS(&ap->w0);
+       user = TIPC_USER(w0);
+
+       switch (user)
+       {
+               case TIPC_USER_LOW_IMPORTANCE:
+               case TIPC_USER_MEDIUM_IMPORTANCE:
+               case TIPC_USER_HIGH_IMPORTANCE:
+               case TIPC_USER_CRITICAL_IMPORTANCE:
+               case TIPC_USER_NAME_DISTRIBUTOR:
+               case TIPC_USER_CONN_MANAGER:
+                       print_payload(ndo, (struct payload_tipc_pkthdr *)bp);
+                       break;                   
+
+               case TIPC_USER_LINK_CONFIG:
+                       print_link_conf(ndo, (struct link_conf_tipc_pkthdr *)bp);
+                       break;
+
+               case TIPC_USER_BCAST_PROTOCOL:
+               case TIPC_USER_MSG_BUNDLER:
+               case TIPC_USER_LINK_PROTOCOL:
+               case TIPC_USER_CHANGEOVER_PROTOCOL:
+               case TIPC_USER_MSG_FRAGMENTER:
+                       print_internal(ndo, (struct internal_tipc_pkthdr *)bp);
+                       break;
+
+       }
+       return;
+
+trunc:
+       ND_PRINT((ndo, "[|TIPC]"));
+}
+
+/*
+ * Local Variables:
+ * c-style: bsd
+ * End:
+ */
+
index aabda77..a9387f1 100644 (file)
@@ -200,7 +200,8 @@ Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN
 notation.
 .TP
 .B \-B
-Set the operating system capture buffer size to \fIbuffer_size\fP.
+Set the operating system capture buffer size to \fIbuffer_size\fP, in
+units of KiB (1024 bytes).
 .TP
 .B \-c
 Exit after receiving \fIcount\fP packets.
@@ -392,9 +393,37 @@ Make stdout line buffered.
 Useful if you want to see the data
 while capturing it.
 E.g.,
-.br
-``tcpdump\ \ \-l\ \ |\ \ tee dat'' or
-``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''.
+.IP
+.RS
+.RS
+.nf
+\fBtcpdump \-l | tee dat\fP
+.fi
+.RE
+.RE
+.IP
+or
+.IP
+.RS
+.RS
+.nf
+\fBtcpdump \-l > dat & tail \-f dat\fP
+.fi
+.RE
+.RE
+.IP
+Note that on Windows,``line buffered'' means ``unbuffered'', so that
+WinDump will write each character individually if
+.B \-l
+is specified.
+.IP
+.B \-U
+is similar to
+.B \-l
+in its behavior, but it will cause output to be ``packet-buffered'', so
+that the output is written to stdout at the end of each packet rather
+than at the end of each line; this is buffered on all platforms,
+including Windows.
 .TP
 .B \-L
 List the known data link types for the interface, in the specified mode,
@@ -511,11 +540,20 @@ on each dump line.
 Print undecoded NFS handles.
 .TP
 .B \-U
-Make output saved via the
+If the
+.B \-w
+option is not specified, make the printed packet output
+``packet-buffered''; i.e., as the description of the contents of each
+packet is printed, it will be written to the standard output, rather
+than, when not writing to a terminal, being written only when the output
+buffer fills.
+.IP
+If the
 .B \-w
-option ``packet-buffered''; i.e., as each packet is saved, it will be
-written to the output file, rather than being written only when the
-output buffer fills.
+option is specified, make the saved raw packet output
+``packet-buffered''; i.e., as each packet is saved, it will be written
+to the output file, rather than being written only when the output
+buffer fills.
 .IP
 The
 .B \-U
@@ -557,6 +595,13 @@ Write the raw packets to \fIfile\fR rather than parsing and printing
 them out.
 They can later be printed with the \-r option.
 Standard output is used if \fIfile\fR is ``-''.
+.IP
+This output will be buffered if written to a file or pipe, so a program
+reading from the file or pipe may not see packets for an arbitrary
+amount of time after they are received.  Use the
+.B \-U
+flag to cause packets to be written as soon as they are received.
+.IP
 See
 .BR pcap-savefile (@MAN_FILE_FORMATS@)
 for a description of the file format.
index ac35b2b..587ed32 100644 (file)
@@ -87,6 +87,12 @@ extern int SIZE_BUF;
 #define NAME_MAX 255
 #endif
 
+#ifdef SIGINFO
+#define SIGNAL_REQ_INFO SIGINFO
+#elif SIGUSR1
+#define SIGNAL_REQ_INFO SIGUSR1
+#endif
+
 netdissect_options Gndo;
 netdissect_options *gndo = &Gndo;
 
@@ -119,7 +125,7 @@ static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
      __attribute__ ((noreturn, format (printf, 2, 3)));
 static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int);
 #endif
 
@@ -1349,13 +1355,13 @@ main(int argc, char **argv)
                pcap_userdata = (u_char *)&printinfo;
        }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
        /*
         * We can't get statistics when reading from a file rather
         * than capturing from a device.
         */
        if (RFileName == NULL)
-               (void)setsignal(SIGINFO, requestinfo);
+               (void)setsignal(SIGNAL_REQ_INFO, requestinfo);
 #endif
 
        if (vflag > 0 && WFileName) {
@@ -1844,7 +1850,7 @@ default_print(const u_char *bp, u_int length)
        ndo_default_print(gndo, bp, length);
 }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int signo _U_)
 {
        if (infodelay)