X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/24df77f09e26a72f662a82b92645707e0572d1cc..d8078c7fcb4d8260ca2e9ebb78f43d71894be639:/print-ldp.c diff --git a/print-ldp.c b/print-ldp.c index 282bed62..bdf9a138 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" @@ -29,7 +27,6 @@ #include "l2vpn.h" #include "af.h" - /* * ldp common header * @@ -142,8 +139,10 @@ static const struct tok ldp_msg_values[] = { #define LDP_TLV_ATM_SESSION_PARM 0x0501 #define LDP_TLV_FR_SESSION_PARM 0x0502 #define LDP_TLV_FT_SESSION 0x0503 +#define LDP_TLV_TYPED_WC_FEC_CAP 0x050b /* rfc 5918 */ #define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600 #define LDP_TLV_MTU 0x0601 /* rfc 3988 */ +#define LDP_TLV_DUAL_STACK_CAP 0x0701 /* rfc 7552 */ static const struct tok ldp_tlv_values[] = { { LDP_TLV_FEC, "FEC" }, @@ -165,8 +164,41 @@ static const struct tok ldp_tlv_values[] = { { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" }, { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" }, { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" }, + { LDP_TLV_TYPED_WC_FEC_CAP, "Typed Wildcard FEC Capability" }, { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" }, { LDP_TLV_MTU, "MTU" }, + { LDP_TLV_DUAL_STACK_CAP, "Dual-Stack Capability" }, + { 0, NULL} +}; + +static const struct tok ldp_status_code_values[] = { + /* rfc 5036 */ + { 0x00000000, "Success" }, + { 0x00000001, "Bad LDP Identifier" }, + { 0x00000002, "Bad Protocol Version" }, + { 0x00000003, "Bad PDU Length" }, + { 0x00000004, "Unknown Message Type" }, + { 0x00000005, "Bad Message Length" }, + { 0x00000006, "Unknown TLV" }, + { 0x00000007, "Bad TLV Length" }, + { 0x00000008, "Malformted TLV Value" }, + { 0x00000009, "Hold Timer Expired" }, + { 0x0000000A, "Shutdown" }, + { 0x0000000B, "Loop Detected" }, + { 0x0000000C, "Unknown FEC" }, + { 0x0000000D, "No Route" }, + { 0x0000000E, "No Label Resources" }, + { 0x0000000F, "Label Resources/Available" }, + { 0x00000010, "Session Rejected/No Hello" }, + { 0x00000011, "Session Rejected/Parameters Advertisement Mode" }, + { 0x00000012, "Session Rejected/Parameters Max PDU Length" }, + { 0x00000013, "Session Rejected/Parameters Label Range" }, + { 0x00000014, "KeepAlive Timer Expired" }, + { 0x00000015, "Label Request Aborted" }, + { 0x00000016, "Missing Message Parameters" }, + { 0x00000017, "Unsupported Address Family" }, + { 0x00000018, "Session Rejected/Bad KeepAlive Time" }, + { 0x00000019, "Internal Error" }, { 0, NULL} }; @@ -211,6 +243,16 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { { 0, NULL} }; +/* rfc 7552 */ +#define LDP_DUAL_STACK_TRANSPORT_PREF_IPV4 0x40 +#define LDP_DUAL_STACK_TRANSPORT_PREF_IPV6 0x60 + +static const struct tok ldp_dual_stack_transport_pref_values[] = { + { LDP_DUAL_STACK_TRANSPORT_PREF_IPV4, "IPv4" }, + { LDP_DUAL_STACK_TRANSPORT_PREF_IPV6, "IPv6" }, + { 0, NULL} +}; + static u_int ldp_pdu_print(netdissect_options *, const u_char *); /* @@ -230,13 +272,6 @@ static u_int ldp_pdu_print(netdissect_options *, const u_char *); * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define TLV_TCHECK(minlen) \ - 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, @@ -249,8 +284,8 @@ ldp_tlv_print(netdissect_options *ndo, const struct ldp_tlv_header *ldp_tlv_header; u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; - u_char fec_type; - u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; + u_char fec_type, transport_pref; + u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len; char buf[100]; int i; @@ -279,7 +314,7 @@ ldp_tlv_print(netdissect_options *ndo, switch(tlv_type) { case LDP_TLV_COMMON_HELLO: - TLV_TCHECK(4); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); ND_PRINT("\n\t Hold Time: %us, Flags: [%s Hello%s]", GET_BE_U_2(tptr), (GET_BE_U_2(tptr + 2)&0x8000) ? "Targeted" : "Link", @@ -287,35 +322,35 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_TLV_IPV4_TRANSPORT_ADDR: - TLV_TCHECK(4); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); ND_PRINT("\n\t IPv4 Transport Address: %s", GET_IPADDR_STRING(tptr)); break; case LDP_TLV_IPV6_TRANSPORT_ADDR: - TLV_TCHECK(16); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 16); ND_PRINT("\n\t IPv6 Transport Address: %s", GET_IP6ADDR_STRING(tptr)); break; case LDP_TLV_CONFIG_SEQ_NUMBER: - TLV_TCHECK(4); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr)); break; case LDP_TLV_ADDRESS_LIST: - TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, + LDP_TLV_ADDRESS_LIST_AFNUM_LEN); af = GET_BE_U_2(tptr); tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN; ND_PRINT("\n\t Address Family: %s, addresses", tok2str(af_values, "Unknown (%u)", af)); switch (af) { - case AFNUM_INET: + case AFNUM_IP: while(tlv_tlen >= sizeof(nd_ipv4)) { - ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); ND_PRINT(" %s", GET_IPADDR_STRING(tptr)); tlv_tlen-=sizeof(nd_ipv4); tptr+=sizeof(nd_ipv4); } break; - case AFNUM_INET6: + case AFNUM_IP6: while(tlv_tlen >= sizeof(nd_ipv6)) { ND_PRINT(" %s", GET_IP6ADDR_STRING(tptr)); tlv_tlen-=sizeof(nd_ipv6); @@ -328,17 +363,40 @@ ldp_tlv_print(netdissect_options *ndo, } break; + case LDP_TLV_HOP_COUNT: + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 1); + ND_PRINT("\n\t Hop Count: %u", GET_U_1(tptr)); + break; + + case LDP_TLV_PATH_VECTOR: + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); + ND_PRINT("\n\t Path Vector: %s", GET_IPADDR_STRING(tptr)); + tptr += 4; + tlv_tlen -= 4; + while (tlv_tlen >= 4) { + ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); + tptr += 4; + tlv_tlen -= 4; + } + break; + case LDP_TLV_COMMON_SESSION: - TLV_TCHECK(8); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 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; case LDP_TLV_FEC: - TLV_TCHECK(1); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 1); fec_type = GET_U_1(tptr); ND_PRINT("\n\t %s FEC (0x%02x)", tok2str(ldp_fec_values, "Unknown", fec_type), @@ -351,11 +409,11 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_FEC_WILDCARD: break; case LDP_FEC_PREFIX: - TLV_TCHECK(2); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 2); af = GET_BE_U_2(tptr); tptr+=2; tlv_tlen-=2; - if (af == AFNUM_INET) { + if (af == AFNUM_IP) { i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; @@ -365,8 +423,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_IP6) { i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; @@ -376,8 +433,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: @@ -387,7 +443,7 @@ ldp_tlv_print(netdissect_options *ndo, * We assume the type was supposed to be one of the MPLS * Pseudowire Types. */ - TLV_TCHECK(7); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 7); vc_info_len = GET_U_1(tptr + 2); /* @@ -405,7 +461,7 @@ ldp_tlv_print(netdissect_options *ndo, } /* Make sure we have the VC ID as well */ - TLV_TCHECK(11); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 11); ND_PRINT(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff), GET_BE_U_2(tptr)&0x8000 ? "" : "no ", @@ -422,7 +478,7 @@ ldp_tlv_print(netdissect_options *ndo, /* Skip past the fixed information and the VC ID */ tptr+=11; tlv_tlen-=11; - TLV_TCHECK(vc_info_len); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, vc_info_len); while (vc_info_len > 2) { vc_info_tlv_type = GET_U_1(tptr); @@ -444,8 +500,7 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_FEC_MARTINI_IFPARM_DESC: ND_PRINT(": "); - for (idx = 2; idx < vc_info_tlv_len; idx++) - fn_print_char(ndo, GET_U_1(tptr + idx)); + nd_printjn(ndo, tptr + 2, vc_info_tlv_len - 2); break; case LDP_FEC_MARTINI_IFPARM_VCCV: @@ -471,26 +526,29 @@ ldp_tlv_print(netdissect_options *ndo, break; case LDP_TLV_GENERIC_LABEL: - TLV_TCHECK(4); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); ND_PRINT("\n\t Label: %u", GET_BE_U_4(tptr) & 0xfffff); break; case LDP_TLV_STATUS: - TLV_TCHECK(8); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 10); ui = GET_BE_U_4(tptr); tptr+=4; - ND_PRINT("\n\t Status: 0x%02x, Flags: [%s and %s forward]", - ui&0x3fffffff, - ui&0x80000000 ? "Fatal error" : "Advisory Notification", - ui&0x40000000 ? "do" : "don't"); + ND_PRINT("\n\t Status Code: %s, Flags: [%s and %s forward]", + tok2str(ldp_status_code_values, "Unknown", ui&0x3fffffff), + ui&0x80000000 ? "Fatal error" : "Advisory Notification", + ui&0x40000000 ? "do" : "don't"); ui = GET_BE_U_4(tptr); tptr+=4; if (ui) ND_PRINT(", causing Message ID: 0x%08x", ui); + ui = GET_BE_U_2(tptr); + if (ui) + ND_PRINT(", Message Type: %s", tok2str(ldp_msg_values, "Unknown", ui)); break; case LDP_TLV_FT_SESSION: - TLV_TCHECK(12); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 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 ", @@ -509,19 +567,30 @@ ldp_tlv_print(netdissect_options *ndo, ND_PRINT(", Recovery Time: %ums", ui); break; + case LDP_TLV_TYPED_WC_FEC_CAP: + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 1); + ND_PRINT("\n\t %s", GET_U_1(tptr)&0x80 ? "Support" : "No Support"); + break; + case LDP_TLV_MTU: - TLV_TCHECK(2); + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 2); ND_PRINT("\n\t MTU: %u", GET_BE_U_2(tptr)); break; + case LDP_TLV_DUAL_STACK_CAP: + ND_ICHECKMSG_U("tlv length", tlv_tlen, <, 4); + transport_pref = GET_U_1(tptr); + ND_PRINT("\n\t Transport Connection Preference: %s", + tok2str(ldp_dual_stack_transport_pref_values, + "Unknown", + transport_pref)); + break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ - case LDP_TLV_HOP_COUNT: - case LDP_TLV_PATH_VECTOR: case LDP_TLV_ATM_LABEL: case LDP_TLV_FR_LABEL: case LDP_TLV_EXTD_STATUS: @@ -539,10 +608,10 @@ 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); invalid: + nd_print_invalid(ndo); return(tlv_len+4); /* Type & Length fields not included */ } @@ -595,10 +664,10 @@ 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; } @@ -617,7 +686,7 @@ ldp_pdu_print(netdissect_options *ndo, tptr = pptr + sizeof(struct ldp_common_header); tlen = pdu_len - (sizeof(struct ldp_common_header)-4); /* Type & Length fields not included */ - while(tlen>0) { + while(tlen != 0) { /* did we capture enough for fully decoding the msg header ? */ ND_TCHECK_LEN(tptr, sizeof(struct ldp_msg_header)); @@ -628,13 +697,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; } @@ -665,6 +734,9 @@ ldp_pdu_print(netdissect_options *ndo, case LDP_MSG_LABEL_MAPPING: case LDP_MSG_ADDRESS_WITHDRAW: case LDP_MSG_LABEL_WITHDRAW: + case LDP_MSG_LABEL_REQUEST: + case LDP_MSG_LABEL_RELEASE: + case LDP_MSG_LABEL_ABORT_REQUEST: while(msg_tlen >= 4) { processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen); if (processed == 0) @@ -674,15 +746,6 @@ ldp_pdu_print(netdissect_options *ndo, } break; - /* - * FIXME those are the defined messages that lack a decoder - * you are welcome to contribute code ;-) - */ - - case LDP_MSG_LABEL_REQUEST: - case LDP_MSG_LABEL_RELEASE: - case LDP_MSG_LABEL_ABORT_REQUEST: - default: if (ndo->ndo_vflag <= 1) print_unknown_data(ndo, msg_tptr, "\n\t ", msg_tlen); @@ -698,6 +761,5 @@ ldp_pdu_print(netdissect_options *ndo, } return pdu_len+4; trunc: - nd_print_trunc(ndo); - return 0; + nd_trunc_longjmp(ndo); }