From: hannes Date: Sun, 6 Jun 2004 19:20:03 +0000 (+0000) Subject: add baseline LSP-PING support per draft-ietf-mpls-lsp-ping-05 X-Git-Tag: tcpdump-3.9.1~350 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/21480b97d89d0edebe1cb706503a9bee117bd9db add baseline LSP-PING support per draft-ietf-mpls-lsp-ping-05 --- diff --git a/FILES b/FILES index d95347fc..0883644b 100644 --- a/FILES +++ b/FILES @@ -143,6 +143,7 @@ print-lane.c print-ldp.c print-llc.c print-lmp.c +print-lspping.c print-lwres.c print-mobile.c print-mobility.c diff --git a/Makefile.in b/Makefile.in index 2f113dcb..47f1d278 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # -# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.286 2004-04-30 22:22:05 hannes Exp $ (LBL) +# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.287 2004-06-06 19:20:04 hannes Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -76,7 +76,8 @@ CSRC = addrtoname.c gmpls.c oui.c gmt2local.c ipproto.c machdep.c parsenfsfh.c \ print-gre.c print-hsrp.c print-icmp.c print-igmp.c \ print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \ print-ipx.c print-isakmp.c print-isoclns.c print-krb.c \ - print-l2tp.c print-lane.c print-ldp.c print-llc.c print-lmp.c \ + print-l2tp.c print-lane.c print-ldp.c print-llc.c \ + print-lmp.c print-lspping.c \ print-lwres.c print-mobile.c print-mpls.c print-msdp.c \ print-nfs.c print-ntp.c print-null.c print-ospf.c \ print-pflog.c print-pim.c print-ppp.c print-pppoe.c \ diff --git a/interface.h b/interface.h index aee96623..c9aca357 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.230 2004-04-30 22:42:25 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.231 2004-06-06 19:20:05 hannes Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -225,6 +225,7 @@ extern void cisco_autorp_print(const u_char *, u_int); extern void rsvp_print(const u_char *, u_int); extern void ldp_print(const u_char *, u_int); extern void lmp_print(const u_char *, u_int); +extern void lspping_print(const u_char *, u_int); extern void eigrp_print(const u_char *, u_int); extern void mobile_print(const u_char *, u_int); extern void pim_print(const u_char *, u_int); diff --git a/print-lspping.c b/print-lspping.c new file mode 100644 index 00000000..e23874fe --- /dev/null +++ b/print-lspping.c @@ -0,0 +1,244 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.1 2004-06-06 19:20:03 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * LSPPING common header + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version Number | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Reply mode | Return Code | Return Subcode| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender's Handle | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Sent (seconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Sent (microseconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Received (seconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Received (microseconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLVs ... | + * . . + * . . + * . . + */ + +struct lspping_common_header { + u_int8_t version[2]; + u_int8_t reserved[2]; + u_int8_t msg_type; + u_int8_t reply_mode; + u_int8_t return_code; + u_int8_t return_subcode; + u_int8_t sender_handle[4]; + u_int8_t seq_number[4]; + u_int8_t ts_sent_sec[4]; + u_int8_t ts_sent_usec[4]; + u_int8_t ts_rcvd_sec[4]; + u_int8_t ts_rcvd_usec[4]; +}; + +#define LSPPING_VERSION 1 +#define FALSE 0 +#define TRUE 1 + +static const struct tok lspping_msg_type_values[] = { + { 1, "MPLS Echo Request"}, + { 2, "MPLS Echo Reply"}, + { 0, NULL} +}; + +static const struct tok lspping_reply_mode_values[] = { + { 1, "Do not reply"}, + { 2, "Reply via an IPv4/IPv6 UDP packet"}, + { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"}, + { 4, "Reply via application level control channel"}, + { 0, NULL} +}; + +/* + * LSPPING TLV header + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value | + * . . + * . . + * . . + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lspping_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; +}; + +#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 + +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" }, + { 0, NULL} +}; + +void +lspping_print(register const u_char *pptr, register u_int len) { + + const struct lspping_common_header *lspping_com_header; + const struct lspping_tlv_header *lspping_tlv_header; + const u_char *tptr,*tlv_tptr; + int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; + int hexdump; + + tptr=pptr; + lspping_com_header = (const struct lspping_common_header *)pptr; + TCHECK(*lspping_com_header); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) { + printf("LSP-PING version %u packet not supported", + EXTRACT_16BITS(&lspping_com_header->version[0])); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("LSP-PINGv%u, %s, seq %u, length: %u", + EXTRACT_16BITS(&lspping_com_header->version[0]), + tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type), + EXTRACT_32BITS(lspping_com_header->seq_number), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=len; + + printf("\n\tLSP-PINGv%u, msg-type: %s (%u), reply-mode: %s (%u)" \ + "\n\t Return Code: (%u), Return Subcode: (%u)" \ + "\n\t Sender Handle: 0x%08x, Sequence: %u" \ + "\n\t Sender Timestamp %u.%us, Receiver Timestamp %u.%us", + EXTRACT_16BITS(&lspping_com_header->version[0]), + tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), + lspping_com_header->msg_type, + tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), + lspping_com_header->reply_mode, + lspping_com_header->return_code, + lspping_com_header->return_subcode, + EXTRACT_32BITS(lspping_com_header->sender_handle), + EXTRACT_32BITS(lspping_com_header->seq_number), + EXTRACT_32BITS(lspping_com_header->ts_sent_sec), + EXTRACT_32BITS(lspping_com_header->ts_sent_usec), + EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec), + EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec)); + + tptr+=sizeof(const struct lspping_common_header); + tlen-=sizeof(const struct lspping_common_header); + + while(tlen>0) { + /* did we capture enough for fully decoding the tlv header ? */ + if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) + goto trunc; + + lspping_tlv_header = (const struct lspping_tlv_header *)tptr; + lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); + lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); + + if(lspping_tlv_len % 4 || lspping_tlv_len < 4) + return; + + printf("\n\t %s TLV (%u), length: %u", + tok2str(lspping_tlv_values, + "Unknown", + lspping_tlv_type), + lspping_tlv_type, + lspping_tlv_len); + + tlv_tptr=tptr+sizeof(struct lspping_tlv_header); + tlv_tlen=lspping_tlv_len-sizeof(struct lspping_tlv_header); + + /* did we capture enough for fully decoding the tlv ? */ + if (!TTEST2(*tptr, lspping_tlv_len)) + goto trunc; + hexdump=FALSE; + + switch(lspping_tlv_type) { + + /* + * FIXME those are the defined messages that lack a decoder + * you are welcome to contribute code ;-) + */ + + case LSPPING_TLV_TARGET_FEC_STACK: + case LSPPING_TLV_DOWNSTREAM_MAPPING: + case LSPPING_TLV_PAD: + case LSPPING_TLV_ERROR_CODE: + case LSPPING_TLV_VENDOR_PRIVATE: + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t ", + lspping_tlv_len-sizeof(struct lspping_tlv_header)); + + tptr+=lspping_tlv_len; + tlen-=lspping_tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-mpls.c b/print-mpls.c index 319e8b21..c56f2643 100644 --- a/print-mpls.c +++ b/print-mpls.c @@ -28,7 +28,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.10 2003-11-16 09:36:29 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.11 2004-06-06 19:20:04 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -183,14 +183,3 @@ mpls_print(const u_char *bp, u_int length) trunc: printf("[|MPLS]"); } - -/* - * draft-ietf-mpls-lsp-ping-02.txt - */ -void -mpls_lsp_ping_print(const u_char *pptr, u_int length) -{ - printf("UDP, LSP-PING, length: %u", length); - if (vflag >1) - print_unknown_data(pptr,"\n\t ", length); -} diff --git a/print-udp.c b/print-udp.c index 97ad680d..8c3759ea 100644 --- a/print-udp.c +++ b/print-udp.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.131 2004-04-19 21:17:14 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.132 2004-06-06 19:20:03 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -673,7 +673,7 @@ udp_print(register const u_char *bp, u_int length, else if (ISPORT(LDP_PORT)) ldp_print((const u_char *)(up + 1), length); else if (ISPORT(MPLS_LSP_PING_PORT)) - mpls_lsp_ping_print((const u_char *)(up + 1), length); + lspping_print((const u_char *)(up + 1), length); else if (dport == BFD_CONTROL_PORT || dport == BFD_ECHO_PORT ) bfd_print((const u_char *)(up+1), length, dport); diff --git a/tests/lsp-ping.pcap b/tests/lsp-ping.pcap new file mode 100644 index 00000000..33894e15 Binary files /dev/null and b/tests/lsp-ping.pcap differ