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.36 2002-01-10 09:33:23 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
{
205 u_char metric_default
;
207 u_char metric_expense
;
209 u_char neighbor_nodeid
[SYSTEM_ID_LEN
+1];
213 struct isis_common_header
{
216 u_char version
; /* Protocol version? */
218 u_char pdu_type
; /* 3 MSbs are reserved */
219 u_char pkt_version
; /* Packet format version? */
224 struct isis_iih_lan_header
{
226 u_char source_id
[SYSTEM_ID_LEN
];
227 u_char holding_time
[2];
230 u_char lan_id
[SYSTEM_ID_LEN
+1];
233 struct isis_iih_ptp_header
{
235 u_char source_id
[SYSTEM_ID_LEN
];
236 u_char holding_time
[2];
241 struct isis_lsp_header
{
243 u_char remaining_lifetime
[2];
244 u_char lsp_id
[SYSTEM_ID_LEN
+2];
245 u_char sequence_number
[4];
250 struct isis_csnp_header
{
252 u_char source_id
[SYSTEM_ID_LEN
+1];
253 u_char start_lsp_id
[SYSTEM_ID_LEN
+2];
254 u_char end_lsp_id
[SYSTEM_ID_LEN
+2];
257 struct isis_psnp_header
{
259 u_char source_id
[SYSTEM_ID_LEN
+1];
262 struct isis_tlv_lsp
{
263 u_char remaining_lifetime
[2];
264 u_char lsp_id
[SYSTEM_ID_LEN
+2];
265 u_char sequence_number
[4];
269 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
270 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
271 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
272 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
273 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
274 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
276 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
277 const u_char
*esrc
, const u_char
*edst
)
280 const struct isis_common_header
*header
;
282 header
= (const struct isis_common_header
*)p
;
283 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
286 printf("[|iso-clns] ");
287 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
289 etheraddr_string(esrc
),
290 etheraddr_string(edst
));
297 (void)printf("CLNS(%d)", length
);
298 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
299 (void)printf(", %s > %s",
300 etheraddr_string(esrc
),
301 etheraddr_string(edst
));
305 (void)printf("ESIS");
306 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
307 (void)printf(", %s > %s",
308 etheraddr_string(esrc
),
309 etheraddr_string(edst
));
310 esis_print(p
, length
);
314 (void)printf("ISIS(%d)", length
);
315 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
316 (void)printf(", %s > %s",
317 etheraddr_string(esrc
),
318 etheraddr_string(edst
));
319 if (!isis_print(p
, length
))
320 default_print_unaligned(p
, caplen
);
324 (void)printf("ISO NULLNS(%d)", length
);
325 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
326 (void)printf(", %s > %s",
327 etheraddr_string(esrc
),
328 etheraddr_string(edst
));
332 (void)printf("CLNS %02x(%d)", p
[0], length
);
333 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
334 (void)printf(", %s > %s",
335 etheraddr_string(esrc
),
336 etheraddr_string(edst
));
338 default_print_unaligned(p
, caplen
);
343 #define ESIS_REDIRECT 6
356 esis_print(const u_char
*p
, u_int length
)
360 const struct esis_hdr
*eh
;
367 printf(" no header at all!");
371 eh
= (const struct esis_hdr
*) &p
[2];
377 printf(" LI(%d) > PDU size (%d)!", li
, length
);
380 if (li
< sizeof(struct esis_hdr
) + 2) {
384 printf(" too short for esis header %d:", li
);
385 while (--length
!= 0)
386 printf("%02X", *p
++);
390 switch (eh
->type
& 0x1f) {
405 printf(" type %d", eh
->type
& 0x1f);
408 off
[0] = eh
->cksum
[0];
409 off
[1] = eh
->cksum
[1];
410 if (vflag
&& osi_cksum(p
, li
, off
)) {
411 printf(" bad cksum (got %02x%02x)",
412 eh
->cksum
[1], eh
->cksum
[0]);
413 default_print(p
, length
);
416 if (eh
->version
!= 1) {
417 printf(" unsupported version %d", eh
->version
);
420 p
+= sizeof(*eh
) + 2;
421 li
-= sizeof(*eh
) + 2; /* protoid * li */
423 switch (eh
->type
& 0x1f) {
424 case ESIS_REDIRECT
: {
425 const u_char
*dst
, *snpa
, *is
;
427 dst
= p
; p
+= *p
+ 1;
430 printf("\n\t\t\t %s", isonsap_string(dst
));
431 snpa
= p
; p
+= *p
+ 1;
440 printf(" > %s", etheraddr_string(&snpa
[1]));
442 printf(" > %s", isonsap_string(is
));
462 printf("\n\t\t\t %s", isonsap_string(is
));
468 (void)printf(" len=%d", length
);
469 if (length
&& p
< snapend
) {
470 length
= snapend
- p
;
471 default_print(p
, length
);
476 while (p
< ep
&& li
) {
483 printf(" bad opts/li");
490 printf(" opt (%d) too long", op
);
498 if (op
== 198 && opli
== 2) {
499 printf(" tmo=%d", q
[0] * 256 + q
[1]);
502 printf (" %d:<", op
);
504 printf("%02x", *q
++);
514 print_nsap(register const u_char
*cp
, register int length
)
518 for (i
= 0; i
< length
; i
++) {
521 printf("%02x", *cp
++);
522 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
530 isis_print_sysid(const u_char
*cp
)
534 for (i
= 1; i
<= 6; i
++) {
537 printf("%02x", *cp
++);
546 isis_print_nodeid(const u_char
*cp
)
550 for (i
= 1; i
<= 7; i
++) {
553 printf("%02x", *cp
++);
562 isis_print_lspid(const u_char
*cp
)
566 for (i
= 1; i
<= 7; i
++) {
567 printf("%02x", *cp
++);
571 printf("-%02x", *cp
);
575 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
579 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
580 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
581 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
582 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
583 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
584 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
585 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
586 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
588 int mask
, prefix_len
;
589 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
591 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
594 if (length
< sizeof(*tlv_ip_reach
)) {
595 printf("short IP reachability (%d vs %lu)", length
,
596 (unsigned long)sizeof(*tlv_ip_reach
));
600 if (!TTEST(*tlv_ip_reach
))
603 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
606 while (prefix_len
<= 33) {
607 if (bitmasks
[prefix_len
++] == mask
) {
614 * 34 indicates no match -> must be a discontiguous netmask
615 * lets dump the mask, otherwise print the prefix_len
617 if (prefix_len
== 34)
618 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u",
619 (tlv_ip_reach
->prefix
)[0],
620 (tlv_ip_reach
->prefix
)[1],
621 (tlv_ip_reach
->prefix
)[2],
622 (tlv_ip_reach
->prefix
)[3],
623 (tlv_ip_reach
->mask
)[0], (tlv_ip_reach
->mask
)[1],
624 (tlv_ip_reach
->mask
)[2], (tlv_ip_reach
->mask
)[3]);
626 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u",
627 (tlv_ip_reach
->prefix
)[0],
628 (tlv_ip_reach
->prefix
)[1],
629 (tlv_ip_reach
->prefix
)[2],
630 (tlv_ip_reach
->prefix
)[3], prefix_len
);
632 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
633 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_default
),
634 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_default
) ? "External" : "Internal",
635 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->metric_default
) ? "down" : "up");
637 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_delay
))
638 printf("\n\t\t\t Delay Metric: %02d, %s",
639 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_delay
),
640 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_delay
) ? "External" : "Internal");
642 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_expense
))
643 printf("\n\t\t\t Expense Metric: %02d, %s",
644 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_expense
),
645 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_expense
) ? "External" : "Internal");
647 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_error
))
648 printf("\n\t\t\t Error Metric: %02d, %s",
649 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_error
),
650 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_error
) ? "External" : "Internal");
652 length
-= sizeof(struct isis_tlv_ip_reach
);
660 * Decode IS-IS packets. Return 0 on error.
663 static int isis_print (const u_char
*p
, u_int length
)
665 const struct isis_common_header
*header
;
667 const struct isis_iih_lan_header
*header_iih_lan
;
668 const struct isis_iih_ptp_header
*header_iih_ptp
;
669 const struct isis_lsp_header
*header_lsp
;
670 const struct isis_csnp_header
*header_csnp
;
671 const struct isis_psnp_header
*header_psnp
;
673 const struct isis_tlv_lsp
*tlv_lsp
;
674 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
675 const struct isis_tlv_is_reach
*tlv_is_reach
;
677 u_char pdu_type
, max_area
, type
, len
, tmp
, alen
, subl
, subt
, tslen
, ttslen
;
678 const u_char
*optr
, *pptr
, *tptr
;
679 u_short packet_len
,pdu_len
;
680 u_int i
,j
,bit_length
,byte_length
,metric
;
681 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
683 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
686 float bw
; /* copy buffer for several subTLVs of the extended IS reachability TLV */
689 optr
= p
; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */
690 header
= (const struct isis_common_header
*)p
;
692 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
693 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
694 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
695 header_lsp
= (const struct isis_lsp_header
*)pptr
;
696 header_csnp
= (const struct isis_csnp_header
*)pptr
;
697 header_psnp
= (const struct isis_psnp_header
*)pptr
;
700 * Sanity checking of the header.
702 if (header
->nlpid
!= NLPID_ISIS
) {
703 printf(", coding error!");
707 if (header
->version
!= ISIS_VERSION
) {
708 printf(", version %d packet not supported", header
->version
);
712 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
713 printf(", system ID length of %d is not supported",
718 if (header
->pkt_version
!= ISIS_VERSION
) {
719 printf(", version %d packet not supported", header
->pkt_version
);
723 max_area
= header
->max_area
;
726 max_area
= 3; /* silly shit */
729 printf(", bad packet -- 255 areas");
735 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)",
741 pdu_type
=header
->pdu_type
;
747 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
748 printf(", bogus fixed header length %u should be %lu",
749 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
753 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
754 if (packet_len
>pdu_len
) {
755 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
759 printf(", L%s Lan IIH (%u)",
760 ISIS_MASK_LEVEL_BITS(pdu_type
) ? "1" : "2",
763 TCHECK(*header_iih_lan
);
764 printf("\n\t\t source-id: ");
765 isis_print_sysid(header_iih_lan
->source_id
);
766 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan
->holding_time
));
767 switch(header_iih_lan
->circuit_type
) {
770 printf(", Level 1 only");
774 printf(", Level 2 only");
778 printf(", Level 1, Level 2");
782 printf(", unknown 0x%02x", header_iih_lan
->circuit_type
);
785 printf("\n\t\t lan-id: ");
786 isis_print_nodeid(header_iih_lan
->lan_id
);
787 printf(", Priority: %u",(header_iih_lan
->priority
) & PRIORITY_MASK
);
789 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
790 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
794 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
795 printf(", bogus fixed header length %u should be %lu",
796 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
800 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
801 if (packet_len
>pdu_len
) {
802 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
806 printf(", PTP IIH (%u)",pdu_len
);
807 TCHECK(*header_iih_ptp
);
808 printf("\n\t\t source-id: ");
809 isis_print_sysid(header_iih_ptp
->source_id
);
810 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp
->holding_time
));
811 printf(", circuit-id: 0x%02x", header_iih_ptp
->circuit_id
);
812 switch(header_iih_ptp
->circuit_type
) {
815 printf(", Level 1 only");
819 printf(", Level 2 only");
823 printf(", Level 1, Level 2");
827 printf(", unknown 0x%02x", header_iih_ptp
->circuit_type
);
831 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
832 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
837 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
838 printf(", bogus fixed header length %u should be %lu",
839 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
843 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
844 if (packet_len
>pdu_len
) {
845 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
849 if (pdu_type
== L1_LSP
)
850 printf(", L1 LSP (%u)",pdu_len
);
851 else if (pdu_type
== L2_LSP
)
852 printf(", L2 LSP (%u)",pdu_len
);
855 printf("\n\t\t lsp-id: ");
856 isis_print_lspid(header_lsp
->lsp_id
);
857 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp
->sequence_number
));
858 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
859 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp
->checksum
));
861 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
863 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
864 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
865 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
866 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
867 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
868 printf("ATT bit set, ");
870 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
871 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
873 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
874 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
879 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
880 printf(", bogus fixed header length %u should be %lu",
881 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
885 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
886 if (packet_len
>pdu_len
) {
887 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
891 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type
) ? "2" : "1", pdu_len
);
892 TCHECK(*header_csnp
);
893 printf("\n\t\t source-id: ");
894 isis_print_nodeid(header_csnp
->source_id
);
895 printf("\n\t\t start lsp-id: ");
896 isis_print_lspid(header_csnp
->start_lsp_id
);
897 printf("\n\t\t end lsp-id: ");
898 isis_print_lspid(header_csnp
->end_lsp_id
);
900 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
901 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
906 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
907 printf("- bogus fixed header length %u should be %lu",
908 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
912 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
913 if (packet_len
>pdu_len
) {
914 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
918 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type
) ? "2" : "1", pdu_len
);
919 TCHECK(*header_psnp
);
920 printf("\n\t\t source-id: ");
921 isis_print_nodeid(header_psnp
->source_id
);
923 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
924 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
928 printf(", PDU type (0x%02x) not supported", pdu_type
);
933 * Now print the TLV's.
936 while (packet_len
>= 2) {
937 if (pptr
== snapend
) {
941 if (!TTEST2(*pptr
, 2)) {
942 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
943 (long)(pptr
-snapend
));
949 if (len
> packet_len
) {
956 printf("Area address(es) (%u)",len
);
959 if (!TTEST2(*tptr
, 1))
962 while (tmp
&& alen
< tmp
) {
963 printf("\n\t\t\tArea address (%u): ",alen
);
964 if (!print_nsap(tptr
, alen
))
968 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
970 if (!TTEST2(*tptr
, 1))
976 printf("IS Neighbor(s) (%u)",len
);
979 while (tmp
>= ETHER_ADDR_LEN
) {
980 printf("\n\t\t\tIS Neighbor: ");
981 if (!isis_print_sysid(tptr
))
983 tmp
-= ETHER_ADDR_LEN
;
984 tptr
+= ETHER_ADDR_LEN
;
989 printf("Padding (%u)", len
);
992 case TLV_MT_IS_REACH
:
993 printf("Multi Topology IS Reachability (%u)",len
);
998 if (!TTEST2(*tptr
, 2))
1000 switch(EXTRACT_16BITS(tptr
)&0x0fff) {
1003 printf("IPv4 unicast");
1007 printf("In-Band Management");
1011 printf("IPv6 unicast");
1015 printf("Multicast");
1019 printf("Development, Experimental or Proprietary");
1023 printf("Reserved for IETF Consensus");
1026 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr
)&0x0fff);
1028 printf("\n\t\t\t IS Neighbor: ");
1029 if (!isis_print_nodeid(tptr
))
1031 tptr
+=(SYSTEM_ID_LEN
+1);
1032 if (!TTEST2(*tptr
, 3))
1034 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1036 if (!TTEST2(*tptr
, 1))
1039 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1046 case TLV_EXT_IS_REACH
:
1047 printf("Extended IS Reachability (%u)",len
);
1051 printf("\n\t\t\tIS Neighbor: ");
1052 if (!isis_print_nodeid(tptr
))
1054 tptr
+=(SYSTEM_ID_LEN
+1);
1055 if (!TTEST2(*tptr
, 3))
1057 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1059 if (!TTEST2(*tptr
, 1))
1062 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1064 printf(" (%u)",tslen
);
1067 if (!TTEST2(*tptr
,2))
1069 printf("\n\t\t\t ");
1073 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
1074 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr
));
1076 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
1077 if (!TTEST2(*tptr
,4))
1079 j
= EXTRACT_32BITS(tptr
);
1080 memcpy (&bw
, &j
, 4);
1081 printf("Maximum link bandwidth : %.3f Mbps",
1084 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
1085 if (!TTEST2(*tptr
,4))
1087 j
= EXTRACT_32BITS(tptr
);
1088 memcpy (&bw
, &j
, 4);
1089 printf("Reservable link bandwidth: %.3f Mbps",
1092 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
1093 printf("Unreserved bandwidth:");
1094 for (i
= 0; i
< 8; i
++) {
1095 if (!TTEST2(*tptr
,4))
1097 j
= EXTRACT_32BITS(tptr
);
1098 memcpy (&bw
, &j
, 4);
1099 printf("\n\t\t\t priority level %d: %.3f Mbps",
1105 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
1106 if (!TTEST2(*tptr
,3))
1108 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr
));
1110 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
1111 if (!TTEST2(*tptr
,4))
1113 printf("IPv4 interface address: %s", ipaddr_string(tptr
));
1115 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
1116 if (!TTEST2(*tptr
,4))
1118 printf("IPv4 neighbor address: %s", ipaddr_string(tptr
));
1125 printf("Reserved for cisco specific extensions, type %d, length %d", subt
, subl
);
1128 printf("Reserved for future expansion, type %d, length %d", subt
, subl
);
1131 printf("unknown subTLV, type %d, length %d", subt
, subl
);
1142 printf("IS Reachability (%u)",len
);
1146 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1151 printf("\n\t\t\tIsNotVirtual");
1154 printf("\n\t\t\tIsVirtual");
1157 printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr
));
1163 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1166 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1167 if (!TTEST(*tlv_is_reach
))
1170 printf("\n\t\t\tIS Neighbor: ");
1171 isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
);
1173 printf(", Default Metric: %d, %s",
1174 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_default
),
1175 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_default
) ? "External" : "Internal");
1177 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_delay
))
1178 printf("\n\t\t\t Delay Metric: %d, %s",
1179 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_delay
),
1180 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_delay
) ? "External" : "Internal");
1182 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_expense
))
1183 printf("\n\t\t\t Expense Metric: %d, %s",
1184 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_expense
),
1185 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_expense
) ? "External" : "Internal");
1187 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_error
))
1188 printf("\n\t\t\t Error Metric: %d, %s",
1189 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_error
),
1190 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_error
) ? "External" : "Internal");
1192 tmp
-= sizeof(struct isis_tlv_is_reach
);
1198 printf("IP Internal reachability (%u)",len
);
1199 if (!isis_print_tlv_ip_reach(pptr
, len
))
1203 case TLV_IP_REACH_EXT
:
1204 printf("IP External reachability (%u)",len
);
1205 if (!isis_print_tlv_ip_reach(pptr
, len
))
1209 case TLV_EXT_IP_REACH
:
1210 printf("Extended IP reachability (%u)",len
);
1215 memset (prefix
, 0, 4);
1216 if (!TTEST2(*tptr
, 4))
1218 metric
= EXTRACT_32BITS(tptr
);
1221 if (!TTEST2(*tptr
, 1))
1224 bit_length
= (*(tptr
)++&0x3f);
1225 byte_length
= (bit_length
+ 7) / 8;
1226 if (!TTEST2(*tptr
, byte_length
))
1229 memcpy(prefix
,tptr
,byte_length
);
1231 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d",
1238 printf("\n\t\t\t Metric: %u, Distribution: %s",
1240 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1242 printf(", %ssub-TLVs present",
1243 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1245 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1246 if (!TTEST2(*tptr
, 1))
1248 printf(" (%u)",*tptr
); /* no subTLV decoder supported - just print out subTLV length */
1261 printf("IP6 reachability (%u)",len
);
1266 if (!TTEST2(*tptr
, 4))
1268 metric
= EXTRACT_32BITS(tptr
);
1271 if (!TTEST2(*tptr
, 2))
1274 bit_length
= (*(tptr
)++);
1275 byte_length
= (bit_length
+ 7) / 8;
1276 if (!TTEST2(*tptr
, byte_length
))
1279 memset(prefix6
, 0, 16);
1280 memcpy(prefix6
,tptr
,byte_length
);
1282 printf("\n\t\t\tIPv6 prefix: %s/%u",
1283 ip6addr_string(prefix6
),
1286 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1288 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1289 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1290 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1292 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1293 if (!TTEST2(*tptr
, 1))
1295 printf(" (%u)",*tptr
); /* no subTLV decoder supported - just print out subTLV length */
1309 printf("IPv6 Interface address(es) (%u)",len
);
1313 if (!TTEST2(*tptr
, 16))
1316 printf("\n\t\t\tIPv6 interface address: %s",
1317 ip6addr_string(tptr
));
1325 if (!TTEST2(*pptr
, 1))
1327 printf("Authentication (%u)",len
);
1328 if (*pptr
==SUBTLV_AUTH_SIMPLE
) {
1329 printf("\n\t\t\tsimple text password: ");
1330 for(i
=1;i
<len
;i
++) {
1331 if (!TTEST2(*(pptr
+i
), 1))
1333 printf("%c",*(pptr
+i
));
1336 if (!TTEST2(*pptr
, 1))
1338 if (*pptr
==SUBTLV_AUTH_MD5
) {
1339 printf("\n\t\t\tMD5 password: ");
1340 for(i
=1;i
<len
;i
++) {
1341 if (!TTEST2(*(pptr
+i
), 1))
1343 printf("%02x",*(pptr
+i
));
1349 printf("Point-to-point Adjacency State (%u)",len
);
1350 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)pptr
;
1353 if (!TTEST2(*pptr
, 1))
1355 printf("\n\t\t\tAdjacency State: %s",
1356 tok2str(isis_ptp_adjancey_values
, "#0x%x", *pptr
));
1360 if (!TTEST2(tlv_ptp_adj
->ext_local_circuit_id
, 4))
1362 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1363 EXTRACT_32BITS(tlv_ptp_adj
->ext_local_circuit_id
));
1367 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, 6))
1369 printf("\n\t\t\tNeighbor SystemID: ");
1370 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
);
1374 if (!TTEST2(tlv_ptp_adj
->neighbor_ext_local_circuit_id
, 4))
1376 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1377 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_ext_local_circuit_id
));
1382 printf("Protocols supported (%u)", len
);
1383 printf("\n\t\t\tNLPID(s): ");
1384 for (i
= 0; i
< len
; i
++) {
1385 if (!TTEST2(*(pptr
+i
), 1))
1387 printf("%s (0x%02x)",tok2str(isis_nlpid_values
, "Unknown", *(pptr
+i
)),*(pptr
+i
));
1393 case TLV_TE_ROUTER_ID
:
1394 printf("Traffic Engineering Router ID (%u)",len
);
1395 if (!TTEST2(*pptr
, 4))
1397 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1401 printf("IPv4 Interface address(es) (%u)",len
);
1405 if (!TTEST2(*tptr
, 4))
1407 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1414 printf("Hostname (%u)", len
);
1415 printf("\n\t\t\tHostname: ");
1416 for(i
= 0; i
< len
; i
++) {
1417 if (!TTEST2(*(pptr
+i
), 1))
1419 printf("%c",*(pptr
+i
));
1424 tlv_lsp
= (const struct isis_tlv_lsp
*)pptr
;
1425 printf("LSP entries (%u)", len
);
1428 printf("\n\t\t\tlsp-id: ");
1429 if (!isis_print_nodeid(tlv_lsp
->lsp_id
))
1431 if (!TTEST((tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]))
1433 printf("-%02x",(tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]);
1434 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1436 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1437 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1439 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1440 if (!TTEST2(tlv_lsp
->checksum
, 2))
1442 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1443 i
+=sizeof(struct isis_tlv_lsp
);
1449 if (!TTEST2(*pptr
, 2))
1451 printf("Checksum (%u)", len
);
1452 printf("\n\t\t\tchecksum: 0x%04x",
1453 EXTRACT_16BITS(pptr
));
1455 if (osi_cksum(optr
, length
, off
))
1456 printf(" (incorrect)");
1458 printf(" (correct)");
1461 case TLV_MT_SUPPORTED
:
1462 printf("Multi Topology (%u)",len
);
1466 /* length can only be a multiple of 2, otherwise there is
1467 something broken -> so decode down until length is 1 */
1469 if (!TTEST2(*tptr
, 2))
1472 switch(EXTRACT_16BITS(tptr
)&0x0fff) {
1475 printf("IPv4 unicast");
1479 printf("In-Band Management");
1483 printf("IPv6 unicast");
1487 printf("Multicast");
1491 printf("Development, Experimental or Proprietary");
1495 printf("Reserved for IETF Consensus");
1498 printf(" Topology (0x%03x)%s%s",
1499 EXTRACT_16BITS(tptr
)&0xfff,
1500 (EXTRACT_16BITS(tptr
)&0x8000) ? "" : ", no sub-TLVs present",
1501 (EXTRACT_16BITS(tptr
)&0x4000) ? ", ATT bit set" : "" );
1503 printf("\n\t\t\tmalformed MT-ID");
1511 case TLV_RESTART_SIGNALING
:
1513 printf("Restart Signaling (%u)",len
);
1514 if (!TTEST2(*tptr
, 3))
1517 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1518 ISIS_MASK_RESTART_RR(*tptr
) ? "set" : "clear",
1519 ISIS_MASK_RESTART_RA(*tptr
++) ? "set" : "clear",
1520 EXTRACT_16BITS(tptr
));
1525 printf("unknown TLV, type %d, length %d\n\t\t\t", type
, len
);
1528 for(i
=0;i
<len
;i
++) {
1529 if (!TTEST2(*(tptr
+i
), 1))
1531 printf("%02x",*(tptr
+i
)); /* formatted hex output of unknown TLV data */
1534 if (i
/16!=(i
+1)/16) {
1546 if (packet_len
!= 0) {
1547 printf("\n\t\t\t %d straggler bytes", packet_len
);
1552 fputs("[|isis]", stdout
);
1556 printf("\n\t\t\t packet exceeded snapshot");
1561 * Verify the checksum. See 8473-1, Appendix C, section C.4.
1565 osi_cksum(register const u_char
*p
, register u_int len
, u_char
*off
)
1567 int32_t c0
= 0, c1
= 0;
1569 if ((off
[0] == 0) && (off
[1] == 0))
1572 off
[0] = off
[1] = 0;
1573 while ((int)--len
>= 0) {