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.2.2 2002/06/29 04:28:44 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)
579 u_int bitmasks[33] = {
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
592 const struct isis_tlv_ip_reach *tlv_ip_reach;
594 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
597 if (length < sizeof(*tlv_ip_reach)) {
598 printf("short IP reachability (%d vs %lu)", length,
599 (unsigned long)sizeof(*tlv_ip_reach));
603 if (!TTEST(*tlv_ip_reach))
606 mask = EXTRACT_32BITS(tlv_ip_reach->mask);
609 while (prefix_len <= 33) {
610 if (bitmasks[prefix_len++] == mask) {
617 * 34 indicates no match -> must be a discontiguous netmask
618 * lets dump the mask, otherwise print the prefix_len
620 if (prefix_len == 34)
621 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u",
622 (tlv_ip_reach->prefix)[0],
623 (tlv_ip_reach->prefix)[1],
624 (tlv_ip_reach->prefix)[2],
625 (tlv_ip_reach->prefix)[3],
626 (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1],
627 (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]);
629 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u",
630 (tlv_ip_reach->prefix)[0],
631 (tlv_ip_reach->prefix)[1],
632 (tlv_ip_reach->prefix)[2],
633 (tlv_ip_reach->prefix)[3], prefix_len);
635 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
636 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default),
637 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_default) ? "External" : "Internal",
638 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->metric_default) ? "down" : "up");
640 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_delay))
641 printf("\n\t\t\t Delay Metric: %02d, %s",
642 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_delay),
643 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_delay) ? "External" : "Internal");
645 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_expense))
646 printf("\n\t\t\t Expense Metric: %02d, %s",
647 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_expense),
648 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_expense) ? "External" : "Internal");
650 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_error))
651 printf("\n\t\t\t Error Metric: %02d, %s",
652 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_error),
653 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_error) ? "External" : "Internal");
655 length -= sizeof(struct isis_tlv_ip_reach);
663 * Decode IS-IS packets. Return 0 on error.
666 static int isis_print (const u_char *p, u_int length)
668 const struct isis_common_header *header;
670 const struct isis_iih_lan_header *header_iih_lan;
671 const struct isis_iih_ptp_header *header_iih_ptp;
672 const struct isis_lsp_header *header_lsp;
673 const struct isis_csnp_header *header_csnp;
674 const struct isis_psnp_header *header_psnp;
676 const struct isis_tlv_lsp *tlv_lsp;
677 const struct isis_tlv_ptp_adj *tlv_ptp_adj;
678 const struct isis_tlv_is_reach *tlv_is_reach;
680 u_char pdu_type, max_area, type, len, tmp, alen, subl, subt, tslen, ttslen;
681 const u_char *optr, *pptr, *tptr;
683 u_short packet_len,pdu_len;
684 u_int i,j,bit_length,byte_length,metric;
685 u_char prefix[4]; /* copy buffer for ipv4 prefixes */
687 u_char prefix6[16]; /* copy buffer for ipv6 prefixes */
690 float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV */
693 optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */
694 header = (const struct isis_common_header *)p;
696 pptr = p+(ISIS_COMMON_HEADER_SIZE);
697 header_iih_lan = (const struct isis_iih_lan_header *)pptr;
698 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
699 header_lsp = (const struct isis_lsp_header *)pptr;
700 header_csnp = (const struct isis_csnp_header *)pptr;
701 header_psnp = (const struct isis_psnp_header *)pptr;
704 * Sanity checking of the header.
706 if (header->nlpid != NLPID_ISIS) {
707 printf(", coding error!");
711 if (header->version != ISIS_VERSION) {
712 printf(", version %d packet not supported", header->version);
716 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
717 printf(", system ID length of %d is not supported",
722 if (header->pkt_version != ISIS_VERSION) {
723 printf(", version %d packet not supported", header->pkt_version);
727 max_area = header->max_area;
730 max_area = 3; /* silly shit */
733 printf(", bad packet -- 255 areas");
739 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)",
745 pdu_type=header->pdu_type;
751 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
752 printf(", bogus fixed header length %u should be %lu",
753 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE);
757 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
758 if (packet_len>pdu_len) {
759 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
763 printf(", L%s Lan IIH (%u)",
764 ISIS_MASK_LEVEL_BITS(pdu_type) ? "1" : "2",
767 TCHECK(*header_iih_lan);
768 printf("\n\t\t source-id: ");
769 isis_print_sysid(header_iih_lan->source_id);
770 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan->holding_time));
771 switch(header_iih_lan->circuit_type) {
774 printf(", Level 1 only");
778 printf(", Level 2 only");
782 printf(", Level 1, Level 2");
786 printf(", unknown 0x%02x", header_iih_lan->circuit_type);
789 printf("\n\t\t lan-id: ");
790 isis_print_nodeid(header_iih_lan->lan_id);
791 printf(", Priority: %u",(header_iih_lan->priority) & PRIORITY_MASK);
793 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
794 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
798 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
799 printf(", bogus fixed header length %u should be %lu",
800 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE);
804 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
805 if (packet_len>pdu_len) {
806 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
810 printf(", PTP IIH (%u)",pdu_len);
811 TCHECK(*header_iih_ptp);
812 printf("\n\t\t source-id: ");
813 isis_print_sysid(header_iih_ptp->source_id);
814 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp->holding_time));
815 printf(", circuit-id: 0x%02x", header_iih_ptp->circuit_id);
816 switch(header_iih_ptp->circuit_type) {
819 printf(", Level 1 only");
823 printf(", Level 2 only");
827 printf(", Level 1, Level 2");
831 printf(", unknown 0x%02x", header_iih_ptp->circuit_type);
835 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
836 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
841 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
842 printf(", bogus fixed header length %u should be %lu",
843 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE);
847 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
848 if (packet_len>pdu_len) {
849 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
853 if (pdu_type == L1_LSP)
854 printf(", L1 LSP (%u)",pdu_len);
855 else if (pdu_type == L2_LSP)
856 printf(", L2 LSP (%u)",pdu_len);
859 printf("\n\t\t lsp-id: ");
860 isis_print_lspid(header_lsp->lsp_id);
861 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number));
862 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime));
863 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum));
865 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
867 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
868 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
869 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
870 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
871 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
872 printf("ATT bit set, ");
874 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
875 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
877 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
878 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
883 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
884 printf(", bogus fixed header length %u should be %lu",
885 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE);
889 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
890 if (packet_len>pdu_len) {
891 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
895 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len);
896 TCHECK(*header_csnp);
897 printf("\n\t\t source-id: ");
898 isis_print_nodeid(header_csnp->source_id);
899 printf("\n\t\t start lsp-id: ");
900 isis_print_lspid(header_csnp->start_lsp_id);
901 printf("\n\t\t end lsp-id: ");
902 isis_print_lspid(header_csnp->end_lsp_id);
904 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
905 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
910 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
911 printf("- bogus fixed header length %u should be %lu",
912 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE);
916 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
917 if (packet_len>pdu_len) {
918 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
922 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len);
923 TCHECK(*header_psnp);
924 printf("\n\t\t source-id: ");
925 isis_print_nodeid(header_psnp->source_id);
927 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
928 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
932 printf(", PDU type (0x%02x) not supported", pdu_type);
937 * Now print the TLV's.
940 while (packet_len >= 2) {
941 if (pptr == snapend) {
945 if (!TTEST2(*pptr, 2)) {
946 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
947 (long)(pptr-snapend));
953 if (len > packet_len) {
960 printf("Area address(es) (%u)",len);
963 if (!TTEST2(*tptr, 1))
966 while (tmp && alen < tmp) {
967 printf("\n\t\t\tArea address (%u): ",alen);
968 if (!print_nsap(tptr, alen))
972 if (tmp==0) /* if this is the last area address do not attemt a boundary check */
974 if (!TTEST2(*tptr, 1))
980 printf("IS Neighbor(s) (%u)",len);
983 while (tmp >= ETHER_ADDR_LEN) {
984 printf("\n\t\t\tIS Neighbor: ");
985 if (!isis_print_sysid(tptr))
987 tmp -= ETHER_ADDR_LEN;
988 tptr += ETHER_ADDR_LEN;
993 printf("Padding (%u)", len);
996 case TLV_MT_IS_REACH:
997 printf("Multi Topology IS Reachability (%u)",len);
1002 if (!TTEST2(*tptr, 2))
1004 switch(EXTRACT_16BITS(tptr)&0x0fff) {
1007 printf("IPv4 unicast");
1011 printf("In-Band Management");
1015 printf("IPv6 unicast");
1019 printf("Multicast");
1023 printf("Development, Experimental or Proprietary");
1027 printf("Reserved for IETF Consensus");
1030 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff);
1032 printf("\n\t\t\t IS Neighbor: ");
1033 if (!isis_print_nodeid(tptr))
1035 tptr+=(SYSTEM_ID_LEN+1);
1036 if (!TTEST2(*tptr, 3))
1038 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1040 if (!TTEST2(*tptr, 1))
1043 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1050 case TLV_EXT_IS_REACH:
1051 printf("Extended IS Reachability (%u)",len);
1055 printf("\n\t\t\tIS Neighbor: ");
1056 if (!isis_print_nodeid(tptr))
1058 tptr+=(SYSTEM_ID_LEN+1);
1059 if (!TTEST2(*tptr, 3))
1061 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1063 if (!TTEST2(*tptr, 1))
1066 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1068 printf(" (%u)",tslen);
1071 if (!TTEST2(*tptr,2))
1073 printf("\n\t\t\t ");
1077 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
1078 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr));
1080 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
1081 if (!TTEST2(*tptr,4))
1083 j = EXTRACT_32BITS(tptr);
1084 memcpy (&bw, &j, 4);
1085 printf("Maximum link bandwidth : %.3f Mbps",
1088 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW :
1089 if (!TTEST2(*tptr,4))
1091 j = EXTRACT_32BITS(tptr);
1092 memcpy (&bw, &j, 4);
1093 printf("Reservable link bandwidth: %.3f Mbps",
1096 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
1097 printf("Unreserved bandwidth:");
1098 for (i = 0; i < 8; i++) {
1099 if (!TTEST2(*tptr,4))
1101 j = EXTRACT_32BITS(tptr);
1102 memcpy (&bw, &j, 4);
1103 printf("\n\t\t\t priority level %d: %.3f Mbps",
1109 case SUBTLV_EXT_IS_REACH_TE_METRIC:
1110 if (!TTEST2(*tptr,3))
1112 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr));
1114 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
1115 if (!TTEST2(*tptr,4))
1117 printf("IPv4 interface address: %s", ipaddr_string(tptr));
1119 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
1120 if (!TTEST2(*tptr,4))
1122 printf("IPv4 neighbor address: %s", ipaddr_string(tptr));
1129 printf("Reserved for cisco specific extensions, type %d, length %d", subt, subl);
1132 printf("Reserved for future expansion, type %d, length %d", subt, subl);
1135 printf("unknown subTLV, type %d, length %d", subt, subl);
1146 printf("IS Reachability (%u)",len);
1150 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
1155 printf("\n\t\t\tIsNotVirtual");
1158 printf("\n\t\t\tIsVirtual");
1161 printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr));
1167 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
1170 while (tmp >= sizeof(struct isis_tlv_is_reach)) {
1171 if (!TTEST(*tlv_is_reach))
1174 printf("\n\t\t\tIS Neighbor: ");
1175 isis_print_nodeid(tlv_is_reach->neighbor_nodeid);
1177 printf(", Default Metric: %d, %s",
1178 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_default),
1179 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_default) ? "External" : "Internal");
1181 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_delay))
1182 printf("\n\t\t\t Delay Metric: %d, %s",
1183 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_delay),
1184 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_delay) ? "External" : "Internal");
1186 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_expense))
1187 printf("\n\t\t\t Expense Metric: %d, %s",
1188 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_expense),
1189 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_expense) ? "External" : "Internal");
1191 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_error))
1192 printf("\n\t\t\t Error Metric: %d, %s",
1193 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_error),
1194 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_error) ? "External" : "Internal");
1196 tmp -= sizeof(struct isis_tlv_is_reach);
1202 printf("IP Internal reachability (%u)",len);
1203 if (!isis_print_tlv_ip_reach(pptr, len))
1207 case TLV_IP_REACH_EXT:
1208 printf("IP External reachability (%u)",len);
1209 if (!isis_print_tlv_ip_reach(pptr, len))
1213 case TLV_EXT_IP_REACH:
1214 printf("Extended IP reachability (%u)",len);
1219 memset (prefix, 0, 4);
1220 if (!TTEST2(*tptr, 4))
1222 metric = EXTRACT_32BITS(tptr);
1225 if (!TTEST2(*tptr, 1))
1228 bit_length = (*(tptr)++&0x3f);
1229 byte_length = (bit_length + 7) / 8;
1230 if (!TTEST2(*tptr, byte_length))
1233 memcpy(prefix,tptr,byte_length);
1235 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d",
1242 printf("\n\t\t\t Metric: %u, Distribution: %s",
1244 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up");
1246 printf(", %ssub-TLVs present",
1247 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
1249 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
1250 if (!TTEST2(*tptr, 1))
1253 printf(" (%u)",subtlv_len); /* no subTLV decoder supported - just print out subTLV length */
1255 tptr += subtlv_len + 1;
1266 printf("IP6 reachability (%u)",len);
1271 if (!TTEST2(*tptr, 4))
1273 metric = EXTRACT_32BITS(tptr);
1276 if (!TTEST2(*tptr, 2))
1279 bit_length = (*(tptr)++);
1280 byte_length = (bit_length + 7) / 8;
1281 if (!TTEST2(*tptr, byte_length))
1284 memset(prefix6, 0, 16);
1285 memcpy(prefix6,tptr,byte_length);
1287 printf("\n\t\t\tIPv6 prefix: %s/%u",
1288 ip6addr_string(prefix6),
1291 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1293 ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal",
1294 ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up",
1295 ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no ");
1297 if (ISIS_MASK_TLV_IP6_SUBTLV(j)) {
1298 if (!TTEST2(*tptr, 1))
1300 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */
1314 printf("IPv6 Interface address(es) (%u)",len);
1318 if (!TTEST2(*tptr, 16))
1321 printf("\n\t\t\tIPv6 interface address: %s",
1322 ip6addr_string(tptr));
1330 if (!TTEST2(*pptr, 1))
1332 printf("Authentication (%u)",len);
1333 if (*pptr==SUBTLV_AUTH_SIMPLE) {
1334 printf("\n\t\t\tsimple text password: ");
1335 for(i=1;i<len;i++) {
1336 if (!TTEST2(*(pptr+i), 1))
1338 printf("%c",*(pptr+i));
1341 if (!TTEST2(*pptr, 1))
1343 if (*pptr==SUBTLV_AUTH_MD5) {
1344 printf("\n\t\t\tMD5 password: ");
1345 for(i=1;i<len;i++) {
1346 if (!TTEST2(*(pptr+i), 1))
1348 printf("%02x",*(pptr+i));
1354 printf("Point-to-point Adjacency State (%u)",len);
1355 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)pptr;
1358 if (!TTEST2(*pptr, 1))
1360 printf("\n\t\t\tAdjacency State: %s",
1361 tok2str(isis_ptp_adjancey_values, "#0x%x", *pptr));
1365 if (!TTEST2(tlv_ptp_adj->ext_local_circuit_id, 4))
1367 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1368 EXTRACT_32BITS(tlv_ptp_adj->ext_local_circuit_id));
1372 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, 6))
1374 printf("\n\t\t\tNeighbor SystemID: ");
1375 isis_print_sysid(tlv_ptp_adj->neighbor_sysid);
1379 if (!TTEST2(tlv_ptp_adj->neighbor_ext_local_circuit_id, 4))
1381 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1382 EXTRACT_32BITS(tlv_ptp_adj->neighbor_ext_local_circuit_id));
1387 printf("Protocols supported (%u)", len);
1388 printf("\n\t\t\tNLPID(s): ");
1389 for (i = 0; i < len; i++) {
1390 if (!TTEST2(*(pptr+i), 1))
1392 printf("%s (0x%02x)",tok2str(isis_nlpid_values, "Unknown", *(pptr+i)),*(pptr+i));
1398 case TLV_TE_ROUTER_ID:
1399 printf("Traffic Engineering Router ID (%u)",len);
1400 if (!TTEST2(*pptr, 4))
1402 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr));
1406 printf("IPv4 Interface address(es) (%u)",len);
1410 if (!TTEST2(*tptr, 4))
1412 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1419 printf("Hostname (%u)", len);
1420 printf("\n\t\t\tHostname: ");
1421 for(i = 0; i < len; i++) {
1422 if (!TTEST2(*(pptr+i), 1))
1424 printf("%c",*(pptr+i));
1429 tlv_lsp = (const struct isis_tlv_lsp *)pptr;
1430 printf("LSP entries (%u)", len);
1433 printf("\n\t\t\tlsp-id: ");
1434 if (!isis_print_nodeid(tlv_lsp->lsp_id))
1436 if (!TTEST((tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]))
1438 printf("-%02x",(tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]);
1439 if (!TTEST2(tlv_lsp->sequence_number, 4))
1441 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number));
1442 if (!TTEST2(tlv_lsp->remaining_lifetime, 2))
1444 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime));
1445 if (!TTEST2(tlv_lsp->checksum, 2))
1447 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum));
1448 i+=sizeof(struct isis_tlv_lsp);
1454 if (!TTEST2(*pptr, 2))
1456 printf("Checksum (%u)", len);
1457 printf("\n\t\t\tchecksum: 0x%04x",
1458 EXTRACT_16BITS(pptr));
1460 if (osi_cksum(optr, length, off))
1461 printf(" (incorrect)");
1463 printf(" (correct)");
1466 case TLV_MT_SUPPORTED:
1467 printf("Multi Topology (%u)",len);
1471 /* length can only be a multiple of 2, otherwise there is
1472 something broken -> so decode down until length is 1 */
1474 if (!TTEST2(*tptr, 2))
1477 switch(EXTRACT_16BITS(tptr)&0x0fff) {
1480 printf("IPv4 unicast");
1484 printf("In-Band Management");
1488 printf("IPv6 unicast");
1492 printf("Multicast");
1496 printf("Development, Experimental or Proprietary");
1500 printf("Reserved for IETF Consensus");
1503 printf(" Topology (0x%03x)%s%s",
1504 EXTRACT_16BITS(tptr)&0xfff,
1505 (EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs present",
1506 (EXTRACT_16BITS(tptr)&0x4000) ? ", ATT bit set" : "" );
1508 printf("\n\t\t\tmalformed MT-ID");
1516 case TLV_RESTART_SIGNALING:
1518 printf("Restart Signaling (%u)",len);
1519 if (!TTEST2(*tptr, 3))
1522 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1523 ISIS_MASK_RESTART_RR(*tptr) ? "set" : "clear",
1524 ISIS_MASK_RESTART_RA(*tptr) ? "set" : "clear",
1525 EXTRACT_16BITS(tptr+1));
1531 printf("unknown TLV, type %d, length %d\n\t\t\t", type, len);
1534 for(i=0;i<len;i++) {
1535 if (!TTEST2(*(tptr+i), 1))
1537 printf("%02x",*(tptr+i)); /* formatted hex output of unknown TLV data */
1540 if (i/16!=(i+1)/16) {
1552 if (packet_len != 0) {
1553 printf("\n\t\t\t %d straggler bytes", packet_len);
1558 fputs("[|isis]", stdout);
1562 printf("\n\t\t\t packet exceeded snapshot");
1567 * Verify the checksum. See 8473-1, Appendix C, section C.4.
1571 osi_cksum(register const u_char *p, register u_int len, u_char *off)
1573 int32_t c0 = 0, c1 = 0;
1575 if ((off[0] == 0) && (off[1] == 0))
1578 off[0] = off[1] = 0;
1579 while ((int)--len >= 0) {