--- /dev/null
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * complete BGP support.
+ */
+
+#ifndef tcpdump_decode_prefix_h
+#define tcpdump_decode_prefix_h
+
+extern int decode_prefix4(const u_char *pptr, char *buf, u_int buflen);
+#ifdef INET6
+extern int decode_prefix6(const u_char *pd, char *buf, u_int buflen);
+#endif
+
+#endif
* FOR A PARTICULAR PURPOSE.
*
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.6 2003-11-16 09:36:27 guy Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.7 2004-05-27 21:20:50 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include <string.h>
#include "interface.h"
+#include "decode_prefix.h"
#include "extract.h"
#include "addrtoname.h"
#define LDP_TLV_COMMON_SESSION 0x0500
#define LDP_TLV_ATM_SESSION_PARM 0x0501
#define LDP_TLV_FR_SESSION_PARM 0x0502
+#define LDP_TLV_FT_SESSION 0x0503
#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
static const struct tok ldp_tlv_values[] = {
{ LDP_TLV_COMMON_SESSION, "Common Session Parameters" },
{ 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_LABEL_REQUEST_MSG_ID, "Label Request Message ID" },
{ 0, NULL}
};
+#define LDP_FEC_WILDCARD 0x01
+#define LDP_FEC_PREFIX 0x02
+#define LDP_FEC_HOSTADDRESS 0x03
+/* From draft-martini-l2circuit-trans-mpls-13.txt */
+#define LDP_FEC_MARTINI_VC 0x80
+
+static const struct tok ldp_fec_values[] = {
+ { LDP_FEC_WILDCARD, "Wildcard" },
+ { LDP_FEC_PREFIX, "Prefix" },
+ { LDP_FEC_HOSTADDRESS, "Host address" },
+ { LDP_FEC_MARTINI_VC, "Martini VC" },
+ { 0, NULL}
+};
+
+/* From draft-martini-l2circuit-trans-mpls-13.txt */
+#define LDP_MARTINI_VCTYPE_FR_DLCI 0x0001
+#define LDP_MARTINI_VCTYPE_ATM_AAL5 0x0002
+#define LDP_MARTINI_VCTYPE_ATM_CELL 0x0003
+#define LDP_MARTINI_VCTYPE_ETH_VLAN 0x0004
+#define LDP_MARTINI_VCTYPE_ETHERNET 0x0005
+#define LDP_MARTINI_VCTYPE_HDLC 0x0006
+#define LDP_MARTINI_VCTYPE_PPP 0x0007
+#define LDP_MARTINI_VCTYPE_CEM 0x0008
+#define LDP_MARTINI_VCTYPE_ATM_VCC 0x0009
+#define LDP_MARTINI_VCTYPE_ATM_VPC 0x000A
+
+/* Overlaps print-bgp.c bgp_l2vpn_encaps_values */
+static const struct tok ldp_vctype_values[] = {
+ { LDP_MARTINI_VCTYPE_FR_DLCI, "Frame Relay DLCI" },
+ { LDP_MARTINI_VCTYPE_ATM_AAL5, "ATM AAL5 VCC transport" },
+ { LDP_MARTINI_VCTYPE_ATM_CELL, "ATM transparent cell transport" },
+ { LDP_MARTINI_VCTYPE_ETH_VLAN, "Ethernet VLAN" },
+ { LDP_MARTINI_VCTYPE_ETHERNET, "Ethernet" },
+ { LDP_MARTINI_VCTYPE_HDLC, "HDLC" },
+ { LDP_MARTINI_VCTYPE_PPP, "PPP" },
+ { LDP_MARTINI_VCTYPE_CEM, "SONET/SDH Circuit Emulation Service" },
+ { LDP_MARTINI_VCTYPE_ATM_VCC, "ATM VCC cell transport" },
+ { LDP_MARTINI_VCTYPE_ATM_VPC, "ATM VPC cell transport" },
+ { 0, NULL}
+};
+
+/* RFC1700 address family numbers, same definition in print-bgp.c */
+#define AFNUM_INET 1
+#define AFNUM_INET6 2
+
#define FALSE 0
#define TRUE 1
};
const struct ldp_tlv_header *ldp_tlv_header;
- u_short tlv_type,tlv_len,tlv_tlen;
+ u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
+ u_char fec_type;
+ u_int ui;
+ char buf[100];
+ int i;
ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr));
break;
+ case LDP_TLV_ADDRESS_LIST:
+ af = EXTRACT_16BITS(tptr);
+ tptr+=2;
+ printf("\n\t Adress Family: ");
+ if (af == AFNUM_INET) {
+ printf("IPv4, addresses:");
+ for (i=0; i<(tlv_tlen-2)/4; i++) {
+ printf(" %s",ipaddr_string(tptr));
+ tptr+=4;
+ }
+ }
+#ifdef INET6
+ else if (af == AFNUM_INET6) {
+ printf("IPv6, addresses:");
+ for (i=0; i<(tlv_tlen-2)/16; i++) {
+ printf(" %s",ip6addr_string(tptr));
+ tptr+=16;
+ }
+ }
+#endif
+ break;
+
+ case LDP_TLV_COMMON_SESSION:
+ printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
+ EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
+ (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
+ (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled"
+ );
+ break;
+
+ case LDP_TLV_FEC:
+ fec_type = *tptr;
+ printf("\n\t %s FEC (0x%02x)",
+ tok2str(ldp_fec_values, "Unknown", fec_type),
+ fec_type);
+
+ tptr+=1;
+ switch(fec_type) {
+
+ case LDP_FEC_WILDCARD:
+ break;
+ case LDP_FEC_PREFIX:
+ af = EXTRACT_16BITS(tptr);
+ tptr+=2;
+ if (af == AFNUM_INET) {
+ i=decode_prefix4(tptr,buf,sizeof(buf));
+ printf(": IPv4 prefix %s",buf);
+ }
+#ifdef INET6
+ else if (af == AFNUM_INET6) {
+ i=decode_prefix6(tptr,buf,sizeof(buf));
+ printf(": IPv6 prefix %s",buf);
+ }
+#endif
+ break;
+ case LDP_FEC_HOSTADDRESS:
+ break;
+ case LDP_FEC_MARTINI_VC:
+ printf(": %s, %scontrol word, VC %u",
+ tok2str(ldp_vctype_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
+ EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
+ EXTRACT_32BITS(tptr+7));
+ break;
+ }
+
+ break;
+
+ case LDP_TLV_GENERIC_LABEL:
+ printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
+ break;
+
+ case LDP_TLV_STATUS:
+ ui = EXTRACT_32BITS(tptr);
+ tptr+=4;
+ printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]",
+ ui&0x3fffffff,
+ ui&0x80000000 ? "Fatal error" : "Advisory Notification",
+ ui&0x40000000 ? "do" : "don't");
+ ui = EXTRACT_32BITS(tptr);
+ tptr+=4;
+ if (ui)
+ printf(", causing Message ID: 0x%08x", ui);
+ break;
+
+ case LDP_TLV_FT_SESSION:
+ ft_flags = EXTRACT_16BITS(tptr);
+ printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
+ ft_flags&0x8000 ? "" : "No ",
+ ft_flags&0x8 ? "" : "Don't ",
+ ft_flags&0x4 ? "" : "No ",
+ ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
+ ft_flags&0x1 ? "" : "Don't ");
+ tptr+=4;
+ ui = EXTRACT_32BITS(tptr);
+ if (ui)
+ printf(", Reconnect Timeout: %ums", ui);
+ tptr+=4;
+ ui = EXTRACT_32BITS(tptr);
+ if (ui)
+ printf(", Recovery Time: %ums", ui);
+ break;
+
+
/*
* FIXME those are the defined TLVs that lack a decoder
* you are welcome to contribute code ;-)
*/
- case LDP_TLV_FEC:
- case LDP_TLV_ADDRESS_LIST:
case LDP_TLV_HOP_COUNT:
case LDP_TLV_PATH_VECTOR:
- case LDP_TLV_GENERIC_LABEL:
case LDP_TLV_ATM_LABEL:
case LDP_TLV_FR_LABEL:
- case LDP_TLV_STATUS:
case LDP_TLV_EXTD_STATUS:
case LDP_TLV_RETURNED_PDU:
case LDP_TLV_RETURNED_MSG:
- case LDP_TLV_COMMON_SESSION:
case LDP_TLV_ATM_SESSION_PARM:
case LDP_TLV_FR_SESSION_PARM:
case LDP_TLV_LABEL_REQUEST_MSG_ID:
/* ok they seem to want to know everything - lets fully decode it */
tlen=EXTRACT_16BITS(ldp_com_header->pdu_length);
- tptr+=sizeof(const struct ldp_common_header);
- tlen-=sizeof(const struct ldp_common_header);
+ tptr += sizeof(const struct ldp_common_header);
+ tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */
while(tlen>0) {
/* did we capture enough for fully decoding the msg header ? */
switch(msg_type) {
+ case LDP_MSG_NOTIF:
case LDP_MSG_HELLO:
+ case LDP_MSG_INIT:
+ case LDP_MSG_KEEPALIVE:
+ case LDP_MSG_ADDRESS:
+ case LDP_MSG_LABEL_MAPPING:
while(msg_tlen >= 4) {
processed = ldp_tlv_print(msg_tptr);
if (processed == 0)
* you are welcome to contribute code ;-)
*/
- case LDP_MSG_NOTIF:
- case LDP_MSG_INIT:
- case LDP_MSG_KEEPALIVE:
- case LDP_MSG_ADDRESS:
case LDP_MSG_ADDRESS_WITHDRAW:
- case LDP_MSG_LABEL_MAPPING:
case LDP_MSG_LABEL_REQUEST:
case LDP_MSG_LABEL_WITHDRAW:
case LDP_MSG_LABEL_RELEASE:
print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ",
msg_len);
- tptr+=msg_len;
- tlen-=msg_len;
+ tptr += msg_len+4;
+ tlen -= msg_len+4;
}
return;
trunc: