X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/917e5c0ec70327095071ccd1f9bdcb08bcd6be4c..ea5736c8c68f0fc3699cff8205f2823f97a05f8b:/print-lspping.c diff --git a/print-lspping.c b/print-lspping.c index 0808abbf..6958bdac 100644 --- a/print-lspping.c +++ b/print-lspping.c @@ -15,7 +15,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.9 2004-06-16 06:38:08 hannes Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -34,6 +34,7 @@ static const char rcsid[] _U_ = #include "bgp.h" #include "l2vpn.h" +#include "oui.h" /* * LSPPING common header @@ -79,8 +80,6 @@ struct lspping_common_header { }; #define LSPPING_VERSION 1 -#define FALSE 0 -#define TRUE 1 static const struct tok lspping_msg_type_values[] = { { 1, "MPLS Echo Request"}, @@ -136,15 +135,25 @@ struct lspping_tlv_header { #define LSPPING_TLV_TARGET_FEC_STACK 1 #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 #define LSPPING_TLV_PAD 3 -#define LSPPING_TLV_ERROR_CODE 4 -#define LSPPING_TLV_VENDOR_PRIVATE 5 +#define LSPPING_TLV_VENDOR_ENTERPRISE 5 +#define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 +#define LSPPING_TLV_INTERFACE_LABEL_STACK 7 +#define LSPPING_TLV_ERROR_CODE 9 +#define LSPPING_TLV_REPLY_TOS_BYTE 10 +#define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ +#define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 +#define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 static const struct tok lspping_tlv_values[] = { { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, { LSPPING_TLV_PAD, "Pad" }, { LSPPING_TLV_ERROR_CODE, "Error Code" }, - { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Enterprise Code" }, + { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, + { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, + { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, + { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, + { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, { 0, NULL} }; @@ -398,6 +407,64 @@ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { u_int8_t encapsulation[2]; }; +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MTU | Address Type | Resvd (SBZ) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream IP Address (4 or 16 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Interface Address (4 or 16 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Hash Key Type | Depth Limit | Multipath Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . . + * . (Multipath Information) . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Label | Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . . + * . . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Label | Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_downstream_map_ipv4_t { + u_int8_t mtu [2]; + u_int8_t address_type; + u_int8_t res; + u_int8_t downstream_ip[4]; + u_int8_t downstream_interface[4]; +}; + +struct lspping_tlv_downstream_map_ipv6_t { + u_int8_t mtu [2]; + u_int8_t address_type; + u_int8_t res; + u_int8_t downstream_ip[16]; + u_int8_t downstream_interface[16]; +}; + +struct lspping_tlv_downstream_map_info_t { + u_int8_t hash_key_type; + u_int8_t depth_limit; + u_int8_t multipath_length [2]; +}; + +#define LSPPING_AFI_IPV4 1 +#define LSPPING_AFI_UNMB 2 +#define LSPPING_AFI_IPV6 3 + +static const struct tok lspping_tlv_downstream_addr_values[] = { + { LSPPING_AFI_IPV4, "IPv4"}, + { LSPPING_AFI_IPV6, "IPv6"}, + { LSPPING_AFI_UNMB, "Unnumbered"}, + { 0, NULL} +}; + void lspping_print(register const u_char *pptr, register u_int len) { @@ -408,6 +475,13 @@ lspping_print(register const u_char *pptr, register u_int len) { int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; int tlv_hexdump,subtlv_hexdump; int lspping_subtlv_len,lspping_subtlv_type; + struct timeval timestamp; + + union { + const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; + const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; + const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; + } tlv_ptr; union { const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; @@ -450,10 +524,11 @@ lspping_print(register const u_char *pptr, register u_int len) { tlen=len; - printf("\n\tLSP-PINGv%u, msg-type: %s (%u), reply-mode: %s (%u)", + printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", EXTRACT_16BITS(&lspping_com_header->version[0]), tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), lspping_com_header->msg_type, + len, tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), lspping_com_header->reply_mode); @@ -467,30 +542,39 @@ lspping_print(register const u_char *pptr, register u_int len) { lspping_com_header->return_code == 10 || lspping_com_header->return_code == 11 || lspping_com_header->return_code == 12 ) - printf("\n\t Return Code: %s %u (%u), Return Subcode: (%u)", + printf("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), lspping_com_header->return_subcode, lspping_com_header->return_code, lspping_com_header->return_subcode); else - printf("\n\t Return Code: %s (%u), Return Subcode: (%u)", + printf("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), lspping_com_header->return_code, lspping_com_header->return_subcode); - printf("\n\t Sender Handle: 0x%08x, Sequence: %u" \ - "\n\t Sender Timestamp %u.%us, Receiver Timestamp %u.%us", + printf("\n\t Sender Handle: 0x%08x, Sequence: %u", EXTRACT_32BITS(lspping_com_header->sender_handle), - EXTRACT_32BITS(lspping_com_header->seq_number), - EXTRACT_32BITS(lspping_com_header->ts_sent_sec), /* FIXME: replace with ts_print() */ - EXTRACT_32BITS(lspping_com_header->ts_sent_usec), - EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec), /* FIXME: replace with ts_print() */ - EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec)); + EXTRACT_32BITS(lspping_com_header->seq_number)); + + timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec); + timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec); + printf("\n\t Sender Timestamp: "); + ts_print(×tamp); + + timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec); + timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); + printf("Receiver Timestamp: "); + if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0)) + ts_print(×tamp); + else + printf("no timestamp"); tptr+=sizeof(const struct lspping_common_header); tlen-=sizeof(const struct lspping_common_header); while(tlen>(int)sizeof(struct lspping_tlv_header)) { + /* did we capture enough for fully decoding the tlv header ? */ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) goto trunc; @@ -499,10 +583,11 @@ lspping_print(register const u_char *pptr, register u_int len) { lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); - if (lspping_tlv_len == 0) + /* some little sanity checking */ + if (lspping_tlv_type == 0 || lspping_tlv_len == 0) return; - if(lspping_tlv_len % 4 || lspping_tlv_len < 4) { /* aligned to four octet boundary */ + if(lspping_tlv_len < 4) { printf("\n\t ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len); return; } @@ -692,12 +777,96 @@ lspping_print(register const u_char *pptr, register u_int len) { } break; + case LSPPING_TLV_DOWNSTREAM_MAPPING: + /* that strange thing with the downstream map TLV is that until now + * we do not know if its IPv4 or IPv6 , after we found the adress-type + * lets recast the tlv_tptr and move on */ + + tlv_ptr.lspping_tlv_downstream_map_ipv4= \ + (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; + tlv_ptr.lspping_tlv_downstream_map_ipv6= \ + (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; + printf("\n\t MTU: %u, Address-Type: %s (%u)", + EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu), + tok2str(lspping_tlv_downstream_addr_values, + "unknown", + tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type), + tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type); + + switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) { + + case LSPPING_AFI_IPV4: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface IP: %s", + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + break; +#ifdef INET6 + case LSPPING_AFI_IPV6: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface IP: %s", + ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), + ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); + break; +#endif + case LSPPING_AFI_UNMB: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface Index: 0x%08x", + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), + EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + break; + + default: + /* should not happen ! - no error message - tok2str() has barked already */ + break; + } + + tlv_ptr.lspping_tlv_downstream_map_info= \ + (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; + + /* FIXME add hash-key type, depth limit, multipath processing */ + + + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t); + + /* FIXME print downstream labels */ + + + tlv_hexdump=TRUE; /* dump the TLV until code complete */ + + break; + + case LSPPING_TLV_BFD_DISCRIMINATOR: + tptr += sizeof(struct lspping_tlv_header); + if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN)) + goto trunc; + printf("\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)); + break; + + case LSPPING_TLV_VENDOR_ENTERPRISE: + { + u_int32_t vendor_id; + + if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN)) + goto trunc; + vendor_id = EXTRACT_32BITS(tlv_tptr); + printf("\n\t Vendor: %s (0x%04x)", + tok2str(smi_values, "Unknown", vendor_id), + vendor_id); + } + break; + /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ - - case LSPPING_TLV_DOWNSTREAM_MAPPING: case LSPPING_TLV_PAD: case LSPPING_TLV_ERROR_CODE: case LSPPING_TLV_VENDOR_PRIVATE: @@ -712,7 +881,13 @@ lspping_print(register const u_char *pptr, register u_int len) { print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t ", lspping_tlv_len); - tptr+=lspping_tlv_len; + + /* All TLVs are aligned to four octet boundary */ + if (lspping_tlv_len % 4) { + lspping_tlv_len += (4 - lspping_tlv_len % 4); + } + + tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); } return;