2 * Copyright (c) 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 * Original code by Matt Thomas, Digital Equipment Corporation
23 * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
24 * complete IS-IS support.
30 static const char rcsid[] =
31 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.36 2002/01/10 09:33:23 guy Exp $ (LBL)";
38 #include <sys/types.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
47 #include "interface.h"
48 #include "addrtoname.h"
49 #include "ethertype.h"
53 #define NLPID_CLNS 129 /* 0x81 */
54 #define NLPID_ESIS 130 /* 0x82 */
55 #define NLPID_ISIS 131 /* 0x83 */
56 #define NLPID_IP6 0x8e
58 #define NLPID_NULLNS 0
61 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
64 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
65 #define ISIS_VERSION 1
66 #define PDU_TYPE_MASK 0x1F
67 #define PRIORITY_MASK 0x7F
81 * A TLV is a tuple of a type, length and a value and is normally used for
82 * encoding information in all sorts of places. This is an enumeration of
83 * the well known types.
86 #define TLV_AREA_ADDR 1
87 #define TLV_IS_REACH 2
88 #define TLV_ES_REACH 3
94 #define TLV_CHECKSUM 12
95 #define TLV_EXT_IS_REACH 22
96 #define TLV_IP_REACH 128
97 #define TLV_PROTOCOLS 129
98 #define TLV_IP_REACH_EXT 130
99 #define TLV_IDRP_INFO 131
100 #define TLV_IPADDR 132
101 #define TLV_IPAUTH 133
102 #define TLV_TE_ROUTER_ID 134
103 #define TLV_EXT_IP_REACH 135
104 #define TLV_HOSTNAME 137
105 #define TLV_RESTART_SIGNALING 211
106 #define TLV_MT_IS_REACH 222
107 #define TLV_MT_SUPPORTED 229
108 #define TLV_IP6ADDR 232
109 #define TLV_MT_REACH 235
110 #define TLV_IP6_REACH 236
111 #define TLV_PTP_ADJ 240
113 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
114 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
115 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
116 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
117 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
118 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
119 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
121 #define SUBTLV_AUTH_SIMPLE 1
122 #define SUBTLV_AUTH_MD5 54
124 #define ISIS_MASK_LEVEL_BITS(x) ((x)&0x1)
126 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
127 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
128 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
129 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
130 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
131 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
132 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
133 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
135 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
136 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
138 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
139 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
140 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
142 #define ISIS_MASK_RESTART_RR(x) ((x)&0x1)
143 #define ISIS_MASK_RESTART_RA(x) ((x)&0x2)
145 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
146 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
147 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
148 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
150 #define ISIS_LSP_TYPE_UNUSED0 0
151 #define ISIS_LSP_TYPE_LEVEL_1 1
152 #define ISIS_LSP_TYPE_UNUSED2 2
153 #define ISIS_LSP_TYPE_LEVEL_2 3
155 static struct tok isis_lsp_istype_values[] = {
156 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
157 { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
158 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
159 { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"},
163 static struct tok isis_nlpid_values[] = {
164 { NLPID_CLNS, "CLNS"},
166 { NLPID_IP6, "IPv6"},
171 * Katz's point to point adjacency TLV uses codes to tell us the state of
172 * the remote adjacency. Enumerate them.
175 #define ISIS_PTP_ADJ_UP 0
176 #define ISIS_PTP_ADJ_INIT 1
177 #define ISIS_PTP_ADJ_DOWN 2
179 static int osi_cksum(const u_char *, u_int, u_char *);
180 static void esis_print(const u_char *, u_int);
181 static int isis_print(const u_char *, u_int);
184 static struct tok isis_ptp_adjancey_values[] = {
185 { ISIS_PTP_ADJ_UP, "Up" },
186 { ISIS_PTP_ADJ_INIT, "Initializing" },
187 { ISIS_PTP_ADJ_DOWN, "Down" }
190 struct isis_tlv_ptp_adj {
191 u_char adjacency_state;
192 u_char ext_local_circuit_id[4];
193 u_char neighbor_sysid[SYSTEM_ID_LEN];
194 u_char neighbor_ext_local_circuit_id[4];
197 struct isis_tlv_ip_reach {
198 u_char metric_default;
200 u_char metric_expense;
206 struct isis_tlv_is_reach {
207 u_char metric_default;
209 u_char metric_expense;
211 u_char neighbor_nodeid[SYSTEM_ID_LEN+1];
215 struct isis_common_header {
218 u_char version; /* Protocol version? */
220 u_char pdu_type; /* 3 MSbs are reserved */
221 u_char pkt_version; /* Packet format version? */
226 struct isis_iih_lan_header {
228 u_char source_id[SYSTEM_ID_LEN];
229 u_char holding_time[2];
232 u_char lan_id[SYSTEM_ID_LEN+1];
235 struct isis_iih_ptp_header {
237 u_char source_id[SYSTEM_ID_LEN];
238 u_char holding_time[2];
243 struct isis_lsp_header {
245 u_char remaining_lifetime[2];
246 u_char lsp_id[SYSTEM_ID_LEN+2];
247 u_char sequence_number[4];
252 struct isis_csnp_header {
254 u_char source_id[SYSTEM_ID_LEN+1];
255 u_char start_lsp_id[SYSTEM_ID_LEN+2];
256 u_char end_lsp_id[SYSTEM_ID_LEN+2];
259 struct isis_psnp_header {
261 u_char source_id[SYSTEM_ID_LEN+1];
264 struct isis_tlv_lsp {
265 u_char remaining_lifetime[2];
266 u_char lsp_id[SYSTEM_ID_LEN+2];
267 u_char sequence_number[4];
271 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
272 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
273 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
274 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
275 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
276 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
278 void isoclns_print(const u_char *p, u_int length, u_int caplen,
279 const u_char *esrc, const u_char *edst)
282 const struct isis_common_header *header;
284 header = (const struct isis_common_header *)p;
285 pdu_type = header->pdu_type & PDU_TYPE_MASK;
288 printf("[|iso-clns] ");
289 if (!eflag && esrc != NULL && edst != NULL)
291 etheraddr_string(esrc),
292 etheraddr_string(edst));
299 (void)printf("CLNS(%d)", length);
300 if (!eflag && esrc != NULL && edst != NULL)
301 (void)printf(", %s > %s",
302 etheraddr_string(esrc),
303 etheraddr_string(edst));
307 (void)printf("ESIS");
308 if (!eflag && esrc != NULL && edst != NULL)
309 (void)printf(", %s > %s",
310 etheraddr_string(esrc),
311 etheraddr_string(edst));
312 esis_print(p, length);
316 (void)printf("ISIS(%d)", length);
317 if (!eflag && esrc != NULL && edst != NULL)
318 (void)printf(", %s > %s",
319 etheraddr_string(esrc),
320 etheraddr_string(edst));
321 if (!isis_print(p, length))
322 default_print_unaligned(p, caplen);
326 (void)printf("ISO NULLNS(%d)", length);
327 if (!eflag && esrc != NULL && edst != NULL)
328 (void)printf(", %s > %s",
329 etheraddr_string(esrc),
330 etheraddr_string(edst));
334 (void)printf("CLNS %02x(%d)", p[0], length);
335 if (!eflag && esrc != NULL && edst != NULL)
336 (void)printf(", %s > %s",
337 etheraddr_string(esrc),
338 etheraddr_string(edst));
340 default_print_unaligned(p, caplen);
345 #define ESIS_REDIRECT 6
358 esis_print(const u_char *p, u_int length)
362 const struct esis_hdr *eh;
369 printf(" no header at all!");
373 eh = (const struct esis_hdr *) &p[2];
379 printf(" LI(%d) > PDU size (%d)!", li, length);
382 if (li < sizeof(struct esis_hdr) + 2) {
386 printf(" too short for esis header %d:", li);
387 while (--length != 0)
388 printf("%02X", *p++);
392 switch (eh->type & 0x1f) {
407 printf(" type %d", eh->type & 0x1f);
410 off[0] = eh->cksum[0];
411 off[1] = eh->cksum[1];
412 if (vflag && osi_cksum(p, li, off)) {
413 printf(" bad cksum (got %02x%02x)",
414 eh->cksum[1], eh->cksum[0]);
415 default_print(p, length);
418 if (eh->version != 1) {
419 printf(" unsupported version %d", eh->version);
422 p += sizeof(*eh) + 2;
423 li -= sizeof(*eh) + 2; /* protoid * li */
425 switch (eh->type & 0x1f) {
426 case ESIS_REDIRECT: {
427 const u_char *dst, *snpa, *is;
429 dst = p; p += *p + 1;
432 printf("\n\t\t\t %s", isonsap_string(dst));
433 snpa = p; p += *p + 1;
442 printf(" > %s", etheraddr_string(&snpa[1]));
444 printf(" > %s", isonsap_string(is));
464 printf("\n\t\t\t %s", isonsap_string(is));
470 (void)printf(" len=%d", length);
471 if (length && p < snapend) {
472 length = snapend - p;
473 default_print(p, length);
478 while (p < ep && li) {
485 printf(" bad opts/li");
492 printf(" opt (%d) too long", op);
500 if (op == 198 && opli == 2) {
501 printf(" tmo=%d", q[0] * 256 + q[1]);
504 printf (" %d:<", op);
506 printf("%02x", *q++);
516 print_nsap(register const u_char *cp, register int length)
520 for (i = 0; i < length; i++) {
523 printf("%02x", *cp++);
524 if (((i & 1) == 0) && (i + 1 < length)) {
532 isis_print_sysid(const u_char *cp)
536 for (i = 1; i <= 6; i++) {
539 printf("%02x", *cp++);
548 isis_print_nodeid(const u_char *cp)
552 for (i = 1; i <= 7; i++) {
555 printf("%02x", *cp++);
564 isis_print_lspid(const u_char *cp)
568 for (i = 1; i <= 7; i++) {
569 printf("%02x", *cp++);
573 printf("-%02x", *cp);
577 isis_print_tlv_ip_reach (const u_char *cp, int length)
581 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
582 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
583 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
584 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
585 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
586 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
587 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
588 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
590 int mask, prefix_len;
591 const struct isis_tlv_ip_reach *tlv_ip_reach;
593 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
596 if (length < sizeof(*tlv_ip_reach)) {
597 printf("short IP reachability (%d vs %lu)", length,
598 (unsigned long)sizeof(*tlv_ip_reach));
602 if (!TTEST(*tlv_ip_reach))
605 mask = EXTRACT_32BITS(tlv_ip_reach->mask);
608 while (prefix_len <= 33) {
609 if (bitmasks[prefix_len++] == mask) {
616 * 34 indicates no match -> must be a discontiguous netmask
617 * lets dump the mask, otherwise print the prefix_len
619 if (prefix_len == 34)
620 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u",
621 (tlv_ip_reach->prefix)[0],
622 (tlv_ip_reach->prefix)[1],
623 (tlv_ip_reach->prefix)[2],
624 (tlv_ip_reach->prefix)[3],
625 (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1],
626 (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]);
628 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u",
629 (tlv_ip_reach->prefix)[0],
630 (tlv_ip_reach->prefix)[1],
631 (tlv_ip_reach->prefix)[2],
632 (tlv_ip_reach->prefix)[3], prefix_len);
634 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
635 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default),
636 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_default) ? "External" : "Internal",
637 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->metric_default) ? "down" : "up");
639 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_delay))
640 printf("\n\t\t\t Delay Metric: %02d, %s",
641 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_delay),
642 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_delay) ? "External" : "Internal");
644 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_expense))
645 printf("\n\t\t\t Expense Metric: %02d, %s",
646 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_expense),
647 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_expense) ? "External" : "Internal");
649 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_error))
650 printf("\n\t\t\t Error Metric: %02d, %s",
651 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_error),
652 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_error) ? "External" : "Internal");
654 length -= sizeof(struct isis_tlv_ip_reach);
662 * Decode IS-IS packets. Return 0 on error.
665 static int isis_print (const u_char *p, u_int length)
667 const struct isis_common_header *header;
669 const struct isis_iih_lan_header *header_iih_lan;
670 const struct isis_iih_ptp_header *header_iih_ptp;
671 const struct isis_lsp_header *header_lsp;
672 const struct isis_csnp_header *header_csnp;
673 const struct isis_psnp_header *header_psnp;
675 const struct isis_tlv_lsp *tlv_lsp;
676 const struct isis_tlv_ptp_adj *tlv_ptp_adj;
677 const struct isis_tlv_is_reach *tlv_is_reach;
679 u_char pdu_type, max_area, type, len, tmp, alen, subl, subt, tslen, ttslen;
680 const u_char *optr, *pptr, *tptr;
681 u_short packet_len,pdu_len;
682 u_int i,j,bit_length,byte_length,metric;
683 u_char prefix[4]; /* copy buffer for ipv4 prefixes */
685 u_char prefix6[16]; /* copy buffer for ipv6 prefixes */
688 float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV */
691 optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */
692 header = (const struct isis_common_header *)p;
694 pptr = p+(ISIS_COMMON_HEADER_SIZE);
695 header_iih_lan = (const struct isis_iih_lan_header *)pptr;
696 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
697 header_lsp = (const struct isis_lsp_header *)pptr;
698 header_csnp = (const struct isis_csnp_header *)pptr;
699 header_psnp = (const struct isis_psnp_header *)pptr;
702 * Sanity checking of the header.
704 if (header->nlpid != NLPID_ISIS) {
705 printf(", coding error!");
709 if (header->version != ISIS_VERSION) {
710 printf(", version %d packet not supported", header->version);
714 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
715 printf(", system ID length of %d is not supported",
720 if (header->pkt_version != ISIS_VERSION) {
721 printf(", version %d packet not supported", header->pkt_version);
725 max_area = header->max_area;
728 max_area = 3; /* silly shit */
731 printf(", bad packet -- 255 areas");
737 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)",
743 pdu_type=header->pdu_type;
749 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
750 printf(", bogus fixed header length %u should be %lu",
751 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE);
755 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
756 if (packet_len>pdu_len) {
757 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
761 printf(", L%s Lan IIH (%u)",
762 ISIS_MASK_LEVEL_BITS(pdu_type) ? "1" : "2",
765 TCHECK(*header_iih_lan);
766 printf("\n\t\t source-id: ");
767 isis_print_sysid(header_iih_lan->source_id);
768 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan->holding_time));
769 switch(header_iih_lan->circuit_type) {
772 printf(", Level 1 only");
776 printf(", Level 2 only");
780 printf(", Level 1, Level 2");
784 printf(", unknown 0x%02x", header_iih_lan->circuit_type);
787 printf("\n\t\t lan-id: ");
788 isis_print_nodeid(header_iih_lan->lan_id);
789 printf(", Priority: %u",(header_iih_lan->priority) & PRIORITY_MASK);
791 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
792 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
796 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
797 printf(", bogus fixed header length %u should be %lu",
798 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE);
802 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
803 if (packet_len>pdu_len) {
804 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
808 printf(", PTP IIH (%u)",pdu_len);
809 TCHECK(*header_iih_ptp);
810 printf("\n\t\t source-id: ");
811 isis_print_sysid(header_iih_ptp->source_id);
812 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp->holding_time));
813 printf(", circuit-id: 0x%02x", header_iih_ptp->circuit_id);
814 switch(header_iih_ptp->circuit_type) {
817 printf(", Level 1 only");
821 printf(", Level 2 only");
825 printf(", Level 1, Level 2");
829 printf(", unknown 0x%02x", header_iih_ptp->circuit_type);
833 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
834 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
839 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
840 printf(", bogus fixed header length %u should be %lu",
841 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE);
845 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
846 if (packet_len>pdu_len) {
847 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
851 if (pdu_type == L1_LSP)
852 printf(", L1 LSP (%u)",pdu_len);
853 else if (pdu_type == L2_LSP)
854 printf(", L2 LSP (%u)",pdu_len);
857 printf("\n\t\t lsp-id: ");
858 isis_print_lspid(header_lsp->lsp_id);
859 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number));
860 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime));
861 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum));
863 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
865 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
866 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
867 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
868 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
869 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
870 printf("ATT bit set, ");
872 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
873 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
875 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
876 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
881 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
882 printf(", bogus fixed header length %u should be %lu",
883 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE);
887 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
888 if (packet_len>pdu_len) {
889 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
893 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len);
894 TCHECK(*header_csnp);
895 printf("\n\t\t source-id: ");
896 isis_print_nodeid(header_csnp->source_id);
897 printf("\n\t\t start lsp-id: ");
898 isis_print_lspid(header_csnp->start_lsp_id);
899 printf("\n\t\t end lsp-id: ");
900 isis_print_lspid(header_csnp->end_lsp_id);
902 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
903 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
908 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
909 printf("- bogus fixed header length %u should be %lu",
910 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE);
914 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
915 if (packet_len>pdu_len) {
916 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
920 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len);
921 TCHECK(*header_psnp);
922 printf("\n\t\t source-id: ");
923 isis_print_nodeid(header_psnp->source_id);
925 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
926 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
930 printf(", PDU type (0x%02x) not supported", pdu_type);
935 * Now print the TLV's.
938 while (packet_len >= 2) {
939 if (pptr == snapend) {
943 if (!TTEST2(*pptr, 2)) {
944 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
945 (long)(pptr-snapend));
951 if (len > packet_len) {
958 printf("Area address(es) (%u)",len);
961 if (!TTEST2(*tptr, 1))
964 while (tmp && alen < tmp) {
965 printf("\n\t\t\tArea address (%u): ",alen);
966 if (!print_nsap(tptr, alen))
970 if (tmp==0) /* if this is the last area address do not attemt a boundary check */
972 if (!TTEST2(*tptr, 1))
978 printf("IS Neighbor(s) (%u)",len);
981 while (tmp >= ETHER_ADDR_LEN) {
982 printf("\n\t\t\tIS Neighbor: ");
983 if (!isis_print_sysid(tptr))
985 tmp -= ETHER_ADDR_LEN;
986 tptr += ETHER_ADDR_LEN;
991 printf("Padding (%u)", len);
994 case TLV_MT_IS_REACH:
995 printf("Multi Topology IS Reachability (%u)",len);
1000 if (!TTEST2(*tptr, 2))
1002 switch(EXTRACT_16BITS(tptr)&0x0fff) {
1005 printf("IPv4 unicast");
1009 printf("In-Band Management");
1013 printf("IPv6 unicast");
1017 printf("Multicast");
1021 printf("Development, Experimental or Proprietary");
1025 printf("Reserved for IETF Consensus");
1028 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff);
1030 printf("\n\t\t\t IS Neighbor: ");
1031 if (!isis_print_nodeid(tptr))
1033 tptr+=(SYSTEM_ID_LEN+1);
1034 if (!TTEST2(*tptr, 3))
1036 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1038 if (!TTEST2(*tptr, 1))
1041 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1048 case TLV_EXT_IS_REACH:
1049 printf("Extended IS Reachability (%u)",len);
1053 printf("\n\t\t\tIS Neighbor: ");
1054 if (!isis_print_nodeid(tptr))
1056 tptr+=(SYSTEM_ID_LEN+1);
1057 if (!TTEST2(*tptr, 3))
1059 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1061 if (!TTEST2(*tptr, 1))
1064 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1066 printf(" (%u)",tslen);
1069 if (!TTEST2(*tptr,2))
1071 printf("\n\t\t\t ");
1075 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
1076 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr));
1078 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
1079 if (!TTEST2(*tptr,4))
1081 j = EXTRACT_32BITS(tptr);
1082 memcpy (&bw, &j, 4);
1083 printf("Maximum link bandwidth : %.3f Mbps",
1086 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW :
1087 if (!TTEST2(*tptr,4))
1089 j = EXTRACT_32BITS(tptr);
1090 memcpy (&bw, &j, 4);
1091 printf("Reservable link bandwidth: %.3f Mbps",
1094 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
1095 printf("Unreserved bandwidth:");
1096 for (i = 0; i < 8; i++) {
1097 if (!TTEST2(*tptr,4))
1099 j = EXTRACT_32BITS(tptr);
1100 memcpy (&bw, &j, 4);
1101 printf("\n\t\t\t priority level %d: %.3f Mbps",
1107 case SUBTLV_EXT_IS_REACH_TE_METRIC:
1108 if (!TTEST2(*tptr,3))
1110 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr));
1112 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
1113 if (!TTEST2(*tptr,4))
1115 printf("IPv4 interface address: %s", ipaddr_string(tptr));
1117 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
1118 if (!TTEST2(*tptr,4))
1120 printf("IPv4 neighbor address: %s", ipaddr_string(tptr));
1127 printf("Reserved for cisco specific extensions, type %d, length %d", subt, subl);
1130 printf("Reserved for future expansion, type %d, length %d", subt, subl);
1133 printf("unknown subTLV, type %d, length %d", subt, subl);
1144 printf("IS Reachability (%u)",len);
1148 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
1153 printf("\n\t\t\tIsNotVirtual");
1156 printf("\n\t\t\tIsVirtual");
1159 printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr));
1165 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
1168 while (tmp >= sizeof(struct isis_tlv_is_reach)) {
1169 if (!TTEST(*tlv_is_reach))
1172 printf("\n\t\t\tIS Neighbor: ");
1173 isis_print_nodeid(tlv_is_reach->neighbor_nodeid);
1175 printf(", Default Metric: %d, %s",
1176 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_default),
1177 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_default) ? "External" : "Internal");
1179 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_delay))
1180 printf("\n\t\t\t Delay Metric: %d, %s",
1181 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_delay),
1182 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_delay) ? "External" : "Internal");
1184 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_expense))
1185 printf("\n\t\t\t Expense Metric: %d, %s",
1186 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_expense),
1187 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_expense) ? "External" : "Internal");
1189 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_error))
1190 printf("\n\t\t\t Error Metric: %d, %s",
1191 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_error),
1192 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_error) ? "External" : "Internal");
1194 tmp -= sizeof(struct isis_tlv_is_reach);
1200 printf("IP Internal reachability (%u)",len);
1201 if (!isis_print_tlv_ip_reach(pptr, len))
1205 case TLV_IP_REACH_EXT:
1206 printf("IP External reachability (%u)",len);
1207 if (!isis_print_tlv_ip_reach(pptr, len))
1211 case TLV_EXT_IP_REACH:
1212 printf("Extended IP reachability (%u)",len);
1217 memset (prefix, 0, 4);
1218 if (!TTEST2(*tptr, 4))
1220 metric = EXTRACT_32BITS(tptr);
1223 if (!TTEST2(*tptr, 1))
1226 bit_length = (*(tptr)++&0x3f);
1227 byte_length = (bit_length + 7) / 8;
1228 if (!TTEST2(*tptr, byte_length))
1231 memcpy(prefix,tptr,byte_length);
1233 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d",
1240 printf("\n\t\t\t Metric: %u, Distribution: %s",
1242 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up");
1244 printf(", %ssub-TLVs present",
1245 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
1247 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
1248 if (!TTEST2(*tptr, 1))
1250 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */
1263 printf("IP6 reachability (%u)",len);
1268 if (!TTEST2(*tptr, 4))
1270 metric = EXTRACT_32BITS(tptr);
1273 if (!TTEST2(*tptr, 2))
1276 bit_length = (*(tptr)++);
1277 byte_length = (bit_length + 7) / 8;
1278 if (!TTEST2(*tptr, byte_length))
1281 memset(prefix6, 0, 16);
1282 memcpy(prefix6,tptr,byte_length);
1284 printf("\n\t\t\tIPv6 prefix: %s/%u",
1285 ip6addr_string(prefix6),
1288 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1290 ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal",
1291 ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up",
1292 ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no ");
1294 if (ISIS_MASK_TLV_IP6_SUBTLV(j)) {
1295 if (!TTEST2(*tptr, 1))
1297 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */
1311 printf("IPv6 Interface address(es) (%u)",len);
1315 if (!TTEST2(*tptr, 16))
1318 printf("\n\t\t\tIPv6 interface address: %s",
1319 ip6addr_string(tptr));
1327 if (!TTEST2(*pptr, 1))
1329 printf("Authentication (%u)",len);
1330 if (*pptr==SUBTLV_AUTH_SIMPLE) {
1331 printf("\n\t\t\tsimple text password: ");
1332 for(i=1;i<len;i++) {
1333 if (!TTEST2(*(pptr+i), 1))
1335 printf("%c",*(pptr+i));
1338 if (!TTEST2(*pptr, 1))
1340 if (*pptr==SUBTLV_AUTH_MD5) {
1341 printf("\n\t\t\tMD5 password: ");
1342 for(i=1;i<len;i++) {
1343 if (!TTEST2(*(pptr+i), 1))
1345 printf("%02x",*(pptr+i));
1351 printf("Point-to-point Adjacency State (%u)",len);
1352 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)pptr;
1355 if (!TTEST2(*pptr, 1))
1357 printf("\n\t\t\tAdjacency State: %s",
1358 tok2str(isis_ptp_adjancey_values, "#0x%x", *pptr));
1362 if (!TTEST2(tlv_ptp_adj->ext_local_circuit_id, 4))
1364 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1365 EXTRACT_32BITS(tlv_ptp_adj->ext_local_circuit_id));
1369 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, 6))
1371 printf("\n\t\t\tNeighbor SystemID: ");
1372 isis_print_sysid(tlv_ptp_adj->neighbor_sysid);
1376 if (!TTEST2(tlv_ptp_adj->neighbor_ext_local_circuit_id, 4))
1378 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1379 EXTRACT_32BITS(tlv_ptp_adj->neighbor_ext_local_circuit_id));
1384 printf("Protocols supported (%u)", len);
1385 printf("\n\t\t\tNLPID(s): ");
1386 for (i = 0; i < len; i++) {
1387 if (!TTEST2(*(pptr+i), 1))
1389 printf("%s (0x%02x)",tok2str(isis_nlpid_values, "Unknown", *(pptr+i)),*(pptr+i));
1395 case TLV_TE_ROUTER_ID:
1396 printf("Traffic Engineering Router ID (%u)",len);
1397 if (!TTEST2(*pptr, 4))
1399 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr));
1403 printf("IPv4 Interface address(es) (%u)",len);
1407 if (!TTEST2(*tptr, 4))
1409 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1416 printf("Hostname (%u)", len);
1417 printf("\n\t\t\tHostname: ");
1418 for(i = 0; i < len; i++) {
1419 if (!TTEST2(*(pptr+i), 1))
1421 printf("%c",*(pptr+i));
1426 tlv_lsp = (const struct isis_tlv_lsp *)pptr;
1427 printf("LSP entries (%u)", len);
1430 printf("\n\t\t\tlsp-id: ");
1431 if (!isis_print_nodeid(tlv_lsp->lsp_id))
1433 if (!TTEST((tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]))
1435 printf("-%02x",(tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]);
1436 if (!TTEST2(tlv_lsp->sequence_number, 4))
1438 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number));
1439 if (!TTEST2(tlv_lsp->remaining_lifetime, 2))
1441 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime));
1442 if (!TTEST2(tlv_lsp->checksum, 2))
1444 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum));
1445 i+=sizeof(struct isis_tlv_lsp);
1451 if (!TTEST2(*pptr, 2))
1453 printf("Checksum (%u)", len);
1454 printf("\n\t\t\tchecksum: 0x%04x",
1455 EXTRACT_16BITS(pptr));
1457 if (osi_cksum(optr, length, off))
1458 printf(" (incorrect)");
1460 printf(" (correct)");
1463 case TLV_MT_SUPPORTED:
1464 printf("Multi Topology (%u)",len);
1468 /* length can only be a multiple of 2, otherwise there is
1469 something broken -> so decode down until length is 1 */
1471 if (!TTEST2(*tptr, 2))
1474 switch(EXTRACT_16BITS(tptr)&0x0fff) {
1477 printf("IPv4 unicast");
1481 printf("In-Band Management");
1485 printf("IPv6 unicast");
1489 printf("Multicast");
1493 printf("Development, Experimental or Proprietary");
1497 printf("Reserved for IETF Consensus");
1500 printf(" Topology (0x%03x)%s%s",
1501 EXTRACT_16BITS(tptr)&0xfff,
1502 (EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs present",
1503 (EXTRACT_16BITS(tptr)&0x4000) ? ", ATT bit set" : "" );
1505 printf("\n\t\t\tmalformed MT-ID");
1513 case TLV_RESTART_SIGNALING:
1515 printf("Restart Signaling (%u)",len);
1516 if (!TTEST2(*tptr, 3))
1519 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1520 ISIS_MASK_RESTART_RR(*tptr) ? "set" : "clear",
1521 ISIS_MASK_RESTART_RA(*tptr++) ? "set" : "clear",
1522 EXTRACT_16BITS(tptr));
1527 printf("unknown TLV, type %d, length %d\n\t\t\t", type, len);
1530 for(i=0;i<len;i++) {
1531 if (!TTEST2(*(tptr+i), 1))
1533 printf("%02x",*(tptr+i)); /* formatted hex output of unknown TLV data */
1536 if (i/16!=(i+1)/16) {
1548 if (packet_len != 0) {
1549 printf("\n\t\t\t %d straggler bytes", packet_len);
1554 fputs("[|isis]", stdout);
1558 printf("\n\t\t\t packet exceeded snapshot");
1563 * Verify the checksum. See 8473-1, Appendix C, section C.4.
1567 osi_cksum(register const u_char *p, register u_int len, u_char *off)
1569 int32_t c0 = 0, c1 = 0;
1571 if ((off[0] == 0) && (off[1] == 0))
1574 off[0] = off[1] = 0;
1575 while ((int)--len >= 0) {