*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.14 2005-04-19 12:44:05 hannes Exp $";
-#endif
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "bgp.h"
#include "l2vpn.h"
+#include "oui.h"
/*
* 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 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];
};
#define LSPPING_VERSION 1
-#define FALSE 0
-#define TRUE 1
static const struct tok lspping_msg_type_values[] = {
{ 1, "MPLS Echo Request"},
};
-/*
+/*
* 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
#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}
};
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;
+ struct timeval timestamp;
union {
const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
lspping_com_header->return_code == 12 )
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_subcode,
lspping_com_header->return_code,
lspping_com_header->return_subcode);
else
printf("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)",
- tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
+ 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",
EXTRACT_32BITS(lspping_com_header->sender_handle),
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);
+ 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);
+ 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);
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;
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;
}
lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type);
lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length);
subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
-
+
if (lspping_subtlv_len == 0)
break;
"unknown",
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
-
+
break;
/* the old L2VPN VCID subTLV does not have support for the sender field */
"unknown",
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)),
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation));
-
+
break;
case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID:
"unknown",
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation));
-
+
break;
default:
}
/* do we want to see an additionally subtlv hexdump ? */
if (vflag > 1 || subtlv_hexdump==TRUE)
- print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \
+ print_unknown_data(gndo,tlv_tptr+sizeof(struct lspping_tlv_header), \
"\n\t ",
lspping_subtlv_len);
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 */
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_PAD:
case LSPPING_TLV_ERROR_CODE:
case LSPPING_TLV_VENDOR_PRIVATE:
-
+
default:
if (vflag <= 1)
- print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen);
+ print_unknown_data(gndo,tlv_tptr,"\n\t ",tlv_tlen);
break;
}
/* do we want to see an additionally tlv hexdump ? */
if (vflag > 1 || tlv_hexdump==TRUE)
- print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t ",
+ print_unknown_data(gndo,tptr+sizeof(struct lspping_tlv_header),"\n\t ",
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);
}
trunc:
printf("\n\t\t packet exceeded snapshot");
}
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */