From: Guy Harris Date: Sat, 3 Jun 2017 03:05:12 +0000 (-0700) Subject: Clean up IS-IS printing. X-Git-Tag: tcpdump-4.9.2~149 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/d3c9fb5f6d6c40d2994be2399f93e0ad14f751df?ds=inline Clean up IS-IS printing. 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. --- diff --git a/print-isoclns.c b/print-isoclns.c index d08085fa..9c279c79 100644 --- a/print-isoclns.c +++ b/print-isoclns.c @@ -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; } /* diff --git a/tests/isis-seg-fault-2-v.out b/tests/isis-seg-fault-2-v.out index f395a8b5..329a4854 100644 --- a/tests/isis-seg-fault-2-v.out +++ b/tests/isis-seg-fault-2-v.out @@ -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] diff --git a/tests/isis-seg-fault-3-v.out b/tests/isis-seg-fault-3-v.out index d1610935..6c916905 100644 --- a/tests/isis-seg-fault-3-v.out +++ b/tests/isis-seg-fault-3-v.out @@ -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 diff --git a/tests/isis_infloop-v.out b/tests/isis_infloop-v.out index 1bb8301b..7d6a11cc 100644 --- a/tests/isis_infloop-v.out +++ b/tests/isis_infloop-v.out @@ -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]