X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/64e8f9a9ed91a3cbfa8e66367f87ef50a1d62b99..84b51cad218840ece9115c72705f846060005c6f:/print-dtp.c diff --git a/print-dtp.c b/print-dtp.c index 4c3d6c78..a1ae4ba4 100644 --- a/print-dtp.c +++ b/print-dtp.c @@ -23,6 +23,7 @@ #include "netdissect-stdinc.h" +#define ND_LONGJMP_FROM_TCHECK #include "netdissect.h" #include "addrtoname.h" #include "extract.h" @@ -35,26 +36,21 @@ #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); }