]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Clean up IS-IS printing.
authorGuy Harris <[email protected]>
Sat, 3 Jun 2017 03:05:12 +0000 (20:05 -0700)
committerDenis Ovsienko <[email protected]>
Fri, 1 Sep 2017 21:19:37 +0000 (22:19 +0100)
Check the packet length as well as the captured length.

Don't have separate "non-verbose" and "verbose" cases, so we don't
duplicate the length checks.

Print the right value for some length check errors.

Clean up the TLV parsing code - keep parsing until we completely run out
of data, but make sure, before we look at the TLV header, that we
haven't run past the end of the packet as well as that we haven't run
past the end of the captured data.

In the OSI checksum routine:

Have it take an unsigned length, so we don't have to worry about it
being negative.

Use ND_TTEST2 to check whether the checksum offset is within the
bounds of the packet.

If we don't have all the packet data to checksum, just report
"unverified", don't return a "truncated" error.

print-isoclns.c
tests/isis-seg-fault-2-v.out
tests/isis-seg-fault-3-v.out
tests/isis_infloop-v.out

index d08085faf2e2e56c6d05e29d935d0a354902ec24..9c279c79b70c420a5391194b12a1c205ad264aae 100644 (file)
@@ -564,8 +564,8 @@ struct isis_tlv_ptp_adj {
     uint8_t neighbor_extd_local_circuit_id[4];
 };
 
-static int osi_print_cksum(netdissect_options *, const uint8_t *pptr,
-                           uint16_t checksum, int checksum_offset, int length);
+static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
+                           uint16_t checksum, int checksum_offset, u_int length);
 static int clnp_print(netdissect_options *, const uint8_t *, u_int);
 static void esis_print(netdissect_options *, const uint8_t *, u_int);
 static int isis_print(netdissect_options *, const uint8_t *, u_int);
@@ -865,9 +865,8 @@ clnp_print(netdissect_options *ndo,
                EXTRACT_16BITS(clnp_header->segment_length),
                EXTRACT_16BITS(clnp_header->cksum)));
 
-        if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
-                            clnp_header->length_indicator) == 0)
-                goto trunc;
+        osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
+                        clnp_header->length_indicator);
 
         ND_PRINT((ndo, "\n\tFlags [%s]",
                bittok2str(clnp_flag_values, "none", clnp_flags)));
@@ -1153,8 +1152,7 @@ esis_print(netdissect_options *ndo,
         ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ));
         ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)));
 
-        if (osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li) == 0)
-                goto trunc;
+        osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
 
         ND_PRINT((ndo, ", holding time: %us, length indicator: %u",
                   EXTRACT_16BITS(esis_header->holdtime), li));
