X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/92753ab19bb2bb136a67123e8e131c586d97877a..01fe0ebe27b2fe957f699ffa4dbdedc46e12f85b:/print-isoclns.c?ds=inline diff --git a/print-isoclns.c b/print-isoclns.c index 66756519..c0f6dfff 100644 --- a/print-isoclns.c +++ b/print-isoclns.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.133.2.1 2005-04-25 08:43:06 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.133.2.5 2005-04-26 07:14:25 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -586,7 +586,9 @@ void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) break; case NLPID_NULLNS: - (void)printf(", length: %u", length); + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); break; case NLPID_Q933: @@ -610,7 +612,9 @@ void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) default: if (!eflag) printf("OSI NLPID 0x%02x unknown",*p); - (void)printf(", length: %u", length); + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); if (caplen > 1) print_unknown_data(p,"\n\t",caplen); break; @@ -746,8 +750,7 @@ static int clnp_print (const u_int8_t *pptr, u_int length) u_int op, opli; const u_int8_t *tptr; - if (snapend - pptr < 2) - return (0); + TCHECK2(*pptr, 2); if (li < 2) { printf(", bad opts/li"); return (0); @@ -755,6 +758,7 @@ static int clnp_print (const u_int8_t *pptr, u_int length) op = *pptr++; opli = *pptr++; li -= 2; + TCHECK2(*pptr, opli); if (opli > li) { printf(", opt (%d) too long", op); return (0); @@ -762,9 +766,6 @@ static int clnp_print (const u_int8_t *pptr, u_int length) li -= opli; tptr = pptr; - if (snapend < pptr) - return(0); - printf("\n\t %s Option #%u, length %u, value: ", tok2str(clnp_option_values,"Unknown",op), op, @@ -804,6 +805,7 @@ static int clnp_print (const u_int8_t *pptr, u_int length) case CLNP_PDU_ER: /* fall through */ case CLNP_PDU_ERP: + TCHECK(*pptr); if (*(pptr) == NLPID_CLNP) { printf("\n\t-----original packet-----\n\t"); /* FIXME recursion protection */ @@ -872,6 +874,7 @@ esis_print(const u_int8_t *pptr, u_int length) } esis_header = (const struct esis_header_t *) pptr; + TCHECK(*esis_header); li = esis_header->length_indicator; optr = pptr; @@ -921,7 +924,8 @@ esis_print(const u_int8_t *pptr, u_int length) /* do not attempt to verify the checksum if it is zero */ if (EXTRACT_16BITS(esis_header->cksum) == 0) printf("(unverified)"); - else printf("(%s)", osi_cksum(pptr, li) ? "incorrect" : "correct"); + else + printf("(%s)", osi_cksum(pptr, li) ? "incorrect" : "correct"); printf(", holding time: %us, length indicator: %u",EXTRACT_16BITS(esis_header->holdtime),li); @@ -933,25 +937,72 @@ esis_print(const u_int8_t *pptr, u_int length) switch (esis_pdu_type) { case ESIS_PDU_REDIRECT: { - const u_int8_t *dst, *snpa, *tptr; + const u_int8_t *dst, *snpa, *neta; + u_int dstl, snpal, netal; - dst = pptr; pptr += *pptr + 1; - if (pptr > snapend) + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); return; - printf("\n\t %s", isonsap_string(dst+1,*dst)); - snpa = pptr; pptr += *pptr + 1; - tptr = pptr; pptr += *pptr + 1; - if (pptr > snapend) + } + dstl = *pptr; + pptr++; + li--; + TCHECK2(*pptr, dstl); + if (li < dstl) { + printf(", bad redirect/li"); + return; + } + dst = pptr; + pptr += dstl; + li -= dstl; + printf("\n\t %s", isonsap_string(dst,dstl)); + + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); return; + } + snpal = *pptr; + pptr++; + li--; + TCHECK2(*pptr, snpal); + if (li < snpal) { + printf(", bad redirect/li"); + return; + } + snpa = pptr; + pptr += snpal; + li -= snpal; + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + netal = *pptr; + pptr++; + TCHECK2(*pptr, netal); + if (li < netal) { + printf(", bad redirect/li"); + return; + } + neta = pptr; + pptr += netal; + li -= netal; - if (tptr[0] == 0) - printf("\n\t %s", etheraddr_string(&snpa[1])); + if (netal == 0) + printf("\n\t %s", etheraddr_string(snpa)); else - printf("\n\t %s", isonsap_string(tptr+1,*tptr)); + printf("\n\t %s", isonsap_string(neta,netal)); break; } case ESIS_PDU_ESH: + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } source_address_number = *pptr; pptr++; li--; @@ -959,23 +1010,47 @@ esis_print(const u_int8_t *pptr, u_int length) printf("\n\t Number of Source Addresses: %u", source_address_number); while (source_address_number > 0) { + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } source_address_length = *pptr; + pptr++; + li--; + + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad esh/li"); + return; + } printf("\n\t NET (length: %u): %s", source_address_length, - isonsap_string(pptr+1,source_address_length)); - - pptr += source_address_length+1; - li -= source_address_length+1; + isonsap_string(pptr,source_address_length)); + pptr += source_address_length; + li -= source_address_length; source_address_number--; } break; case ESIS_PDU_ISH: { + TCHECK(*pptr); + if (li < 1) { + printf(", bad ish/li"); + return; + } source_address_length = *pptr; - printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr+1, source_address_length)); - pptr += source_address_length+1; - li -= source_address_length +1; + pptr++; + li--; + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad ish/li"); + return; + } + printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length)); + pptr += source_address_length; + li -= source_address_length; break; } @@ -992,8 +1067,7 @@ esis_print(const u_int8_t *pptr, u_int length) u_int op, opli; const u_int8_t *tptr; - if (snapend - pptr < 2) - return; + TCHECK2(*pptr, 2); if (li < 2) { printf(", bad opts/li"); return; @@ -1008,9 +1082,6 @@ esis_print(const u_int8_t *pptr, u_int length) li -= opli; tptr = pptr; - if (snapend < pptr) - return; - printf("\n\t %s Option #%u, length %u, value: ", tok2str(esis_option_values,"Unknown",op), op, @@ -1019,12 +1090,13 @@ esis_print(const u_int8_t *pptr, u_int length) switch (op) { case ESIS_OPTION_ES_CONF_TIME: + TCHECK2(*pptr, 2); printf("%us", EXTRACT_16BITS(tptr)); break; - case ESIS_OPTION_PROTOCOLS: while (opli>0) { + TCHECK(*pptr); printf("%s (0x%02x)", tok2str(nlpid_values, "unknown", @@ -1056,6 +1128,8 @@ esis_print(const u_int8_t *pptr, u_int length) print_unknown_data(pptr,"\n\t ",opli); pptr += opli; } +trunc: + return; } /* shared routine for printing system, node and lsp-ids */ @@ -1905,6 +1979,9 @@ static int isis_print (const u_int8_t *p, u_int length) tlv_type, tlv_len); + if (tlv_len == 0) /* something is malformed */ + break; + /* now check if we have a decoder otherwise do a hexdump at the end*/ switch (tlv_type) { case ISIS_TLV_AREA_ADDR: @@ -1935,7 +2012,7 @@ static int isis_print (const u_int8_t *p, u_int length) break; case ISIS_TLV_ISNEIGH_VARLEN: - if (!TTEST2(*tptr, 1)) + if (!TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */ goto trunctlv; lan_alen = *tptr++; /* LAN address length */ if (lan_alen == 0) {