X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/bef667db65b15c89ec6f1cf325b76acd3c0b8748..282508f16b8fde1bb95fabef1afb2d77c24a306b:/print-ldp.c diff --git a/print-ldp.c b/print-ldp.c index 653ea37c..1ee453b2 100644 --- a/print-ldp.c +++ b/print-ldp.c @@ -16,9 +16,7 @@ /* \summary: Label Distribution Protocol (LDP) printer */ -#ifdef HAVE_CONFIG_H #include -#endif #include "netdissect-stdinc.h" @@ -211,7 +209,7 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { { 0, NULL} }; -static int ldp_pdu_print(netdissect_options *, const u_char *); +static u_int ldp_pdu_print(netdissect_options *, const u_char *); /* * ldp tlv header @@ -231,12 +229,16 @@ static int ldp_pdu_print(netdissect_options *, const u_char *); */ #define TLV_TCHECK(minlen) \ - ND_TCHECK_LEN(tptr, minlen); if (tlv_tlen < minlen) goto badtlv; + if (tlv_tlen < minlen) { \ + ND_PRINT(" [tlv length %u < %u]", tlv_tlen, minlen); \ + nd_print_invalid(ndo); \ + goto invalid; \ + } static u_int ldp_tlv_print(netdissect_options *ndo, const u_char *tptr, - u_short msg_tlen) + u_int msg_tlen) { struct ldp_tlv_header { nd_uint16_t type; @@ -253,7 +255,7 @@ ldp_tlv_print(netdissect_options *ndo, ldp_tlv_header = (const struct ldp_tlv_header *)tptr; ND_TCHECK_SIZE(ldp_tlv_header); tlv_len=GET_BE_U_2(ldp_tlv_header->length); - if (tlv_len + 4 > msg_tlen) { + if (tlv_len + 4U > msg_tlen) { ND_PRINT("\n\t\t TLV contents go past end of message"); return 0; } @@ -284,11 +286,11 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_TLV_IPV4_TRANSPORT_ADDR: TLV_TCHECK(4); - ND_PRINT("\n\t IPv4 Transport Address: %s", ipaddr_string(ndo, tptr)); + ND_PRINT("\n\t IPv4 Transport Address: %s", GET_IPADDR_STRING(tptr)); break; case LDP_TLV_IPV6_TRANSPORT_ADDR: TLV_TCHECK(16); - ND_PRINT("\n\t IPv6 Transport Address: %s", ip6addr_string(ndo, tptr)); + ND_PRINT("\n\t IPv6 Transport Address: %s", GET_IP6ADDR_STRING(tptr)); break; case LDP_TLV_CONFIG_SEQ_NUMBER: TLV_TCHECK(4); @@ -305,16 +307,14 @@ ldp_tlv_print(netdissect_options *ndo, switch (af) { case AFNUM_INET: while(tlv_tlen >= sizeof(nd_ipv4)) { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT(" %s", ipaddr_string(ndo, tptr)); + ND_PRINT(" %s", GET_IPADDR_STRING(tptr)); tlv_tlen-=sizeof(nd_ipv4); tptr+=sizeof(nd_ipv4); } break; case AFNUM_INET6: while(tlv_tlen >= sizeof(nd_ipv6)) { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv6)); - ND_PRINT(" %s", ip6addr_string(ndo, tptr)); + ND_PRINT(" %s", GET_IP6ADDR_STRING(tptr)); tlv_tlen-=sizeof(nd_ipv6); tptr+=sizeof(nd_ipv6); } @@ -326,11 +326,17 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_TLV_COMMON_SESSION: - TLV_TCHECK(8); + TLV_TCHECK(14); ND_PRINT("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", GET_BE_U_2(tptr), GET_BE_U_2(tptr + 2), - (GET_BE_U_2(tptr + 6)&0x8000) ? "On Demand" : "Unsolicited", - (GET_BE_U_2(tptr + 6)&0x4000) ? "Enabled" : "Disabled" + (GET_BE_U_2(tptr + 4)&0x8000) ? "On Demand" : "Unsolicited", + (GET_BE_U_2(tptr + 4)&0x4000) ? "Enabled" : "Disabled" + ); + ND_PRINT("\n\t Path Vector Limit %u, Max-PDU length: %u, Receiver Label-Space-ID %s:%u", + GET_U_1(tptr+5), + GET_BE_U_2(tptr+6), + GET_IPADDR_STRING(tptr+8), + GET_BE_U_2(tptr+12) ); break; @@ -350,8 +356,8 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_FEC_PREFIX: TLV_TCHECK(2); af = GET_BE_U_2(tptr); - tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; - tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + tptr+=2; + tlv_tlen-=2; if (af == AFNUM_INET) { i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) @@ -362,8 +368,7 @@ ldp_tlv_print(netdissect_options *ndo, ND_PRINT(": IPv4 prefix (invalid length)"); else ND_PRINT(": IPv4 prefix %s", buf); - } - else if (af == AFNUM_INET6) { + } else if (af == AFNUM_INET6) { i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; @@ -373,8 +378,7 @@ ldp_tlv_print(netdissect_options *ndo, ND_PRINT(": IPv6 prefix (invalid length)"); else ND_PRINT(": IPv6 prefix %s", buf); - } - else + } else ND_PRINT(": Address family %u prefix", af); break; case LDP_FEC_HOSTADDRESS: @@ -487,7 +491,7 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_TLV_FT_SESSION: - TLV_TCHECK(8); + TLV_TCHECK(12); ft_flags = GET_BE_U_2(tptr); ND_PRINT("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", ft_flags&0x8000 ? "" : "No ", @@ -495,6 +499,7 @@ ldp_tlv_print(netdissect_options *ndo, ft_flags&0x4 ? "" : "No ", ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels", ft_flags&0x1 ? "" : "Don't "); + /* 16 bits (FT Flags) + 16 bits (Reserved) */ tptr+=4; ui = GET_BE_U_4(tptr); if (ui) @@ -535,11 +540,9 @@ ldp_tlv_print(netdissect_options *ndo, return(tlv_len+4); /* Type & Length fields not included */ trunc: - nd_print_trunc(ndo); - return 0; + nd_trunc_longjmp(ndo); -badtlv: - ND_PRINT("\n\t\t TLV contents go past end of TLV"); +invalid: return(tlv_len+4); /* Type & Length fields not included */ } @@ -547,19 +550,24 @@ void ldp_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - int processed; + u_int processed; ndo->ndo_protocol = "ldp"; while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { processed = ldp_pdu_print(ndo, pptr); if (processed == 0) return; + if (len < processed) { + ND_PRINT(" [remaining length %u < %u]", len, processed); + nd_print_invalid(ndo); + break; + } len -= processed; pptr += processed; } } -static int +static u_int ldp_pdu_print(netdissect_options *ndo, const u_char *pptr) { @@ -587,17 +595,17 @@ ldp_pdu_print(netdissect_options *ndo, pdu_len = GET_BE_U_2(ldp_com_header->pdu_length); if (pdu_len < sizeof(struct ldp_common_header)-4) { /* length too short */ - ND_PRINT("%sLDP, pdu-length: %u (too short, < %u)", - (ndo->ndo_vflag < 1) ? "" : "\n\t", - pdu_len, - (u_int)(sizeof(struct ldp_common_header)-4)); + ND_PRINT("%sLDP, pdu-length: %u (too short, < %zu)", + (ndo->ndo_vflag < 1) ? "" : "\n\t", + pdu_len, + sizeof(struct ldp_common_header)-4); return 0; } /* print the LSR-ID, label-space & length */ ND_PRINT("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", (ndo->ndo_vflag < 1) ? "" : "\n\t", - ipaddr_string(ndo, ldp_com_header->lsr_id), + GET_IPADDR_STRING(ldp_com_header->lsr_id), GET_BE_U_2(ldp_com_header->label_space), pdu_len); @@ -620,13 +628,13 @@ ldp_pdu_print(netdissect_options *ndo, if (msg_len < sizeof(struct ldp_msg_header)-4) { /* length too short */ /* FIXME vendor private / experimental check */ - ND_PRINT("\n\t %s Message (0x%04x), length: %u (too short, < %u)", - tok2str(ldp_msg_values, - "Unknown", - msg_type), - msg_type, - msg_len, - (u_int)(sizeof(struct ldp_msg_header)-4)); + ND_PRINT("\n\t %s Message (0x%04x), length: %u (too short, < %zu)", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + sizeof(struct ldp_msg_header)-4); return 0; } @@ -690,6 +698,5 @@ ldp_pdu_print(netdissect_options *ndo, } return pdu_len+4; trunc: - nd_print_trunc(ndo); - return 0; + nd_trunc_longjmp(ndo); }