@@ -2164,6 +2162,8 @@ isis_print(netdissect_options *ndo,
                  TLV verification */
     isis_header = (const struct isis_common_header *)p;
     ND_TCHECK(*isis_header);
+    if (length < ISIS_COMMON_HEADER_SIZE)
+        goto trunc;
     pptr = p+(ISIS_COMMON_HEADER_SIZE);
     header_iih_lan = (const struct isis_iih_lan_header *)pptr;
     header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
@@ -2194,6 +2194,16 @@ isis_print(netdissect_options *ndo,
        return (0);
     }
 
+    if (length < isis_header->fixed_len) {
+       ND_PRINT((ndo, "fixed header length %u > packet length %u", isis_header->fixed_len, length));
+       return (0);
+    }
+
+    if (isis_header->fixed_len < ISIS_COMMON_HEADER_SIZE) {
+       ND_PRINT((ndo, "fixed header length %u < minimum header size %u", isis_header->fixed_len, ISIS_COMMON_HEADER_SIZE));
+       return (0);
+    }
+
     max_area = isis_header->max_area;
     switch(max_area) {
     case 0:
@@ -2236,254 +2246,255 @@ isis_print(netdissect_options *ndo,
     pdu_type=isis_header->pdu_type;
 
     /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
-    if (ndo->ndo_vflag < 1) {
+    if (ndo->ndo_vflag == 0) {
         ND_PRINT((ndo, "%s%s",
                ndo->ndo_eflag ? "" : ", ",
                tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)));
+    } else {
+        /* ok they seem to want to know everything - lets fully decode it */
+        ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
 
-       switch (pdu_type) {
-
-       case ISIS_PDU_L1_LAN_IIH:
-       case ISIS_PDU_L2_LAN_IIH:
-           ND_TCHECK(*header_iih_lan);
-           ND_PRINT((ndo, ", src-id %s",
-                   isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
-           ND_PRINT((ndo, ", lan-id %s, prio %u",
-                   isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
-                   header_iih_lan->priority));
-           break;
-       case ISIS_PDU_PTP_IIH:
-           ND_TCHECK(*header_iih_ptp);
-           ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
-           break;
-       case ISIS_PDU_L1_LSP:
-       case ISIS_PDU_L2_LSP:
-           ND_TCHECK(*header_lsp);
-           ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
-                  isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
-                  EXTRACT_32BITS(header_lsp->sequence_number),
-                  EXTRACT_16BITS(header_lsp->remaining_lifetime)));
-           break;
-       case ISIS_PDU_L1_CSNP:
-       case ISIS_PDU_L2_CSNP:
-           ND_TCHECK(*header_csnp);
-           ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
-           break;
-       case ISIS_PDU_L1_PSNP:
-       case ISIS_PDU_L2_PSNP:
-           ND_TCHECK(*header_psnp);
-           ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
-           break;
-
-       }
-       ND_PRINT((ndo, ", length %u", length));
-
-        return(1);
-    }
-
-    /* ok they seem to want to know everything - lets fully decode it */
-    ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
-
-    ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
-           tok2str(isis_pdu_values,
-                   "unknown, type %u",
-                   pdu_type),
-           isis_header->fixed_len,
-           isis_header->version,
-           isis_header->pdu_version,
-          id_length,
-          isis_header->id_length,
-           max_area,
-           isis_header->max_area));
-
-    if (ndo->ndo_vflag > 1) {
-        if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
-            return(0);                         /* for optionally debugging the common header */
+        ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
+               tok2str(isis_pdu_values,
+                       "unknown, type %u",
+                       pdu_type),
+               isis_header->fixed_len,
+               isis_header->version,
+               isis_header->pdu_version,
+               id_length,
+               isis_header->id_length,
+               max_area,
+               isis_header->max_area));
+
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
+                return (0);                         /* for optionally debugging the common header */
+        }
     }
 
     switch (pdu_type) {
 
     case ISIS_PDU_L1_LAN_IIH:
     case ISIS_PDU_L2_LAN_IIH:
-       if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
-           ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
-                  isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE));
-           return (0);
-       }
-
-       ND_TCHECK(*header_iih_lan);
-       pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
-       if (packet_len>pdu_len) {
-            packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
-            length=pdu_len;
-       }
+        if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
+            ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+                     isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)));
+            return (0);
+        }
+        ND_TCHECK(*header_iih_lan);
+        if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)
+            goto trunc;
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", src-id %s",
+                      isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
+            ND_PRINT((ndo, ", lan-id %s, prio %u",
+                      isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
+                      header_iih_lan->priority));
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
+        pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
+        if (packet_len>pdu_len) {
+           packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+           length=pdu_len;
+        }
 
-       ND_PRINT((ndo, "\n\t  source-id: %s,  holding time: %us, Flags: [%s]",
-               isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
-               EXTRACT_16BITS(header_iih_lan->holding_time),
-               tok2str(isis_iih_circuit_type_values,
-                       "unknown circuit type 0x%02x",
-                       header_iih_lan->circuit_type)));
+        ND_PRINT((ndo, "\n\t  source-id: %s,  holding time: %us, Flags: [%s]",
+                  isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
+                  EXTRACT_16BITS(header_iih_lan->holding_time),
+                  tok2str(isis_iih_circuit_type_values,
+                          "unknown circuit type 0x%02x",
+                          header_iih_lan->circuit_type)));
 
