From 281e9d71408deb6e8c5046c746c2e97002b0e7fe Mon Sep 17 00:00:00 2001 From: bms Date: Wed, 31 Mar 2004 09:17:26 +0000 Subject: Import tcpdump 3.8.3, from http://www.tcpdump.org/releases/tcpdump-3.8.3.tar.gz --- contrib/tcpdump/print-ldp.c | 382 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 contrib/tcpdump/print-ldp.c (limited to 'contrib/tcpdump/print-ldp.c') diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c new file mode 100644 index 0000000..1162ac3 --- /dev/null +++ b/contrib/tcpdump/print-ldp.c @@ -0,0 +1,382 @@ +/* + * 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-ldp.c,v 1.4.2.2 2003/11/16 08:51:31 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * ldp 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 | PDU Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LDP Identifier | + * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct ldp_common_header { + u_int8_t version[2]; + u_int8_t pdu_length[2]; + u_int8_t lsr_id[4]; + u_int8_t label_space[2]; +}; + +#define LDP_VERSION 1 + +/* + * ldp message 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U| Message Type | Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Mandatory Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Optional Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct ldp_msg_header { + u_int8_t type[2]; + u_int8_t length[2]; + u_int8_t id[4]; +}; + +#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) +#define LDP_MASK_U_BIT(x) ((x)&0x8000) + +#define LDP_MSG_NOTIF 0x0001 +#define LDP_MSG_HELLO 0x0100 +#define LDP_MSG_INIT 0x0200 +#define LDP_MSG_KEEPALIVE 0x0201 +#define LDP_MSG_ADDRESS 0x0300 +#define LDP_MSG_ADDRESS_WITHDRAW 0x0301 +#define LDP_MSG_LABEL_MAPPING 0x0400 +#define LDP_MSG_LABEL_REQUEST 0x0401 +#define LDP_MSG_LABEL_WITHDRAW 0x0402 +#define LDP_MSG_LABEL_RELEASE 0x0403 +#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404 + +#define LDP_VENDOR_PRIVATE_MIN 0x3e00 +#define LDP_VENDOR_PRIVATE_MAX 0x3eff +#define LDP_EXPERIMENTAL_MIN 0x3f00 +#define LDP_EXPERIMENTAL_MAX 0x3fff + +static const struct tok ldp_msg_values[] = { + { LDP_MSG_NOTIF, "Notification" }, + { LDP_MSG_HELLO, "Hello" }, + { LDP_MSG_INIT, "Initialization" }, + { LDP_MSG_KEEPALIVE, "Keepalive" }, + { LDP_MSG_ADDRESS, "Address" }, + { LDP_MSG_ADDRESS_WITHDRAW, "Address Widthdraw" }, + { LDP_MSG_LABEL_MAPPING, "Label Mapping" }, + { LDP_MSG_LABEL_REQUEST, "Label Request" }, + { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" }, + { LDP_MSG_LABEL_RELEASE, "Label Release" }, + { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" }, + { 0, NULL} +}; + +#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff) +#define LDP_MASK_F_BIT(x) ((x)&0x4000) + +#define LDP_TLV_FEC 0x0100 +#define LDP_TLV_ADDRESS_LIST 0x0101 +#define LDP_TLV_HOP_COUNT 0x0103 +#define LDP_TLV_PATH_VECTOR 0x0104 +#define LDP_TLV_GENERIC_LABEL 0x0200 +#define LDP_TLV_ATM_LABEL 0x0201 +#define LDP_TLV_FR_LABEL 0x0202 +#define LDP_TLV_STATUS 0x0300 +#define LDP_TLV_EXTD_STATUS 0x0301 +#define LDP_TLV_RETURNED_PDU 0x0302 +#define LDP_TLV_RETURNED_MSG 0x0303 +#define LDP_TLV_COMMON_HELLO 0x0400 +#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401 +#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402 +#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403 +#define LDP_TLV_COMMON_SESSION 0x0500 +#define LDP_TLV_ATM_SESSION_PARM 0x0501 +#define LDP_TLV_FR_SESSION_PARM 0x0502 +#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600 + +static const struct tok ldp_tlv_values[] = { + { LDP_TLV_FEC, "FEC" }, + { LDP_TLV_ADDRESS_LIST, "Address List" }, + { LDP_TLV_HOP_COUNT, "Hop Count" }, + { LDP_TLV_PATH_VECTOR, "Path Vector" }, + { LDP_TLV_GENERIC_LABEL, "Generic Label" }, + { LDP_TLV_ATM_LABEL, "ATM Label" }, + { LDP_TLV_FR_LABEL, "Frame-Relay Label" }, + { LDP_TLV_STATUS, "Status" }, + { LDP_TLV_EXTD_STATUS, "Extended Status" }, + { LDP_TLV_RETURNED_PDU, "Returned PDU" }, + { LDP_TLV_RETURNED_MSG, "Returned Message" }, + { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" }, + { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" }, + { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" }, + { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" }, + { 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_LABEL_REQUEST_MSG_ID, "Label Request Message ID" }, + { 0, NULL} +}; + +#define FALSE 0 +#define TRUE 1 + +int ldp_tlv_print(register const u_char *); + +/* + * ldp 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U|F| Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Value | + * ~ ~ + * | | + * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +int +ldp_tlv_print(register const u_char *tptr) { + + struct ldp_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; + }; + + const struct ldp_tlv_header *ldp_tlv_header; + u_short tlv_type,tlv_len,tlv_tlen; + + ldp_tlv_header = (const struct ldp_tlv_header *)tptr; + tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); + tlv_tlen=tlv_len; + tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", + tok2str(ldp_tlv_values, + "Unknown", + tlv_type), + tlv_type, + tlv_len, + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore", + LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't"); + + tptr+=sizeof(struct ldp_tlv_header); + + switch(tlv_type) { + + case LDP_TLV_COMMON_HELLO: + printf("\n\t Hold Time: %us, Flags: [%s Hello%s]", + EXTRACT_16BITS(tptr), + (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", + (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : ""); + break; + + case LDP_TLV_IPV4_TRANSPORT_ADDR: + printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr)); + break; +#ifdef INET6 + case LDP_TLV_IPV6_TRANSPORT_ADDR: + printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr)); + break; +#endif + case LDP_TLV_CONFIG_SEQ_NUMBER: + printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr)); + 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: + + default: + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlv_tlen); + break; + } + return(tlv_len+4); /* Type & Length fields not included */ +} + +void +ldp_print(register const u_char *pptr, register u_int len) { + + const struct ldp_common_header *ldp_com_header; + const struct ldp_msg_header *ldp_msg_header; + const u_char *tptr,*msg_tptr; + u_short tlen; + u_short msg_len,msg_type,msg_tlen; + int hexdump,processed; + + tptr=pptr; + ldp_com_header = (const struct ldp_common_header *)pptr; + TCHECK(*ldp_com_header); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { + printf("LDP version %u packet not supported", + EXTRACT_16BITS(&ldp_com_header->version)); + return; + } + + /* print the LSR-ID, label-space & length */ + printf("%sLDP, Label-Space-ID: %s:%u, length: %u", + (vflag < 1) ? "" : "\n\t", + ipaddr_string(&ldp_com_header->lsr_id), + EXTRACT_16BITS(&ldp_com_header->label_space), + len); + + /* bail out if non-verbose */ + if (vflag < 1) + return; + + /* 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); + + while(tlen>0) { + /* did we capture enough for fully decoding the msg header ? */ + if (!TTEST2(*tptr, sizeof(struct ldp_msg_header))) + goto trunc; + + ldp_msg_header = (const struct ldp_msg_header *)tptr; + msg_len=EXTRACT_16BITS(ldp_msg_header->length); + msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + EXTRACT_32BITS(&ldp_msg_header->id), + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore"); + + msg_tptr=tptr+sizeof(struct ldp_msg_header); + msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ + + /* did we capture enough for fully decoding the message ? */ + if (!TTEST2(*tptr, msg_len)) + goto trunc; + hexdump=FALSE; + + switch(msg_type) { + + case LDP_MSG_HELLO: + while(msg_tlen >= 4) { + processed = ldp_tlv_print(msg_tptr); + if (processed == 0) + break; + msg_tlen-=processed; + msg_tptr+=processed; + } + break; + + /* + * FIXME those are the defined messages that lack a decoder + * 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: + case LDP_MSG_LABEL_ABORT_REQUEST: + + default: + if (vflag <= 1) + print_unknown_data(msg_tptr,"\n\t ",msg_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ", + msg_len); + + tptr+=msg_len; + tlen-=msg_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} + -- cgit v1.1