X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/fc7b8aeb5e40fc50c68624e12069f5ba7bd9ae2c..refs/heads/master:/print-dtp.c diff --git a/print-dtp.c b/print-dtp.c index 5d84a770..9ff4c1c9 100644 --- a/print-dtp.c +++ b/print-dtp.c @@ -12,22 +12,21 @@ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * - * Dynamic Trunk Protocol (DTP) - * * Original code by Carles Kishimoto */ -#define NETDISSECT_REWORKED -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +/* \summary: Dynamic Trunking Protocol (DTP) printer */ + +#include -#include +#include "netdissect-stdinc.h" -#include "interface.h" +#define ND_LONGJMP_FROM_TCHECK +#include "netdissect.h" #include "addrtoname.h" #include "extract.h" + #define DTP_HEADER_LEN 1 #define DTP_DOMAIN_TLV 0x0001 #define DTP_STATUS_TLV 0x0002 @@ -35,29 +34,25 @@ #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; - - if (length < DTP_HEADER_LEN) - goto trunc; - - tptr = pptr; - - ND_TCHECK2(*tptr, DTP_HEADER_LEN); + ndo->ndo_protocol = "dtp"; + if (length < DTP_HEADER_LEN) { + ND_PRINT("[zero packet length]"); + goto invalid; + } - ND_PRINT((ndo, "DTPv%u, length %u", - (*tptr), - length)); + ND_PRINT("DTPv%u, length %u", + GET_U_1(tptr), + length); /* * In non-verbose mode, just print version. @@ -67,52 +62,59 @@ 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_TCHECK2(*tptr, 4); - - type = EXTRACT_16BITS(tptr); - len = EXTRACT_16BITS(tptr+2); + 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 */ + if (type == 0) + return; + ND_PRINT("\n\t%s (0x%04x) TLV, length %u", + tok2str(dtp_tlv_values, "Unknown", type), + type, len); /* infinite loop check */ - if (type == 0 || len == 0) { - return; + if (len < 4 || len > length) { + ND_PRINT("[TLV length %u]", len); + goto invalid; } - ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u", - tok2str(dtp_tlv_values, "Unknown", type), - type, len)); - switch (type) { case DTP_DOMAIN_TLV: - ND_PRINT((ndo, ", %s", tptr+4)); + ND_PRINT(", "); + nd_printjnp(ndo, tptr+4, len-4); break; case DTP_STATUS_TLV: case DTP_DTP_TYPE_TLV: - ND_PRINT((ndo, ", 0x%x", *(tptr+4))); + if (len != 5) + goto invalid; + ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); break; case DTP_NEIGHBOR_TLV: - ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4))); + if (len != 10) + goto invalid; + ND_PRINT(", %s", GET_MAC48_STRING(tptr+4)); break; default: + ND_TCHECK_LEN(tptr, len); break; } tptr += len; + length -= len; } - return; - trunc: - ND_PRINT((ndo, "[|dtp]")); + invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(tptr, length); } - -/* - * Local Variables: - * c-style: whitesmith - * c-basic-offset: 4 - * End: - */