]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-dtp.c
bgp: Parse BGP extended message support capability
[tcpdump] / print-dtp.c
index 4c3d6c780eac1d1fa9a2e5de730ff1825425b2c3..a1ae4ba4d5aa047ec6efc81ad12328fa1d09aa51 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
 #define DTP_NEIGHBOR_TLV               0x0004
 
 static const struct tok dtp_tlv_values[] = {
-    { DTP_DOMAIN_TLV, "Domain TLV"},
-    { DTP_STATUS_TLV, "Status TLV"},
-    { DTP_DTP_TYPE_TLV, "DTP type TLV"},
-    { DTP_NEIGHBOR_TLV, "Neighbor TLV"},
+    { DTP_DOMAIN_TLV, "Domain},
+    { DTP_STATUS_TLV, "Status},
+    { DTP_DTP_TYPE_TLV, "DTP type},
+    { DTP_NEIGHBOR_TLV, "Neighbor},
     { 0, NULL}
 };
 
 void
-dtp_print(netdissect_options *ndo, const u_char *pptr, u_int length)
+dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length)
 {
-    int type, len;
-    const u_char *tptr;
-
     ndo->ndo_protocol = "dtp";
-    if (length < DTP_HEADER_LEN)
-        goto trunc;
-
-    tptr = pptr;
-
-    ND_TCHECK_LEN(tptr, DTP_HEADER_LEN);
+    if (length < DTP_HEADER_LEN) {
+        ND_PRINT("[zero packet length]");
+        goto invalid;
+    }
 
     ND_PRINT("DTPv%u, length %u",
            GET_U_1(tptr),
@@ -68,10 +64,15 @@ dtp_print(netdissect_options *ndo, const u_char *pptr, u_int length)
     }
 
     tptr += DTP_HEADER_LEN;
+    length -= DTP_HEADER_LEN;
 
-    while (tptr < (pptr+length)) {
+    while (length) {
+        uint16_t type, len;
 
-        ND_TCHECK_4(tptr);
+        if (length < 4) {
+            ND_PRINT("[%u bytes remaining]", length);
+            goto invalid;
+        }
        type = GET_BE_U_2(tptr);
         len  = GET_BE_U_2(tptr + 2);
        /* XXX: should not be but sometimes it is, see the test captures */
@@ -82,40 +83,40 @@ dtp_print(netdissect_options *ndo, const u_char *pptr, u_int length)
                type, len);
 
         /* infinite loop check */
-        if (len < 4)
+        if (len < 4 || len > length) {
+            ND_PRINT("[invalid TLV length %u]", len);
             goto invalid;
-        ND_TCHECK_LEN(tptr, len);
+        }
 
         switch (type) {
        case DTP_DOMAIN_TLV:
                ND_PRINT(", ");
-               nd_printzp(ndo, tptr+4, len-4, pptr+length);
+               nd_printjnp(ndo, tptr+4, len-4);
                break;
 
        case DTP_STATUS_TLV:
        case DTP_DTP_TYPE_TLV:
-                if (len < 5)
+                if (len != 5)
                     goto invalid;
                 ND_PRINT(", 0x%x", GET_U_1(tptr + 4));
                 break;
 
        case DTP_NEIGHBOR_TLV:
-                if (len < 10)
+                if (len != 10)
                     goto invalid;
                 ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4));
                 break;
 
         default:
+            ND_TCHECK_LEN(tptr, len);
             break;
         }
         tptr += len;
+        length -= len;
     }
-
     return;
 
  invalid:
     nd_print_invalid(ndo);
-    return;
- trunc:
-    nd_print_trunc(ndo);
+    ND_TCHECK_LEN(tptr, length);
 }