-       ND_PRINT((ndo, "\n\t  lan-id:    %s, Priority: %u, PDU length: %u",
-               isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
-               (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
-               pdu_len));
+        ND_PRINT((ndo, "\n\t  lan-id:    %s, Priority: %u, PDU length: %u",
+                  isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
+                  (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
+                  pdu_len));
 
-       if (ndo->ndo_vflag > 1) {
-               if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_IIH_LAN_HEADER_SIZE))
-                       return(0);
-       }
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_IIH_LAN_HEADER_SIZE))
+                return (0);
+        }
 
-       packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
-       pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
-       break;
+        packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+        pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+        break;
 
     case ISIS_PDU_PTP_IIH:
-       if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
-           ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
-                  isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE));
-           return (0);
-       }
-
-       ND_TCHECK(*header_iih_ptp);
-       pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
-       if (packet_len>pdu_len) {
+        if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
+            ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+                      isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)));
+            return (0);
+        }
+        ND_TCHECK(*header_iih_ptp);
+        if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)
+            goto trunc;
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
+        pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
+        if (packet_len>pdu_len) {
             packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
             length=pdu_len;
-       }
+        }
 
-       ND_PRINT((ndo, "\n\t  source-id: %s, holding time: %us, Flags: [%s]",
-               isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
-               EXTRACT_16BITS(header_iih_ptp->holding_time),
-               tok2str(isis_iih_circuit_type_values,
-                       "unknown circuit type 0x%02x",
-                       header_iih_ptp->circuit_type)));
+        ND_PRINT((ndo, "\n\t  source-id: %s, holding time: %us, Flags: [%s]",
+                  isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
+                  EXTRACT_16BITS(header_iih_ptp->holding_time),
+                  tok2str(isis_iih_circuit_type_values,
+                          "unknown circuit type 0x%02x",
+                          header_iih_ptp->circuit_type)));
 
-       ND_PRINT((ndo, "\n\t  circuit-id: 0x%02x, PDU length: %u",
-               header_iih_ptp->circuit_id,
-               pdu_len));
+        ND_PRINT((ndo, "\n\t  circuit-id: 0x%02x, PDU length: %u",
+                  header_iih_ptp->circuit_id,
+                  pdu_len));
 
-       if (ndo->ndo_vflag > 1) {
-               if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_IIH_PTP_HEADER_SIZE))
-                       return(0);
-       }
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_IIH_PTP_HEADER_SIZE))
+                return (0);
+        }
 
-       packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
-       pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
-       break;
+        packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+        pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+        break;
 
     case ISIS_PDU_L1_LSP:
     case ISIS_PDU_L2_LSP:
-       if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
-           ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
-                  isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
-           return (0);
-       }
-
-       ND_TCHECK(*header_lsp);
-       pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
-       if (packet_len>pdu_len) {
+        if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
+            ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+                   isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
+            return (0);
+        }
+        ND_TCHECK(*header_lsp);
+        if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)
+            goto trunc;
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
+                      isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
+                      EXTRACT_32BITS(header_lsp->sequence_number),
+                      EXTRACT_16BITS(header_lsp->remaining_lifetime)));
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
+        pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
+        if (packet_len>pdu_len) {
             packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
             length=pdu_len;
-       }
+        }
 
-       ND_PRINT((ndo, "\n\t  lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t  chksum: 0x%04x",
+        ND_PRINT((ndo, "\n\t  lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t  chksum: 0x%04x",
                isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
                EXTRACT_32BITS(header_lsp->sequence_number),
                EXTRACT_16BITS(header_lsp->remaining_lifetime),
                EXTRACT_16BITS(header_lsp->checksum)));
 
-        if (osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
-                            EXTRACT_16BITS(header_lsp->checksum),
-                            12, length-12) == 0)
-                                goto trunc;
+        osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
+                        EXTRACT_16BITS(header_lsp->checksum),
+                        12, length-12);
 
