From: guy Date: Tue, 10 Oct 2000 05:40:21 +0000 (+0000) Subject: Pick up FreeBSD "print-isoclns.c". X-Git-Tag: tcpdump-3.5.1~92 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/663b46c54997112966b58fa01cea64123e5978e9?hp=bcd835dad7dddcfffe058537e9d8639e0287fbc7 Pick up FreeBSD "print-isoclns.c". --- diff --git a/CREDITS b/CREDITS index 63d2ee6a..f71a7125 100644 --- a/CREDITS +++ b/CREDITS @@ -32,9 +32,11 @@ Additional people who have contributed patches: Michael T. Stolarchuk Motonori Shindo Onno van der Linden + Pasvorn Boonmark Rafal Maszkowski Richard Sharpe Rick Jones + Tony Li The original LBL crew: Steve McCanne diff --git a/print-isoclns.c b/print-isoclns.c index f54a26b1..4df98374 100644 --- a/print-isoclns.c +++ b/print-isoclns.c @@ -23,7 +23,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.20 2000-10-06 04:23:12 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.21 2000-10-10 05:40:22 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -41,19 +41,143 @@ static const char rcsid[] = #include "interface.h" #include "addrtoname.h" #include "ethertype.h" +#include "ether.h" +#include "extract.h" -#define CLNS 129 -#define ESIS 130 -#define ISIS 131 -#define NULLNS 0 +#define NLPID_CLNS 129 /* 0x81 */ +#define NLPID_ESIS 130 /* 0x82 */ +#define NLPID_ISIS 131 /* 0x83 */ +#define NLPID_NULLNS 0 -static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *); + +/* + * IS-IS is defined in ISO 10589. Look there for protocol definitions. + */ + +#define SYSTEM_ID_LEN ETHER_ADDR_LEN +#define ISIS_VERSION 1 +#define PDU_TYPE_MASK 0x1F +#define PRIORITY_MASK 0x7F + +#define L1_LAN_IIH 15 +#define L2_LAN_IIH 16 +#define PTP_IIH 17 +#define L1_LS_PDU 18 +#define L2_LS_PDU 19 +#define L1_COMPLETE_SEQ_PDU 24 +#define L2_COMPLETE_SEQ_PDU 25 + +/* + * A TLV is a tuple of a type, length and a value and is normally used for + * encoding information in all sorts of places. This is an enumeration of + * the well known types. + */ + +#define TLV_AREA_ADDR 1 +#define TLV_IS_REACH 2 +#define TLV_ES_REACH 3 +#define TLV_SUMMARY 5 +#define TLV_ISNEIGH 6 +#define TLV_PADDING 8 +#define TLV_LSP 9 +#define TLV_AUTHENT 10 +#define TLV_IP_REACH 128 +#define TLV_PROTOCOLS 129 +#define TLV_IP_EXTERN 130 +#define TLV_IDRP_INFO 131 +#define TLV_IPADDR 132 +#define TLV_IPAUTH 133 +#define TLV_PTP_ADJ 240 + +/* + * Katz's point to point adjacency TLV uses codes to tell us the state of + * the remote adjacency. Enumerate them. + */ + +#define ISIS_PTP_ADJ_UP 0 +#define ISIS_PTP_ADJ_INIT 1 +#define ISIS_PTP_ADJ_DOWN 2 + +static int osi_cksum(const u_char *, int, u_char *); static void esis_print(const u_char *, u_int); +static int isis_print(const u_char *, u_int); + + +struct isis_ptp_adjancey_values { + u_char id; + char *name; +}; + +static struct isis_ptp_adjancey_values isis_ptp_adjancey_values[] = { + { ISIS_PTP_ADJ_UP, "UP" }, + { ISIS_PTP_ADJ_INIT, "INIT" }, + { ISIS_PTP_ADJ_DOWN, "DOWN" } +}; + +struct isis_common_header { + u_char nlpid; + u_char fixed_len; + u_char version; /* Protocol version? */ + u_char id_length; + u_char enc_pdu_type; /* 3 MSbs are reserved */ + u_char pkt_version; /* Packet format version? */ + u_char reserved; + u_char enc_max_area; +}; + +struct isis_header { + u_char nlpid; + u_char fixed_len; + u_char version; /* Protocol version? */ + u_char id_length; + u_char enc_pdu_type; /* 3 MSbs are reserved */ + u_char pkt_version; /* Packet format version? */ + u_char reserved; + u_char enc_max_area; + u_char circuit; + u_char enc_source_id[SYSTEM_ID_LEN]; + u_char enc_holding_time[2]; + u_char enc_packet_len[2]; + u_char enc_priority; + u_char enc_lan_id[SYSTEM_ID_LEN+1]; +}; +struct isis_lan_header { + u_char circuit; + u_char enc_source_id[SYSTEM_ID_LEN]; + u_char enc_holding_time[2]; + u_char enc_packet_len[2]; + u_char enc_priority; + u_char enc_lan_id[SYSTEM_ID_LEN+1]; +}; + +struct isis_ptp_header { + u_char circuit; + u_char enc_source_id[SYSTEM_ID_LEN]; + u_char enc_holding_time[2]; + u_char enc_packet_len[2]; + u_char loc_circuit_id; +}; + +#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) +#define ISIS_HEADER_SIZE (15+(SYSTEM_ID_LEN<<1)) +#define ISIS_PTP_HEADER_SIZE (14+SYSTEM_ID_LEN) +#define L1_LS_PDU_HEADER_SIZE (21+SYSTEM_ID_LEN) +#define L2_LS_PDU_HEADER_SIZE L1_LS_PDU_HEADER_SIZE +#define L1_COMPLETE_SEQ_PDU_HEADER_SIZE 33 +#define L2_COMPLETE_SEQ_PDU_HEADER_SIZE L1_COMPLETE_SEQ_PDU_HEADER_SIZE + + void isoclns_print(const u_char *p, u_int length, u_int caplen, const u_char *esrc, const u_char *edst) { + u_char pdu_type; + struct isis_header *header; + + header = (struct isis_header *)p; + pdu_type = header->enc_pdu_type & PDU_TYPE_MASK; + if (caplen < 1) { printf("[|iso-clns] "); if (!eflag) @@ -65,17 +189,16 @@ isoclns_print(const u_char *p, u_int length, u_int caplen, switch (*p) { - case CLNS: - /* esis_print(&p, &length); */ - printf("iso-clns"); + case NLPID_CLNS: + printf("iso clns"); if (!eflag) (void)printf(" %s > %s", etheraddr_string(esrc), etheraddr_string(edst)); break; - case ESIS: - printf("iso-esis"); + case NLPID_ESIS: + printf("iso esis"); if (!eflag) (void)printf(" %s > %s", etheraddr_string(esrc), @@ -83,20 +206,21 @@ isoclns_print(const u_char *p, u_int length, u_int caplen, esis_print(p, length); return; - case ISIS: - printf("iso-isis"); - if (!eflag) - (void)printf(" %s > %s", + case NLPID_ISIS: + printf("iso isis"); + if (!eflag) { + if(pdu_type != PTP_IIH) + (void)printf(" %s > %s", etheraddr_string(esrc), etheraddr_string(edst)); - /* isis_print(&p, &length); */ + } (void)printf(" len=%d ", length); - if (caplen > 1) - default_print_unaligned(p, caplen); + if (!isis_print(p, length)) + default_print_unaligned(p, caplen); break; - case NULLNS: - printf("iso-nullns"); + case NLPID_NULLNS: + printf("iso nullns"); if (!eflag) (void)printf(" %s > %s", etheraddr_string(esrc), @@ -104,7 +228,7 @@ isoclns_print(const u_char *p, u_int length, u_int caplen, break; default: - printf("iso-clns %02x", p[0]); + printf("iso clns %02x", p[0]); if (!eflag) (void)printf(" %s > %s", etheraddr_string(esrc), @@ -134,7 +258,6 @@ esis_print(const u_char *p, u_int length) const u_char *ep; int li = p[1]; const struct esis_hdr *eh = (const struct esis_hdr *) &p[2]; - u_char cksum[2]; u_char off[2]; if (length == 2) { @@ -182,9 +305,10 @@ esis_print(const u_char *p, u_int length) } off[0] = eh->cksum[0]; off[1] = eh->cksum[1]; - if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) { - printf(" bad cksum (got %02x%02x want %02x%02x)", - eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]); + if (vflag && osi_cksum(p, li, off)) { + printf(" bad cksum (got %02x%02x)", + eh->cksum[1], eh->cksum[0]); + default_print(p, length); return; } if (eh->version != 1) { @@ -201,7 +325,7 @@ esis_print(const u_char *p, u_int length) dst = p; p += *p + 1; if (p > snapend) return; - printf(" %s", isonsap_string(dst)); + printf("\n\t\t\t %s", isonsap_string(dst)); snpa = p; p += *p + 1; is = p; p += *p + 1; if (p > snapend) @@ -232,7 +356,8 @@ esis_print(const u_char *p, u_int length) } if (p > snapend) return; - printf(" %s", isonsap_string(is)); + if (!qflag) + printf("\n\t\t\t %s", isonsap_string(is)); li = ep - p; break; } @@ -279,36 +404,268 @@ esis_print(const u_char *p, u_int length) } } +/* + * print_nsap + * Print out an NSAP. + */ + +static void +print_nsap (register const u_char *cp, register int length) +{ + int i; + + for (i = 0; i < length; i++) { + printf("%02x", *cp++); + if (((i & 1) == 0) && (i + 1 < length)) { + printf("."); + } + + } +} + +/* + * isis_print + * Decode IS-IS packets. Return 0 on error. + * + * So far, this is only smart enough to print IIH's. Someday... + */ + static int -osi_cksum(register const u_char *p, register u_int len, - const u_char *toff, u_char *cksum, u_char *off) +isis_print (const u_char *p, u_int length) +{ + struct isis_header *header; + struct isis_ptp_header *header_ptp; + u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen; + u_short packet_len, holding_time; + int i; + + header_ptp = (struct isis_ptp_header *)header = (struct isis_header *)p; + printf("\n\t\t\t"); + + /* + * Sanity checking of the header. + */ + if (header->nlpid != NLPID_ISIS) { + printf(" coding error!"); + return(0); + } + + if (header->version != ISIS_VERSION) { + printf(" version %d packet not supported", header->version); + return(0); + } + + if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) { + printf(" system ID length of %d is not supported", + header->id_length); + return(0); + } + + if ((header->fixed_len != ISIS_HEADER_SIZE) && + (header->fixed_len != ISIS_PTP_HEADER_SIZE) && + (header->fixed_len != L1_LS_PDU_HEADER_SIZE) && + (header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) { + printf(" bogus fixed header length %u", + header->fixed_len); + return(0); + } + + pdu_type = header->enc_pdu_type & PDU_TYPE_MASK; + if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH) && + (pdu_type != PTP_IIH) && + (pdu_type != L1_COMPLETE_SEQ_PDU) && + (pdu_type != L2_COMPLETE_SEQ_PDU) ) { + printf(" PDU type (%d) not supported", pdu_type); + return(0); + } + + if (header->pkt_version != ISIS_VERSION) { + printf(" version %d packet not supported", header->pkt_version); + return(0); + } + + max_area = header->enc_max_area; + switch(max_area) { + case 0: + max_area = 3; /* silly shit */ + break; + case 255: + printf(" bad packet -- 255 areas"); + return(0); + default: + break; + } + + switch (header->circuit) { + case 0: + printf(" PDU with circuit type 0"); + return(0); + case 1: + if (pdu_type == L2_LAN_IIH) { + printf(" L2 IIH on an L1 only circuit"); + return(0); + } + break; + case 2: + if (pdu_type == L1_LAN_IIH) { + printf(" L1 IIH on an L2 only circuit"); + return(0); + } + break; + case 3: + break; + default: + printf(" unknown circuit type"); + return(0); + } + + holding_time = EXTRACT_16BITS(header->enc_holding_time); + + packet_len = EXTRACT_16BITS(header->enc_packet_len); + if ((packet_len < ISIS_HEADER_SIZE) || + (packet_len > length)) { + printf(" bogus packet length %d, real length %d", packet_len, + length); + return(0); + } + + if(pdu_type != PTP_IIH) + priority = header->enc_priority & PRIORITY_MASK; + + /* + * Now print the fixed header. + */ + switch (pdu_type) { + case L1_LAN_IIH: + printf(" L1 lan iih, "); + break; + case L2_LAN_IIH: + printf(" L2 lan iih, "); + break; + case PTP_IIH: + printf(" PTP iih, "); + break; + } + + printf("circuit "); + switch (header->circuit) { + case 1: + printf("l1 only, "); + break; + case 2: + printf("l2 only, "); + break; + case 3: + printf("l1-l2, "); + break; + } + + printf ("holding time %d ", holding_time); + printf ("\n\t\t\t source %s, length %d", + etheraddr_string(header->enc_source_id), packet_len); + if((pdu_type==L1_LAN_IIH)||(pdu_type==L2_LAN_IIH)) + printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id), + header->enc_lan_id[SYSTEM_ID_LEN]); + + /* + * Now print the TLV's. + */ + if(pdu_type==PTP_IIH) { + packet_len -= ISIS_PTP_HEADER_SIZE; + pptr = (char *)p + ISIS_PTP_HEADER_SIZE; + } else { + packet_len -= ISIS_HEADER_SIZE; + pptr = (char *)p + ISIS_HEADER_SIZE; + } + while (packet_len >= 2) { + if (pptr >= snapend) { + printf("\n\t\t\t packet exceeded snapshot"); + return(1); + } + type = *pptr++; + len = *pptr++; + packet_len -= 2; + if (len > packet_len) { + break; + } + + switch (type) { + case TLV_AREA_ADDR: + printf("\n\t\t\t area addresses"); + tmp = len; + tptr = pptr; + alen = *tptr++; + while (tmp && alen < tmp) { + printf("\n\t\t\t "); + print_nsap(tptr, alen); + printf(" (%d)", alen); + tptr += alen; + tmp -= alen + 1; + alen = *tptr++; + } + break; + case TLV_ISNEIGH: + printf("\n\t\t\t neighbor addresses"); + tmp = len; + tptr = pptr; + while (tmp >= ETHER_ADDR_LEN) { + printf("\n\t\t\t %s", etheraddr_string(tptr)); + tmp -= ETHER_ADDR_LEN; + tptr += ETHER_ADDR_LEN; + } + break; + case TLV_PADDING: + printf("\n\t\t\t padding for %d bytes", len); + break; + case TLV_AUTHENT: + printf("\n\t\t\t authentication data"); + default_print(pptr, len); + break; + case TLV_PTP_ADJ: + printf("\n\t\t\t PTP adjacency status %s", + isis_ptp_adjancey_values[*pptr].name); + break; + case TLV_PROTOCOLS: + printf("\n\t\t\t Supports protocols %s", (len>1)? "are":"is"); + for(i=0;i= 0) { c0 += *p++; - c1 += c0; c0 %= 255; + c1 += c0; c1 %= 255; } - x = (c0 * f - c1); - if (x < 0) - x = 255 - (-x % 255); - else - x %= 255; - y = -1 * (x + c0); - if (y < 0) - y = 255 - (-y % 255); - else - y %= 255; - - off[0] = x; - off[1] = y; - - return (off[0] != cksum[0] || off[1] != cksum[1]); + return (c0 | c1); }