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.
28 static const char rcsid
[] =
29 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.35 2001-12-18 09:00:14 guy Exp $ (LBL)";
36 #include <sys/types.h>
38 #include <sys/socket.h>
40 #include <netinet/in.h>
45 #include "interface.h"
46 #include "addrtoname.h"
47 #include "ethertype.h"
51 #define NLPID_CLNS 129 /* 0x81 */
52 #define NLPID_ESIS 130 /* 0x82 */
53 #define NLPID_ISIS 131 /* 0x83 */
54 #define NLPID_IP6 0x8e
56 #define NLPID_NULLNS 0
59 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
62 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
63 #define ISIS_VERSION 1
64 #define PDU_TYPE_MASK 0x1F
65 #define PRIORITY_MASK 0x7F
79 * A TLV is a tuple of a type, length and a value and is normally used for
80 * encoding information in all sorts of places. This is an enumeration of
81 * the well known types.
84 #define TLV_AREA_ADDR 1
85 #define TLV_IS_REACH 2
86 #define TLV_ES_REACH 3
92 #define TLV_CHECKSUM 12
93 #define TLV_EXT_IS_REACH 22
94 #define TLV_IP_REACH 128
95 #define TLV_PROTOCOLS 129
96 #define TLV_IP_REACH_EXT 130
97 #define TLV_IDRP_INFO 131
98 #define TLV_IPADDR 132
99 #define TLV_IPAUTH 133
100 #define TLV_TE_ROUTER_ID 134
101 #define TLV_EXT_IP_REACH 135
102 #define TLV_HOSTNAME 137
103 #define TLV_RESTART_SIGNALING 211
104 #define TLV_MT_IS_REACH 222
105 #define TLV_MT_SUPPORTED 229
106 #define TLV_IP6ADDR 232
107 #define TLV_MT_REACH 235
108 #define TLV_IP6_REACH 236
109 #define TLV_PTP_ADJ 240
111 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
112 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
113 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
114 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
115 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
116 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
117 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
119 #define SUBTLV_AUTH_SIMPLE 1
120 #define SUBTLV_AUTH_MD5 54
122 #define ISIS_MASK_LEVEL_BITS(x) ((x)&0x1)
124 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
125 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
126 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
127 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
128 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
129 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
130 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
131 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
133 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
134 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
136 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
137 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
138 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
140 #define ISIS_MASK_RESTART_RR(x) ((x)&0x1)
141 #define ISIS_MASK_RESTART_RA(x) ((x)&0x2)
143 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
144 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
145 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
146 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
148 #define ISIS_LSP_TYPE_UNUSED0 0
149 #define ISIS_LSP_TYPE_LEVEL_1 1
150 #define ISIS_LSP_TYPE_UNUSED2 2
151 #define ISIS_LSP_TYPE_LEVEL_2 3
153 static struct tok isis_lsp_istype_values
[] = {
154 { ISIS_LSP_TYPE_UNUSED0
, "Unused 0x0 (invalid)"},
155 { ISIS_LSP_TYPE_LEVEL_1
, "L1 IS"},
156 { ISIS_LSP_TYPE_UNUSED2
, "Unused 0x2 (invalid)"},
157 { ISIS_LSP_TYPE_LEVEL_2
, "L1L2 IS"},
161 static struct tok isis_nlpid_values
[] = {
162 { NLPID_CLNS
, "CLNS"},
164 { NLPID_IP6
, "IPv6"},
169 * Katz's point to point adjacency TLV uses codes to tell us the state of
170 * the remote adjacency. Enumerate them.
173 #define ISIS_PTP_ADJ_UP 0
174 #define ISIS_PTP_ADJ_INIT 1
175 #define ISIS_PTP_ADJ_DOWN 2
177 static int osi_cksum(const u_char
*, u_int
, u_char
*);
178 static void esis_print(const u_char
*, u_int
);
179 static int isis_print(const u_char
*, u_int
);
182 static struct tok isis_ptp_adjancey_values
[] = {
183 { ISIS_PTP_ADJ_UP
, "Up" },
184 { ISIS_PTP_ADJ_INIT
, "Initializing" },
185 { ISIS_PTP_ADJ_DOWN
, "Down" }
188 struct isis_tlv_ptp_adj
{
189 u_char adjacency_state
;
190 u_char ext_local_circuit_id
[4];
191 u_char neighbor_sysid
[SYSTEM_ID_LEN
];
192 u_char neighbor_ext_local_circuit_id
[4];
195 struct isis_tlv_ip_reach
{
196 u_char metric_default
;
198 u_char metric_expense
;
204 struct isis_tlv_is_reach
{
206 u_char metric_default
;
208 u_char metric_expense
;
210 u_char neighbor_nodeid
[SYSTEM_ID_LEN
+1];
214 struct isis_common_header
{
217 u_char version
; /* Protocol version? */
219 u_char pdu_type
; /* 3 MSbs are reserved */
220 u_char pkt_version
; /* Packet format version? */
225 struct isis_iih_lan_header
{
227 u_char source_id
[SYSTEM_ID_LEN
];
228 u_char holding_time
[2];
231 u_char lan_id
[SYSTEM_ID_LEN
+1];
234 struct isis_iih_ptp_header
{
236 u_char source_id
[SYSTEM_ID_LEN
];
237 u_char holding_time
[2];
242 struct isis_lsp_header
{
244 u_char remaining_lifetime
[2];
245 u_char lsp_id
[SYSTEM_ID_LEN
+2];
246 u_char sequence_number
[4];
251 struct isis_csnp_header
{
253 u_char source_id
[SYSTEM_ID_LEN
+1];
254 u_char start_lsp_id
[SYSTEM_ID_LEN
+2];
255 u_char end_lsp_id
[SYSTEM_ID_LEN
+2];
258 struct isis_psnp_header
{
260 u_char source_id
[SYSTEM_ID_LEN
+1];
263 struct isis_tlv_lsp
{
264 u_char remaining_lifetime
[2];
265 u_char lsp_id
[SYSTEM_ID_LEN
+2];
266 u_char sequence_number
[4];
270 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
271 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
272 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
273 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
274 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
275 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
277 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
278 const u_char
*esrc
, const u_char
*edst
)
281 const struct isis_common_header
*header
;
283 header
= (const struct isis_common_header
*)p
;
284 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
287 printf("[|iso-clns] ");
288 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
290 etheraddr_string(esrc
),
291 etheraddr_string(edst
));
298 (void)printf("CLNS(%d)", length
);
299 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
300 (void)printf(", %s > %s",
301 etheraddr_string(esrc
),
302 etheraddr_string(edst
));
306 (void)printf("ESIS");
307 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
308 (void)printf(", %s > %s",
309 etheraddr_string(esrc
),
310 etheraddr_string(edst
));
311 esis_print(p
, length
);
315 (void)printf("ISIS(%d)", length
);
316 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
317 (void)printf(", %s > %s",
318 etheraddr_string(esrc
),
319 etheraddr_string(edst
));
320 if (!isis_print(p
, length
))
321 default_print_unaligned(p
, caplen
);
325 (void)printf("ISO NULLNS(%d)", length
);
326 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
327 (void)printf(", %s > %s",
328 etheraddr_string(esrc
),
329 etheraddr_string(edst
));
333 (void)printf("CLNS %02x(%d)", p
[0], length
);
334 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
335 (void)printf(", %s > %s",
336 etheraddr_string(esrc
),
337 etheraddr_string(edst
));
339 default_print_unaligned(p
, caplen
);
344 #define ESIS_REDIRECT 6
357 esis_print(const u_char
*p
, u_int length
)
361 const struct esis_hdr
*eh
;
368 printf(" no header at all!");
372 eh
= (const struct esis_hdr
*) &p
[2];
378 printf(" LI(%d) > PDU size (%d)!", li
, length
);
381 if (li
< sizeof(struct esis_hdr
) + 2) {
385 printf(" too short for esis header %d:", li
);
386 while (--length
!= 0)
387 printf("%02X", *p
++);
391 switch (eh
->type
& 0x1f) {
406 printf(" type %d", eh
->type
& 0x1f);
409 off
[0] = eh
->cksum
[0];
410 off
[1] = eh
->cksum
[1];
411 if (vflag
&& osi_cksum(p
, li
, off
)) {
412 printf(" bad cksum (got %02x%02x)",
413 eh
->cksum
[1], eh
->cksum
[0]);
414 default_print(p
, length
);
417 if (eh
->version
!= 1) {
418 printf(" unsupported version %d", eh
->version
);
421 p
+= sizeof(*eh
) + 2;
422 li
-= sizeof(*eh
) + 2; /* protoid * li */
424 switch (eh
->type
& 0x1f) {
425 case ESIS_REDIRECT
: {
426 const u_char
*dst
, *snpa
, *is
;
428 dst
= p
; p
+= *p
+ 1;
431 printf("\n\t\t\t %s", isonsap_string(dst
));
432 snpa
= p
; p
+= *p
+ 1;
441 printf(" > %s", etheraddr_string(&snpa
[1]));
443 printf(" > %s", isonsap_string(is
));
463 printf("\n\t\t\t %s", isonsap_string(is
));
469 (void)printf(" len=%d", length
);
470 if (length
&& p
< snapend
) {
471 length
= snapend
- p
;
472 default_print(p
, length
);
477 while (p
< ep
&& li
) {
484 printf(" bad opts/li");
491 printf(" opt (%d) too long", op
);
499 if (op
== 198 && opli
== 2) {
500 printf(" tmo=%d", q
[0] * 256 + q
[1]);
503 printf (" %d:<", op
);
505 printf("%02x", *q
++);
515 print_nsap(register const u_char
*cp
, register int length
)
519 for (i
= 0; i
< length
; i
++) {
522 printf("%02x", *cp
++);
523 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
531 isis_print_sysid(const u_char
*cp
)
535 for (i
= 1; i
<= 6; i
++) {
538 printf("%02x", *cp
++);
547 isis_print_nodeid(const u_char
*cp
)
551 for (i
= 1; i
<= 7; i
++) {
554 printf("%02x", *cp
++);
563 isis_print_lspid(const u_char
*cp
)
567 for (i
= 1; i
<= 7; i
++) {
568 printf("%02x", *cp
++);
572 printf("-%02x", *cp
);
576 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
580 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
581 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
582 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
583 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
584 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
585 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
586 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
587 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
589 int mask
, prefix_len
;
590 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
592 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
595 if (length
< sizeof(*tlv_ip_reach
)) {
596 printf("short IP reachability (%d vs %lu)", length
,
597 (unsigned long)sizeof(*tlv_ip_reach
));
601 if (!TTEST(*tlv_ip_reach
))
604 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
607 while (prefix_len
<= 33) {
608 if (bitmasks
[prefix_len
++] == mask
) {
615 * 34 indicates no match -> must be a discontiguous netmask
616 * lets dump the mask, otherwise print the prefix_len
618 if (prefix_len
== 34)
619 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u",
620 (tlv_ip_reach
->prefix
)[0],
621 (tlv_ip_reach
->prefix
)[1],
622 (tlv_ip_reach
->prefix
)[2],
623 (tlv_ip_reach
->prefix
)[3],
624 (tlv_ip_reach
->mask
)[0], (tlv_ip_reach
->mask
)[1],
625 (tlv_ip_reach
->mask
)[2], (tlv_ip_reach
->mask
)[3]);
627 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u",
628 (tlv_ip_reach
->prefix
)[0],
629 (tlv_ip_reach
->prefix
)[1],
630 (tlv_ip_reach
->prefix
)[2],
631 (tlv_ip_reach
->prefix
)[3], prefix_len
);
633 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
634 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_default
),
635 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_default
) ? "External" : "Internal",
636 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->metric_default
) ? "down" : "up");
638 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_delay
))
639 printf("\n\t\t\t Delay Metric: %02d, %s",
640 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_delay
),
641 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_delay
) ? "External" : "Internal");
643 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_expense
))
644 printf("\n\t\t\t Expense Metric: %02d, %s",
645 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_expense
),
646 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_expense
) ? "External" : "Internal");
648 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_error
))
649 printf("\n\t\t\t Error Metric: %02d, %s",
650 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_error
),
651 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_error
) ? "External" : "Internal");
653 length
-= sizeof(struct isis_tlv_ip_reach
);
661 * Decode IS-IS packets. Return 0 on error.
664 static int isis_print (const u_char
*p
, u_int length
)
666 const struct isis_common_header
*header
;
668 const struct isis_iih_lan_header
*header_iih_lan
;
669 const struct isis_iih_ptp_header
*header_iih_ptp
;
670 const struct isis_lsp_header
*header_lsp
;
671 const struct isis_csnp_header
*header_csnp
;
672 const struct isis_psnp_header
*header_psnp
;
674 const struct isis_tlv_lsp
*tlv_lsp
;
675 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
676 const struct isis_tlv_is_reach
*tlv_is_reach
;
678 u_char pdu_type
, max_area
, type
, len
, tmp
, alen
, subl
, subt
, tslen
, ttslen
;
679 const u_char
*optr
, *pptr
, *tptr
;
680 u_short packet_len
,pdu_len
;
681 u_int i
,j
,bit_length
,byte_length
,metric
;
682 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
684 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
687 float bw
; /* copy buffer for several subTLVs of the extended IS reachability TLV */
690 optr
= p
; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */
691 header
= (const struct isis_common_header
*)p
;
693 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
694 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
695 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
696 header_lsp
= (const struct isis_lsp_header
*)pptr
;
697 header_csnp
= (const struct isis_csnp_header
*)pptr
;
698 header_psnp
= (const struct isis_psnp_header
*)pptr
;
701 * Sanity checking of the header.
703 if (header
->nlpid
!= NLPID_ISIS
) {
704 printf(", coding error!");
708 if (header
->version
!= ISIS_VERSION
) {
709 printf(", version %d packet not supported", header
->version
);
713 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
714 printf(", system ID length of %d is not supported",
719 if (header
->pkt_version
!= ISIS_VERSION
) {
720 printf(", version %d packet not supported", header
->pkt_version
);
724 max_area
= header
->max_area
;
727 max_area
= 3; /* silly shit */
730 printf(", bad packet -- 255 areas");
736 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)",
742 pdu_type
=header
->pdu_type
;
748 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
749 printf(", bogus fixed header length %u should be %lu",
750 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
754 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
755 if (packet_len
>pdu_len
) {
756 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
760 printf(", L%s Lan IIH (%u)",
761 ISIS_MASK_LEVEL_BITS(pdu_type
) ? "1" : "2",
764 TCHECK(*header_iih_lan
);
765 printf("\n\t\t source-id: ");
766 isis_print_sysid(header_iih_lan
->source_id
);
767 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan
->holding_time
));
768 switch(header_iih_lan
->circuit_type
) {
771 printf(", Level 1 only");
775 printf(", Level 2 only");
779 printf(", Level 1, Level 2");
783 printf(", unknown 0x%02x", header_iih_lan
->circuit_type
);
786 printf("\n\t\t lan-id: ");
787 isis_print_nodeid(header_iih_lan
->lan_id
);
788 printf(", Priority: %u",(header_iih_lan
->priority
) & PRIORITY_MASK
);
790 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
791 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
795 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
796 printf(", bogus fixed header length %u should be %lu",
797 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
801 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
802 if (packet_len
>pdu_len
) {
803 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
807 printf(", PTP IIH (%u)",pdu_len
);
808 TCHECK(*header_iih_ptp
);
809 printf("\n\t\t source-id: ");
810 isis_print_sysid(header_iih_ptp
->source_id
);
811 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp
->holding_time
));
812 printf(", circuit-id: 0x%02x", header_iih_ptp
->circuit_id
);
813 switch(header_iih_ptp
->circuit_type
) {
816 printf(", Level 1 only");
820 printf(", Level 2 only");
824 printf(", Level 1, Level 2");
828 printf(", unknown 0x%02x", header_iih_ptp
->circuit_type
);
832 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
833 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
838 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
839 printf(", bogus fixed header length %u should be %lu",
840 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
844 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
845 if (packet_len
>pdu_len
) {
846 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
850 if (pdu_type
== L1_LSP
)
851 printf(", L1 LSP (%u)",pdu_len
);
852 else if (pdu_type
== L2_LSP
)
853 printf(", L2 LSP (%u)",pdu_len
);
856 printf("\n\t\t lsp-id: ");
857 isis_print_lspid(header_lsp
->lsp_id
);
858 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp
->sequence_number
));
859 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
860 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp
->checksum
));
862 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
864 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
865 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
866 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
867 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
868 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
869 printf("ATT bit set, ");
871 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
872 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
874 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
875 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
880 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
881 printf(", bogus fixed header length %u should be %lu",
882 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
886 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
887 if (packet_len
>pdu_len
) {
888 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
892 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type
) ? "2" : "1", pdu_len
);
893 TCHECK(*header_csnp
);
894 printf("\n\t\t source-id: ");
895 isis_print_nodeid(header_csnp
->source_id
);
896 printf("\n\t\t start lsp-id: ");
897 isis_print_lspid(header_csnp
->start_lsp_id
);
898 printf("\n\t\t end lsp-id: ");
899 isis_print_lspid(header_csnp
->end_lsp_id
);
901 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
902 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
907 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
908 printf("- bogus fixed header length %u should be %lu",
909 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
913 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
914 if (packet_len
>pdu_len
) {
915 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
919 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type
) ? "2" : "1", pdu_len
);
920 TCHECK(*header_psnp
);
921 printf("\n\t\t source-id: ");
922 isis_print_nodeid(header_psnp
->source_id
);
924 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
925 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
929 printf(", PDU type (0x%02x) not supported", pdu_type
);
934 * Now print the TLV's.
937 while (packet_len
>= 2) {
938 if (pptr
== snapend
) {
942 if (!TTEST2(*pptr
, 2)) {
943 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
944 (long)(pptr
-snapend
));
950 if (len
> packet_len
) {
957 printf("Area address(es) (%u)",len
);
960 if (!TTEST2(*tptr
, 1))
963 while (tmp
&& alen
< tmp
) {
964 printf("\n\t\t\tArea address (%u): ",alen
);
965 if (!print_nsap(tptr
, alen
))
969 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
971 if (!TTEST2(*tptr
, 1))
977 printf("IS Neighbor(s) (%u)",len
);
980 while (tmp
>= ETHER_ADDR_LEN
) {
981 printf("\n\t\t\tIS Neighbor: ");
982 if (!isis_print_sysid(tptr
))
984 tmp
-= ETHER_ADDR_LEN
;
985 tptr
+= ETHER_ADDR_LEN
;
990 printf("Padding (%u)", len
);
993 case TLV_MT_IS_REACH
:
994 printf("Multi Topology IS Reachability (%u)",len
);
999 if (!TTEST2(*tptr
, 2))
1001 switch(EXTRACT_16BITS(tptr
)&0x0fff) {
1004 printf("IPv4 unicast");
1008 printf("In-Band Management");
1012 printf("IPv6 unicast");
1016 printf("Multicast");
1020 printf("Development, Experimental or Proprietary");
1024 printf("Reserved for IETF Consensus");
1027 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr
)&0x0fff);
1029 printf("\n\t\t\t IS Neighbor: ");
1030 if (!isis_print_nodeid(tptr
))
1032 tptr
+=(SYSTEM_ID_LEN
+1);
1033 if (!TTEST2(*tptr
, 3))
1035 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1037 if (!TTEST2(*tptr
, 1))
1040 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1047 case TLV_EXT_IS_REACH
:
1048 printf("Extended IS Reachability (%u)",len
);
1052 printf("\n\t\t\tIS Neighbor: ");
1053 if (!isis_print_nodeid(tptr
))
1055 tptr
+=(SYSTEM_ID_LEN
+1);
1056 if (!TTEST2(*tptr
, 3))
1058 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1060 if (!TTEST2(*tptr
, 1))
1063 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1065 printf(" (%u)",tslen
);
1068 if (!TTEST2(*tptr
,2))
1070 printf("\n\t\t\t ");
1074 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
1075 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr
));
1077 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
1078 if (!TTEST2(*tptr
,4))
1080 j
= EXTRACT_32BITS(tptr
);
1081 memcpy (&bw
, &j
, 4);
1082 printf("Maximum link bandwidth : %.3f Mbps",
1085 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
1086 if (!TTEST2(*tptr
,4))
1088 j
= EXTRACT_32BITS(tptr
);
1089 memcpy (&bw
, &j
, 4);
1090 printf("Reservable link bandwidth: %.3f Mbps",
1093 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
1094 printf("Unreserved bandwidth:");
1095 for (i
= 0; i
< 8; i
++) {
1096 if (!TTEST2(*tptr
,4))
1098 j
= EXTRACT_32BITS(tptr
);
1099 memcpy (&bw
, &j
, 4);
1100 printf("\n\t\t\t priority level %d: %.3f Mbps",
1106 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
1107 if (!TTEST2(*tptr
,3))
1109 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr
));
1111 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
1112 if (!TTEST2(*tptr
,4))
1114 printf("IPv4 interface address: %s", ipaddr_string(tptr
));
1116 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
1117 if (!TTEST2(*tptr
,4))
1119 printf("IPv4 neighbor address: %s", ipaddr_string(tptr
));
1126 printf("Reserved for cisco specific extensions, type %d, length %d", subt
, subl
);
1129 printf("Reserved for future expansion, type %d, length %d", subt
, subl
);
1132 printf("unknown subTLV, type %d, length %d", subt
, subl
);
1143 printf("IS Reachability (%u)",len
);
1144 tlv_is_reach
= (const struct isis_tlv_is_reach
*)pptr
;
1145 if (!TTEST(*tlv_is_reach
))
1147 printf("\n\t\t\tIS Neighbor: ");
1148 isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
);
1151 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1152 if (!TTEST(*tlv_is_reach
))
1155 printf(", Default Metric: %d, %s",
1156 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_default
),
1157 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_default
) ? "External" : "Internal");
1159 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_delay
))
1160 printf("\n\t\t\t Delay Metric: %d, %s",
1161 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_delay
),
1162 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_delay
) ? "External" : "Internal");
1164 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_expense
))
1165 printf("\n\t\t\t Expense Metric: %d, %s",
1166 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_expense
),
1167 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_expense
) ? "External" : "Internal");
1169 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_error
))
1170 printf("\n\t\t\t Error Metric: %d, %s",
1171 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_error
),
1172 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_error
) ? "External" : "Internal");
1174 switch (tlv_is_reach
->virtual_flag
) {
1176 printf(", IsNotVirtual");
1179 printf(", IsVirtual");
1182 printf(", bogus virtual flag 0x%02x",tlv_is_reach
->virtual_flag
);
1186 tmp
-= sizeof(struct isis_tlv_is_reach
);
1192 printf("IP Internal reachability (%u)",len
);
1193 if (!isis_print_tlv_ip_reach(pptr
, len
))
1197 case TLV_IP_REACH_EXT
:
1198 printf("IP External reachability (%u)",len
);
1199 if (!isis_print_tlv_ip_reach(pptr
, len
))
1203 case TLV_EXT_IP_REACH
:
1204 printf("Extended IP reachability (%u)",len
);
1209 memset (prefix
, 0, 4);
1210 if (!TTEST2(*tptr
, 4))
1212 metric
= EXTRACT_32BITS(tptr
);
1215 if (!TTEST2(*tptr
, 1))
1218 bit_length
= (*(tptr
)++&0x3f);
1219 byte_length
= (bit_length
+ 7) / 8;
1220 if (!TTEST2(*tptr
, byte_length
))
1223 memcpy(prefix
,tptr
,byte_length
);
1225 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d",
1232 printf("\n\t\t\t Metric: %u, Distribution: %s",
1234 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1236 printf(", %ssub-TLVs present",
1237 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1239 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1240 if (!TTEST2(*tptr
, 1))
1242 printf(" (%u)",*tptr
); /* no subTLV decoder supported - just print out subTLV length */
1255 printf("IP6 reachability (%u)",len
);
1260 if (!TTEST2(*tptr
, 4))
1262 metric
= EXTRACT_32BITS(tptr
);
1265 if (!TTEST2(*tptr
, 2))
1268 bit_length
= (*(tptr
)++);
1269 byte_length
= (bit_length
+ 7) / 8;
1270 if (!TTEST2(*tptr
, byte_length
))
1273 memset(prefix6
, 0, 16);
1274 memcpy(prefix6
,tptr
,byte_length
);
1276 printf("\n\t\t\tIPv6 prefix: %s/%u",
1277 ip6addr_string(prefix6
),
1280 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1282 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1283 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1284 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1286 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1287 if (!TTEST2(*tptr
, 1))
1289 printf(" (%u)",*tptr
); /* no subTLV decoder supported - just print out subTLV length */
1303 printf("IPv6 Interface address(es) (%u)",len
);
1307 if (!TTEST2(*tptr
, 16))
1310 printf("\n\t\t\tIPv6 interface address: %s",
1311 ip6addr_string(tptr
));
1319 if (!TTEST2(*pptr
, 1))
1321 printf("Authentication (%u)",len
);
1322 if (*pptr
==SUBTLV_AUTH_SIMPLE
) {
1323 printf("\n\t\t\tsimple text password: ");
1324 for(i
=1;i
<len
;i
++) {
1325 if (!TTEST2(*(pptr
+i
), 1))
1327 printf("%c",*(pptr
+i
));
1330 if (!TTEST2(*pptr
, 1))
1332 if (*pptr
==SUBTLV_AUTH_MD5
) {
1333 printf("\n\t\t\tMD5 password: ");
1334 for(i
=1;i
<len
;i
++) {
1335 if (!TTEST2(*(pptr
+i
), 1))
1337 printf("%02x",*(pptr
+i
));
1343 printf("Point-to-point Adjacency State (%u)",len
);
1344 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)pptr
;
1347 if (!TTEST2(*pptr
, 1))
1349 printf("\n\t\t\tAdjacency State: %s",
1350 tok2str(isis_ptp_adjancey_values
, "#0x%x", *pptr
));
1354 if (!TTEST2(tlv_ptp_adj
->ext_local_circuit_id
, 4))
1356 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1357 EXTRACT_32BITS(tlv_ptp_adj
->ext_local_circuit_id
));
1361 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, 6))
1363 printf("\n\t\t\tNeighbor SystemID: ");
1364 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
);
1368 if (!TTEST2(tlv_ptp_adj
->neighbor_ext_local_circuit_id
, 4))
1370 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1371 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_ext_local_circuit_id
));
1376 printf("Protocols supported (%u)", len
);
1377 printf("\n\t\t\tNLPID(s): ");
1378 for (i
= 0; i
< len
; i
++) {
1379 if (!TTEST2(*(pptr
+i
), 1))
1381 printf("%s (0x%02x)",tok2str(isis_nlpid_values
, "Unknown", *(pptr
+i
)),*(pptr
+i
));
1387 case TLV_TE_ROUTER_ID
:
1388 printf("Traffic Engineering Router ID (%u)",len
);
1389 if (!TTEST2(*pptr
, 4))
1391 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1395 printf("IPv4 Interface address(es) (%u)",len
);
1399 if (!TTEST2(*tptr
, 4))
1401 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1408 printf("Hostname (%u)", len
);
1409 printf("\n\t\t\tHostname: ");
1410 for(i
= 0; i
< len
; i
++) {
1411 if (!TTEST2(*(pptr
+i
), 1))
1413 printf("%c",*(pptr
+i
));
1418 tlv_lsp
= (const struct isis_tlv_lsp
*)pptr
;
1419 printf("LSP entries (%u)", len
);
1422 printf("\n\t\t\tlsp-id: ");
1423 if (!isis_print_nodeid(tlv_lsp
->lsp_id
))
1425 if (!TTEST((tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]))
1427 printf("-%02x",(tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]);
1428 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1430 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1431 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1433 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1434 if (!TTEST2(tlv_lsp
->checksum
, 2))
1436 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1437 i
+=sizeof(struct isis_tlv_lsp
);
1443 if (!TTEST2(*pptr
, 2))
1445 printf("Checksum (%u)", len
);
1446 printf("\n\t\t\tchecksum: 0x%04x",
1447 EXTRACT_16BITS(pptr
));
1449 if (osi_cksum(optr
, length
, off
))
1450 printf(" (incorrect)");
1452 printf(" (correct)");
1455 case TLV_MT_SUPPORTED
:
1456 printf("Multi Topology (%u)",len
);
1460 /* length can only be a multiple of 2, otherwise there is
1461 something broken -> so decode down until length is 1 */
1463 if (!TTEST2(*tptr
, 2))
1466 switch(EXTRACT_16BITS(tptr
)&0x0fff) {
1469 printf("IPv4 unicast");
1473 printf("In-Band Management");
1477 printf("IPv6 unicast");
1481 printf("Multicast");
1485 printf("Development, Experimental or Proprietary");
1489 printf("Reserved for IETF Consensus");
1492 printf(" Topology (0x%03x)%s%s",
1493 EXTRACT_16BITS(tptr
)&0xfff,
1494 (EXTRACT_16BITS(tptr
)&0x8000) ? "" : ", no sub-TLVs present",
1495 (EXTRACT_16BITS(tptr
)&0x4000) ? ", ATT bit set" : "" );
1497 printf("\n\t\t\tmalformed MT-ID");
1505 case TLV_RESTART_SIGNALING
:
1507 printf("Restart Signaling (%u)",len
);
1508 if (!TTEST2(*tptr
, 3))
1511 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1512 ISIS_MASK_RESTART_RR(*tptr
) ? "set" : "clear",
1513 ISIS_MASK_RESTART_RA(*tptr
++) ? "set" : "clear",
1514 EXTRACT_16BITS(tptr
));
1519 printf("unknown TLV, type %d, length %d\n\t\t\t", type
, len
);
1522 for(i
=0;i
<len
;i
++) {
1523 if (!TTEST2(*(tptr
+i
), 1))
1525 printf("%02x",*(tptr
+i
)); /* formatted hex output of unknown TLV data */
1528 if (i
/16!=(i
+1)/16) {
1540 if (packet_len
!= 0) {
1541 printf("\n\t\t\t %d straggler bytes", packet_len
);
1546 fputs("[|isis]", stdout
);
1550 printf("\n\t\t\t packet exceeded snapshot");
1555 * Verify the checksum. See 8473-1, Appendix C, section C.4.
1559 osi_cksum(register const u_char
*p
, register u_int len
, u_char
*off
)
1561 int32_t c0
= 0, c1
= 0;
1563 if ((off
[0] == 0) && (off
[1] == 0))
1566 off
[0] = off
[1] = 0;
1567 while ((int)--len
>= 0) {