-       ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
+        ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
                pdu_len,
                ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
 
-       if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
-           ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
-           ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
-           ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
-           ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
-           ND_PRINT((ndo, "ATT bit set, "));
-       }
-       ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
-       ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
-                 ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
+        if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
+            ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
+            ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
+            ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
+            ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
+            ND_PRINT((ndo, "ATT bit set, "));
+        }
+        ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
+        ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
+                  ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
 
-       if (ndo->ndo_vflag > 1) {
-               if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_LSP_HEADER_SIZE))
-                       return(0);
-       }
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_LSP_HEADER_SIZE))
+                return (0);
+        }
 
-       packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
-       pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
-       break;
+        packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+        pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+        break;
 
     case ISIS_PDU_L1_CSNP:
     case ISIS_PDU_L2_CSNP:
-       if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
-           ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
-                  isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE));
-           return (0);
-       }
-
-       ND_TCHECK(*header_csnp);
-       pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
-       if (packet_len>pdu_len) {
+        if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
+            ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
+                      isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)));
+            return (0);
+        }
+        ND_TCHECK(*header_csnp);
+        if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)
+            goto trunc;
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
+        pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
+        if (packet_len>pdu_len) {
             packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
             length=pdu_len;
-       }
+        }
 
-       ND_PRINT((ndo, "\n\t  source-id:    %s, PDU length: %u",
+        ND_PRINT((ndo, "\n\t  source-id:    %s, PDU length: %u",
                isis_print_id(header_csnp->source_id, NODE_ID_LEN),
                pdu_len));
-       ND_PRINT((ndo, "\n\t  start lsp-id: %s",
+        ND_PRINT((ndo, "\n\t  start lsp-id: %s",
                isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)));
-       ND_PRINT((ndo, "\n\t  end lsp-id:   %s",
+        ND_PRINT((ndo, "\n\t  end lsp-id:   %s",
                isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)));
 
-       if (ndo->ndo_vflag > 1) {
-               if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_CSNP_HEADER_SIZE))
-                       return(0);
-       }
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_CSNP_HEADER_SIZE))
+                return (0);
+        }
 
-       packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
-       pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+        packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+        pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
         break;
 
     case ISIS_PDU_L1_PSNP:
     case ISIS_PDU_L2_PSNP:
-       if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
-           ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
-                  isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE));
-           return (0);
-       }
-
-       ND_TCHECK(*header_psnp);
-       pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
-       if (packet_len>pdu_len) {
+        if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
+            ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
+                   isis_header->fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)));
+            return (0);
+        }
+        ND_TCHECK(*header_psnp);
+        if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)
+            goto trunc;
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
+        pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
+        if (packet_len>pdu_len) {
             packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
             length=pdu_len;
-       }
+        }
 
-       ND_PRINT((ndo, "\n\t  source-id:    %s, PDU length: %u",
+        ND_PRINT((ndo, "\n\t  source-id:    %s, PDU length: %u",
                isis_print_id(header_psnp->source_id, NODE_ID_LEN),
                pdu_len));
 
-       if (ndo->ndo_vflag > 1) {
-               if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_PSNP_HEADER_SIZE))
-                       return(0);
-       }
+        if (ndo->ndo_vflag > 1) {
+            if (!print_unknown_data(ndo, pptr, "\n\t  ", ISIS_PSNP_HEADER_SIZE))
+                return (0);
+        }
 
-       packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
-       pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
-       break;
+        packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+        pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+        break;
 
     default:
+        if (ndo->ndo_vflag == 0) {
+            ND_PRINT((ndo, ", length %u", length));
+            return (1);
+        }
        (void)print_unknown_data(ndo, pptr, "\n\t  ", length);
        return (0);
     }
@@ -2492,20 +2503,15 @@ isis_print(netdissect_options *ndo,
      * Now print the TLV's.
      */
 
-    while (packet_len >= 2) {
-        if (pptr == ndo->ndo_snapend) {
-            return (1);
-        }
-
+    while (packet_len > 0) {
        ND_TCHECK2(*pptr, 2);
+       if (packet_len < 2)
+           goto trunc;
        tlv_type = *pptr++;
        tlv_len = *pptr++;
         tmp =tlv_len; /* copy temporary len & pointer to packet data */
         tptr = pptr;
        packet_len -= 2;
-       if (tlv_len > packet_len) {
-           break;
-       }
 
         /* first lets see if we know the TLVs name*/
        ND_PRINT((ndo, "\n\t    %s TLV #%u, length: %u",
@@ -2518,6 +2524,9 @@ isis_print(netdissect_options *ndo,
         if (tlv_len == 0) /* something is invalid */
            continue;
 
+       if (packet_len < tlv_len)
+           goto trunc;
+
         /* now check if we have a decoder otherwise do a hexdump at the end*/
        switch (tlv_type) {
        case ISIS_TLV_AREA_ADDR:
@@ -2906,9 +2915,8 @@ isis_print(netdissect_options *ndo,
              * to avoid conflicts the checksum TLV is zeroed.
              * see rfc3358 for details
              */
-            if (osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
-                length) == 0)
-                    goto trunc;
+            osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr,
+                length);
            break;
 
        case ISIS_TLV_POI:
@@ -3102,40 +3110,33 @@ isis_print(netdissect_options *ndo,
     return(1);
 }
 
-static int
+static void
 osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
-               uint16_t checksum, int checksum_offset, int length)
+               uint16_t checksum, int checksum_offset, u_int length)
 {
         uint16_t calculated_checksum;
 
         /* do not attempt to verify the checksum if it is zero,
-         * if the total length is nonsense,
          * if the offset is nonsense,
          * or the base pointer is not sane
          */
         if (!checksum
-            || length < 0
             || checksum_offset < 0
-            || length > ndo->ndo_snaplen
-            || checksum_offset > ndo->ndo_snaplen
-            || checksum_offset > length) {
+            || !ND_TTEST2(*(pptr + checksum_offset), 2)
+            || (u_int)checksum_offset > length
+            || !ND_TTEST2(*pptr, length)) {
                 ND_PRINT((ndo, " (unverified)"));
-                return 1;
         } else {
 #if 0
                 printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen);
 #endif
-                ND_TCHECK2(*pptr, length);
                 calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
                 if (checksum == calculated_checksum) {
                         ND_PRINT((ndo, " (correct)"));
                 } else {
                         ND_PRINT((ndo, " (incorrect should be 0x%04x)", calculated_checksum));
                 }
-                return 1;
         }
-trunc:
-        return 0;
 }
 
 /*
index f395a8b57e1d241e95d215f58309c163d3ba5116..329a4854a190679a4c9622c84e519eed0998a028 100644 (file)
@@ -219,4 +219,4 @@ IS-IS, length 1497
                0x0080:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
                0x0090:  aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
                0x00a0:  aaaa aaaa aaaa aaaa aaaa
-             164 straggler bytes
+           unknown TLV #170, length: 170 [|isis]
index d16109357dbe1b419ab1f3b1014c6949fb7bcdc7..6c916905b414282fcc5eb50218f5f9e7bc89cc65 100644 (file)
@@ -1,4 +1,17 @@
 IS-IS, length 131146
        L2 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 3 (0)
          lsp-id: 1111.1111.1111.00-00, seq: 0x00000007, lifetime:  1200s
-         chksum: 0x378e [|isis]
+         chksum: 0x378e (unverified), PDU length: 74, Flags: [ L2 IS ]
+           Area address(es) TLV #1, length: 4
+             Area address (length: 3): 49.0001
+           Protocols supported TLV #129, length: 1
+             NLPID(s): IPv4 (0xcc)
+           Hostname TLV #137, length: 2
+             Hostname: R1
+           IPv4 Interface address(es) TLV #132, length: 4
+             IPv4 interface address: 10.0.0.1
+           IS Reachability TLV #2, length: 12
+             IsNotVirtual
+             IS Neighbor: 2222.2222.2222.00, Default Metric: 10, Internal
+           IPv4 Internal Reachability TLV #128, length: 12
+             IPv4 prefix:        10.0.0.0/30, Distribution: up, Metric: 10, Internal
index 1bb8301b0381e88bda910252085f366db69c931f..7d6a11cc8ede86b7ba0aa8f55ef7d9eef0645bdf 100644 (file)
@@ -4,37 +4,32 @@ IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto GRE (47), length 54)
        L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (6), max-area: 7 (7)
          lsp-id: ffff.ffff.ffff.ff-ff, seq: 0xffffffff, lifetime: 65535s
          chksum: 0xffff (incorrect should be 0x0fe8), PDU length: 65535, Flags: [ L1 IS ]
-           IS Neighbor(s) (variable length) TLV #7, length: 0
-             1 straggler bytes
+           IS Neighbor(s) (variable length) TLV #7, length: 0 [|isis]
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto GRE (47), length 54)
     234.176.145.73 > 192.168.1.1: GREv0, Flags [none], length 34
        IS-IS, length 30
        L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (6), max-area: 7 (7)
          lsp-id: ffff.ffff.ffff.ff-ff, seq: 0xffffffff, lifetime: 65535s
          chksum: 0xffff (incorrect should be 0x0fe8), PDU length: 65535, Flags: [ L1 IS ]
-           IS Neighbor(s) (variable length) TLV #7, length: 0
-             1 straggler bytes
+           IS Neighbor(s) (variable length) TLV #7, length: 0 [|isis]
 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto GRE (47), length 54)
     225.91.211.91 > 192.168.1.1: GREv0, Flags [none], length 34
        IS-IS, length 30
        L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (6), max-area: 7 (7)
          lsp-id: ffff.ffff.ffff.ff-ff, seq: 0xffffffff, lifetime: 65535s
          chksum: 0xffff (incorrect should be 0x0fe8), PDU length: 65535, Flags: [ L1 IS ]
-           IS Neighbor(s) (variable length) TLV #7, length: 0
-             1 straggler bytes
+           IS Neighbor(s) (variable length) TLV #7, length: 0 [|isis]
 IP (tos 0x0, ttl 128, id 0, offset 0, flags [DF], proto GRE (47), length 54)
     160.196.17.46 > 192.168.1.1: GREv0, Flags [none], length 34
        IS-IS, length 30
        L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (6), max-area: 7 (7)
          lsp-id: ffff.ffff.ffff.ff-ff, seq: 0xffffffff, lifetime: 65535s
          chksum: 0xffff (incorrect should be 0x0fe8), PDU length: 65535, Flags: [ L1 IS ]
-           IS Neighbor(s) (variable length) TLV #7, length: 0
-             1 straggler bytes
+           IS Neighbor(s) (variable length) TLV #7, length: 0 [|isis]
 IP (tos 0x0, ttl 128, id 0, offset 0, flags [DF], proto GRE (47), length 54)
     246.181.173.63 > 192.168.1.1: GREv0, Flags [none], length 34
        IS-IS, length 30
        L1 LSP, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (6), max-area: 7 (7)
          lsp-id: ffff.ffff.ffff.ff-ff, seq: 0xffffffff, lifetime: 65535s
          chksum: 0xffff (incorrect should be 0x0fe8), PDU length: 65535, Flags: [ L1 IS ]
-           IS Neighbor(s) (variable length) TLV #7, length: 0
-             1 straggler bytes
+           IS Neighbor(s) (variable length) TLV #7, length: 0 [|isis]