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.46 2002-04-30 09:04:35 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
77 static struct tok isis_pdu_values
[] = {
78 { L1_LAN_IIH
, "L1 Lan IIH"},
79 { L2_LAN_IIH
, "L2 Lan IIH"},
80 { PTP_IIH
, "p2p IIH"},
83 { L1_CSNP
, "L1 CSNP"},
84 { L2_CSNP
, "L2 CSNP"},
85 { L1_PSNP
, "L1 PSNP"},
86 { L2_PSNP
, "L2 PSNP"},
91 * A TLV is a tuple of a type, length and a value and is normally used for
92 * encoding information in all sorts of places. This is an enumeration of
93 * the well known types.
95 * list taken from draft-ietf-isis-wg-tlv-codepoints-01.txt
98 #define TLV_AREA_ADDR 1
99 #define TLV_IS_REACH 2
100 #define TLV_ESNEIGH 3
101 #define TLV_PART_DIS 4
102 #define TLV_SUMMARY 5
103 #define TLV_ISNEIGH 6
104 #define TLV_PADDING 8
107 #define TLV_CHECKSUM 12
108 #define TLV_LSP_BUFFERSIZE 14
109 #define TLV_EXT_IS_REACH 22
110 #define TLV_IS_ALIAS_ID 24
111 #define TLV_DECNET_PHASE4 42
112 #define TLV_LUCENT_PRIVATE 66
113 #define TLV_IP_REACH 128
114 #define TLV_PROTOCOLS 129
115 #define TLV_IP_REACH_EXT 130
116 #define TLV_IDRP_INFO 131
117 #define TLV_IPADDR 132
118 #define TLV_IPAUTH 133
119 #define TLV_TE_ROUTER_ID 134
120 #define TLV_EXT_IP_REACH 135
121 #define TLV_HOSTNAME 137
122 #define TLV_SHARED_RISK_GROUP 138
123 #define TLV_NORTEL_PRIVATE1 176
124 #define TLV_NORTEL_PRIVATE2 177
125 #define TLV_RESTART_SIGNALING 211
126 #define TLV_MT_IS_REACH 222
127 #define TLV_MT_SUPPORTED 229
128 #define TLV_IP6ADDR 232
129 #define TLV_MT_IP_REACH 235
130 #define TLV_IP6_REACH 236
131 #define TLV_MT_IP6_REACH 237
132 #define TLV_PTP_ADJ 240
134 static struct tok isis_tlv_values
[] = {
135 { TLV_AREA_ADDR
, "Area address(es)"},
136 { TLV_IS_REACH
, "IS Reachability"},
137 { TLV_ESNEIGH
, "IS Neighbor(s)"},
138 { TLV_PART_DIS
, "Partition DIS"},
139 { TLV_SUMMARY
, "Prefix Neighbors"},
140 { TLV_ISNEIGH
, "IS Neighbor(s)"},
141 { TLV_PADDING
, "Padding"},
142 { TLV_LSP
, "LSP entries"},
143 { TLV_AUTH
, "Authentication"},
144 { TLV_CHECKSUM
, "Checksum"},
145 { TLV_LSP_BUFFERSIZE
, "LSP Buffersize"},
146 { TLV_EXT_IS_REACH
, "Extended IS Reachability"},
147 { TLV_IS_ALIAS_ID
, "IS Alias ID"},
148 { TLV_DECNET_PHASE4
, "DECnet Phase IV"},
149 { TLV_LUCENT_PRIVATE
, "Lucent Proprietary"},
150 { TLV_IP_REACH
, "IP Internal reachability"},
151 { TLV_PROTOCOLS
, "Protocols supported"},
152 { TLV_IP_REACH_EXT
, "IP External reachability"},
153 { TLV_IDRP_INFO
, "Inter-Domain Information Type"},
154 { TLV_IPADDR
, "IP Interface address(es)"},
155 { TLV_IPAUTH
, "IP authentication (depreciated)"},
156 { TLV_TE_ROUTER_ID
, "Traffic Engineering Router ID"},
157 { TLV_EXT_IP_REACH
, "Extended IP reachability"},
158 { TLV_HOSTNAME
, "Hostname"},
159 { TLV_SHARED_RISK_GROUP
, "Shared Risk Link Group"},
160 { TLV_NORTEL_PRIVATE1
, "Nortel Proprietary"},
161 { TLV_NORTEL_PRIVATE2
, "Nortel Proprietary"},
162 { TLV_RESTART_SIGNALING
, "Restart Signaling"},
163 { TLV_MT_IS_REACH
, "Multi Topology IS Reachability"},
164 { TLV_MT_SUPPORTED
, "Multi Topology"},
165 { TLV_IP6ADDR
, "IP6 Interface address(es)"},
166 { TLV_MT_IP_REACH
, "Multi-Topology IP reachability"},
167 { TLV_IP6_REACH
, "IP6 reachability"},
168 { TLV_MT_IP6_REACH
, "Multi-Topology IP6 reachability"},
169 { TLV_PTP_ADJ
, "Point-to-point Adjacency State"},
173 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
174 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
175 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
176 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
177 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
178 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
179 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
180 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
181 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
182 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
183 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
185 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
186 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
188 #define SUBTLV_AUTH_SIMPLE 1
189 #define SUBTLV_AUTH_MD5 54
190 #define SUBTLV_AUTH_MD5_LEN 16
191 #define SUBTLV_AUTH_PRIVATE 255
193 static struct tok isis_subtlv_auth_values
[] = {
194 { SUBTLV_AUTH_SIMPLE
, "simple text password"},
195 { SUBTLV_AUTH_MD5
, "HMAC-MD5 password"},
196 { SUBTLV_AUTH_PRIVATE
, "Routing Domain private password"},
200 #define SUBTLV_IDRP_RES 0
201 #define SUBTLV_IDRP_LOCAL 1
202 #define SUBTLV_IDRP_ASN 2
204 static struct tok isis_subtlv_idrp_values
[] = {
205 { SUBTLV_IDRP_RES
, "Reserved"},
206 { SUBTLV_IDRP_LOCAL
, "Routing-Domain Specific"},
207 { SUBTLV_IDRP_ASN
, "AS Number Tag"},
211 #define ISIS_8BIT_MASK(x) ((x)&0xff)
213 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
214 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
215 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
216 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
217 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
218 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
219 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
220 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
222 #define ISIS_MASK_MTID(x) ((x)&0xfff)
223 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
224 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
226 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
227 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
229 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
230 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
231 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
233 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
234 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
236 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
237 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
238 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
239 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
241 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
243 static const char *isis_gmpls_link_prot_values
[] = {
254 static struct tok isis_gmpls_sw_cap_values
[] = {
255 { 1, "Packet-Switch Capable-1"},
256 { 2, "Packet-Switch Capable-2"},
257 { 3, "Packet-Switch Capable-3"},
258 { 4, "Packet-Switch Capable-4"},
259 { 51, "Layer-2 Switch Capable"},
260 { 100, "Time-Division-Multiplex"},
261 { 150, "Lambda-Switch Capable"},
262 { 200, "Fiber-Switch Capable"},
266 static struct tok isis_gmpls_lsp_enc_values
[] = {
268 { 2, "Ethernet V2/DIX"},
271 { 5, "SDH ITU-T G.707"},
272 { 6, "SONET ANSI T1.105"},
273 { 7, "Digital Wrapper"},
274 { 8, "Lambda (photonic)"},
276 { 10, "Ethernet 802.3"},
277 { 11, "FiberChannel"},
281 static struct tok isis_mt_values
[] = {
282 { 0, "IPv4 unicast"},
283 { 1, "In-Band Management"},
284 { 2, "IPv6 unicast"},
286 { 4095, "Development, Experimental or Proprietary"},
290 static struct tok isis_iih_circuit_type_values
[] = {
291 { 1, "Level 1 only"},
292 { 2, "Level 2 only"},
293 { 3, "Level 1, Level 2"},
297 #define ISIS_LSP_TYPE_UNUSED0 0
298 #define ISIS_LSP_TYPE_LEVEL_1 1
299 #define ISIS_LSP_TYPE_UNUSED2 2
300 #define ISIS_LSP_TYPE_LEVEL_2 3
302 static struct tok isis_lsp_istype_values
[] = {
303 { ISIS_LSP_TYPE_UNUSED0
, "Unused 0x0 (invalid)"},
304 { ISIS_LSP_TYPE_LEVEL_1
, "L1 IS"},
305 { ISIS_LSP_TYPE_UNUSED2
, "Unused 0x2 (invalid)"},
306 { ISIS_LSP_TYPE_LEVEL_2
, "L1L2 IS"},
310 static struct tok isis_nlpid_values
[] = {
311 { NLPID_CLNS
, "CLNS"},
313 { NLPID_IP6
, "IPv6"},
318 * Katz's point to point adjacency TLV uses codes to tell us the state of
319 * the remote adjacency. Enumerate them.
322 #define ISIS_PTP_ADJ_UP 0
323 #define ISIS_PTP_ADJ_INIT 1
324 #define ISIS_PTP_ADJ_DOWN 2
327 static struct tok isis_ptp_adjancey_values
[] = {
328 { ISIS_PTP_ADJ_UP
, "Up" },
329 { ISIS_PTP_ADJ_INIT
, "Initializing" },
330 { ISIS_PTP_ADJ_DOWN
, "Down" },
334 struct isis_tlv_ptp_adj
{
335 u_char adjacency_state
;
336 u_char ext_local_circuit_id
[4];
337 u_char neighbor_sysid
[SYSTEM_ID_LEN
];
338 u_char neighbor_ext_local_circuit_id
[4];
341 static int osi_cksum(const u_char
*, u_int
);
342 static void esis_print(const u_char
*, u_int
);
343 static int isis_print(const u_char
*, u_int
);
345 struct isis_tlv_ip_reach
{
346 u_char metric_default
;
348 u_char metric_expense
;
354 struct isis_tlv_is_reach
{
355 u_char metric_default
;
357 u_char metric_expense
;
359 u_char neighbor_nodeid
[SYSTEM_ID_LEN
+1];
362 static struct tok isis_is_reach_virtual_values
[] = {
363 { 0, "IsNotVirtual"},
368 struct isis_common_header
{
371 u_char version
; /* Protocol version? */
373 u_char pdu_type
; /* 3 MSbs are reserved */
374 u_char pkt_version
; /* Packet format version? */
379 struct isis_iih_lan_header
{
381 u_char source_id
[SYSTEM_ID_LEN
];
382 u_char holding_time
[2];
385 u_char lan_id
[SYSTEM_ID_LEN
+1];
388 struct isis_iih_ptp_header
{
390 u_char source_id
[SYSTEM_ID_LEN
];
391 u_char holding_time
[2];
396 struct isis_lsp_header
{
398 u_char remaining_lifetime
[2];
399 u_char lsp_id
[SYSTEM_ID_LEN
+2];
400 u_char sequence_number
[4];
405 struct isis_csnp_header
{
407 u_char source_id
[SYSTEM_ID_LEN
+1];
408 u_char start_lsp_id
[SYSTEM_ID_LEN
+2];
409 u_char end_lsp_id
[SYSTEM_ID_LEN
+2];
412 struct isis_psnp_header
{
414 u_char source_id
[SYSTEM_ID_LEN
+1];
417 struct isis_tlv_lsp
{
418 u_char remaining_lifetime
[2];
419 u_char lsp_id
[SYSTEM_ID_LEN
+2];
420 u_char sequence_number
[4];
424 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
425 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
426 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
427 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
428 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
429 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
431 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
432 const u_char
*esrc
, const u_char
*edst
)
435 const struct isis_common_header
*header
;
437 header
= (const struct isis_common_header
*)p
;
438 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
441 printf("[|iso-clns] ");
442 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
444 etheraddr_string(esrc
),
445 etheraddr_string(edst
));
452 (void)printf("CLNS(%d)", length
);
453 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
454 (void)printf(", %s > %s",
455 etheraddr_string(esrc
),
456 etheraddr_string(edst
));
460 (void)printf("ESIS");
461 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
462 (void)printf(", %s > %s",
463 etheraddr_string(esrc
),
464 etheraddr_string(edst
));
465 esis_print(p
, length
);
469 (void)printf("ISIS(%d)", length
);
470 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
471 (void)printf(", %s > %s",
472 etheraddr_string(esrc
),
473 etheraddr_string(edst
));
474 if (!isis_print(p
, length
))
475 default_print_unaligned(p
, caplen
);
479 (void)printf("ISO NULLNS(%d)", length
);
480 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
481 (void)printf(", %s > %s",
482 etheraddr_string(esrc
),
483 etheraddr_string(edst
));
487 (void)printf("CLNS %02x(%d)", p
[0], length
);
488 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
489 (void)printf(", %s > %s",
490 etheraddr_string(esrc
),
491 etheraddr_string(edst
));
493 default_print_unaligned(p
, caplen
);
498 #define ESIS_REDIRECT 6
511 esis_print(const u_char
*p
, u_int length
)
515 const struct esis_hdr
*eh
;
521 printf(" no header at all!");
525 eh
= (const struct esis_hdr
*) &p
[2];
531 printf(" LI(%d) > PDU size (%d)!", li
, length
);
534 if (li
< sizeof(struct esis_hdr
) + 2) {
538 printf(" too short for esis header %d:", li
);
539 while (--length
!= 0)
540 printf("%02X", *p
++);
544 switch (eh
->type
& 0x1f) {
559 printf(" type %d", eh
->type
& 0x1f);
562 if (vflag
&& osi_cksum(p
, li
)) {
563 printf(" bad cksum (got 0x%02x%02x)",
564 eh
->cksum
[1], eh
->cksum
[0]);
565 default_print(p
, length
);
568 if (eh
->version
!= 1) {
569 printf(" unsupported version %d", eh
->version
);
572 p
+= sizeof(*eh
) + 2;
573 li
-= sizeof(*eh
) + 2; /* protoid * li */
575 switch (eh
->type
& 0x1f) {
576 case ESIS_REDIRECT
: {
577 const u_char
*dst
, *snpa
, *is
;
579 dst
= p
; p
+= *p
+ 1;
582 printf("\n\t\t\t %s", isonsap_string(dst
));
583 snpa
= p
; p
+= *p
+ 1;
592 printf(" > %s", etheraddr_string(&snpa
[1]));
594 printf(" > %s", isonsap_string(is
));
614 printf("\n\t\t\t %s", isonsap_string(is
));
620 (void)printf(" len=%d", length
);
621 if (length
&& p
< snapend
) {
622 length
= snapend
- p
;
623 default_print(p
, length
);
628 while (p
< ep
&& li
) {
635 printf(" bad opts/li");
642 printf(" opt (%d) too long", op
);
650 if (op
== 198 && opli
== 2) {
651 printf(" tmo=%d", q
[0] * 256 + q
[1]);
654 printf (" %d:<", op
);
656 printf("%02x", *q
++);
666 print_nsap(register const u_char
*cp
, register int length
)
670 for (i
= 0; i
< length
; i
++) {
673 printf("%02x", *cp
++);
674 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
681 char *isis_print_sysid (const u_char
*);
682 /* allocate space for the following string
684 * 14 bytes plus one termination byte */
687 isis_print_sysid(const u_char
*cp
)
692 for (i
= 1; i
<= 6; i
++) {
695 pos
+=sprintf(pos
, "%02x", *cp
++);
697 pos
+=sprintf(pos
, ".");
705 char *isis_print_nodeid (const u_char
*);
706 /* allocate space for the following string
708 * 17 bytes plus one termination byte */
711 isis_print_nodeid(const u_char
*cp
)
716 for (i
= 1; i
<= 7; i
++) {
719 pos
+=sprintf(pos
, "%02x", *cp
++);
721 pos
+=sprintf(pos
, ".");
728 char *isis_print_lspid (const u_char
*);
729 /* allocate space for the following string
730 * xxxx.xxxx.xxxx.yy-zz
731 * 20 bytes plus one termination byte */
734 isis_print_lspid(const u_char
*cp
)
739 for (i
= 1; i
<= 7; i
++) {
740 pos
+=sprintf(pos
, "%02x", *cp
++);
742 pos
+=sprintf(pos
, ".");
744 pos
+=sprintf(pos
, "-%02x", *cp
);
749 * this is a generic routine for printing unknown data;
750 * as it is called from various places (TLV and subTLV parsing routines)
751 * we pass on the linefeed plus indentation string to
752 * get a proper output - returns 0 on error
756 isis_print_unknown_data(const u_char
*cp
,const char *lf
,int len
)
760 printf("%s0x0000: ",lf
);
762 if (!TTEST2(*(cp
+i
), 1))
764 printf("%02x",*(cp
+i
));
767 if (i
/16!=(i
+1)/16) {
769 printf("%s0x%04x: ",lf
,i
);
772 return(1); /* everything is ok */
775 printf("%spacket exceeded snapshot",lf
);
781 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
783 u_int bitmasks
[33] = {
785 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
786 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
787 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
788 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
789 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
790 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
791 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
792 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
796 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
798 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
801 if (length
< sizeof(*tlv_ip_reach
)) {
802 printf("short IP reachability (%d vs %lu)", length
,
803 (unsigned long)sizeof(*tlv_ip_reach
));
807 if (!TTEST(*tlv_ip_reach
))
810 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
813 /* lets see if we can transform the mask into a prefixlen */
814 while (prefix_len
<= 33) {
815 if (bitmasks
[prefix_len
++] == mask
) {
822 * 34 indicates no match -> must be a discontiguous netmask
823 * lets dump the mask, otherwise print the prefix_len
825 if (prefix_len
== 34)
826 printf("\n\t\t\tIPv4 prefix: %s mask %s",
827 ipaddr_string((tlv_ip_reach
->prefix
)),
828 ipaddr_string((tlv_ip_reach
->mask
)));
830 printf("\n\t\t\tIPv4 prefix: %s/%u",
831 ipaddr_string((tlv_ip_reach
->prefix
)),
834 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
835 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_default
),
836 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_default
) ? "External" : "Internal",
837 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->metric_default
) ? "down" : "up");
839 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_delay
))
840 printf("\n\t\t\t Delay Metric: %02d, %s",
841 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_delay
),
842 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_delay
) ? "External" : "Internal");
844 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_expense
))
845 printf("\n\t\t\t Expense Metric: %02d, %s",
846 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_expense
),
847 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_expense
) ? "External" : "Internal");
849 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_error
))
850 printf("\n\t\t\t Error Metric: %02d, %s",
851 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_error
),
852 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_error
) ? "External" : "Internal");
854 length
-= sizeof(struct isis_tlv_ip_reach
);
861 * this is the common IP-REACH subTLV decoder it is called
862 * from various EXTD-IP REACH TLVs (135,235,236,237)
866 isis_print_ip_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
869 case SUBTLV_IP_REACH_ADMIN_TAG32
:
870 if (!TTEST2(*tptr
,4))
872 printf("%s32-Bit Administrative tag: 0x%08x",
874 EXTRACT_32BITS(tptr
));
876 case SUBTLV_IP_REACH_ADMIN_TAG64
:
877 if (!TTEST2(*tptr
,8))
879 printf("%s64-Bit Administrative tag: 0x%08x%08x",
881 EXTRACT_32BITS(tptr
),
882 EXTRACT_32BITS(tptr
+4));
885 printf("%sunknown subTLV, type %d, length %d",
889 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
897 printf("%spacket exceeded snapshot",lf
);
902 * this is the common IS-REACH subTLV decoder it is called
903 * from various EXTD-IS REACH TLVs (22,24,222)
907 isis_print_is_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
910 float bw
; /* copy buffer for several subTLVs */
913 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
914 if (!TTEST2(*tptr
,4))
916 printf("%sAdministrative groups: 0x%08x",
918 EXTRACT_32BITS(tptr
));
920 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
921 if (!TTEST2(*tptr
,4))
923 printf("%sLink Local Identifier: 0x%08x",
925 EXTRACT_32BITS(tptr
));
927 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
928 if (!TTEST2(*tptr
,4))
930 printf("%sLink Remote Identifier: 0x%08x",
932 EXTRACT_32BITS(tptr
));
934 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
935 if (!TTEST2(*tptr
,4))
937 j
= EXTRACT_32BITS(tptr
);
939 printf("%sMaximum link bandwidth : %.3f Mbps",
943 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
944 if (!TTEST2(*tptr
,4))
946 j
= EXTRACT_32BITS(tptr
);
948 printf("%sReservable link bandwidth: %.3f Mbps",
952 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
953 printf("%sUnreserved bandwidth:",lf
);
954 for (i
= 0; i
< 8; i
++) {
955 if (!TTEST2(*(tptr
+i
*4),4))
957 j
= EXTRACT_32BITS(tptr
);
959 printf("%s priority level %d: %.3f Mbps",
965 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
966 if (!TTEST2(*tptr
,3))
968 printf("%sTraffic Engineering Metric: %d",
970 EXTRACT_24BITS(tptr
));
972 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
973 if (!TTEST2(*tptr
,4))
975 printf("%sIPv4 interface address: %s",
977 ipaddr_string(tptr
));
979 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
980 if (!TTEST2(*tptr
,4))
982 printf("%sIPv4 neighbor address: %s",
984 ipaddr_string(tptr
));
986 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE
:
987 if (!TTEST2(*tptr
,2))
990 j
= (ISIS_8BIT_MASK(*tptr
)); /* fetch the typecode and make sure
991 that no high-order LSBs are set */
992 printf("%sLink Protection Type: %s",
995 /* scan through the bits until the typecode is zero */
997 printf("%s", isis_gmpls_link_prot_values
[i
]);
999 if (j
) /*any other bit set ?*/
1003 printf(", Priority %u", *(tptr
+1));
1005 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
1006 printf("%sInterface Switching Capability",lf
);
1008 if (!TTEST2(*tptr
,1))
1010 printf("%s Interface Switching Capability:%s",
1012 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1014 if (!TTEST2(*(tptr
+1),1))
1016 printf(", LSP Encoding: %s",
1017 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1019 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1022 printf("%s Max LSP Bandwidth:",lf
);
1023 for (i
= 0; i
< 8; i
++) {
1024 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1026 j
= EXTRACT_32BITS(tptr
);
1027 memcpy (&bw
, &j
, 4);
1028 printf("%s priority level %d: %.3f Mbps",
1034 /* there is some optional stuff left to decode but this is as of yet
1035 not specified so just lets hexdump what is left */
1037 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1047 printf("%sReserved for cisco specific extensions, type %d, length %d",
1053 printf("%sReserved for future expansion, type %d, length %d",
1059 printf("%sunknown subTLV, type %d, length %d",
1063 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1071 printf("%spacket exceeded snapshot",lf
);
1078 * Decode IS-IS packets. Return 0 on error.
1081 static int isis_print (const u_char
*p
, u_int length
)
1083 const struct isis_common_header
*header
;
1085 const struct isis_iih_lan_header
*header_iih_lan
;
1086 const struct isis_iih_ptp_header
*header_iih_ptp
;
1087 const struct isis_lsp_header
*header_lsp
;
1088 const struct isis_csnp_header
*header_csnp
;
1089 const struct isis_psnp_header
*header_psnp
;
1091 const struct isis_tlv_lsp
*tlv_lsp
;
1092 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1093 const struct isis_tlv_is_reach
*tlv_is_reach
;
1095 u_char pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, subl
, subt
, tslen
;
1096 const u_char
*optr
, *pptr
, *tptr
;
1097 u_short packet_len
,pdu_len
,time_remain
;
1098 u_int i
,j
,bit_length
,byte_length
,metric
,ra
,rr
;
1099 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
1101 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
1104 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1105 need it for parsing the checksum TLV */
1106 header
= (const struct isis_common_header
*)p
;
1108 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1109 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1110 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1111 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1112 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1113 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1116 * Sanity checking of the header.
1118 if (header
->nlpid
!= NLPID_ISIS
) {
1119 printf(", coding error!");
1123 if (header
->version
!= ISIS_VERSION
) {
1124 printf(", version %d packet not supported", header
->version
);
1128 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1129 printf(", system ID length of %d is not supported",
1134 if (header
->pkt_version
!= ISIS_VERSION
) {
1135 printf(", version %d packet not supported", header
->pkt_version
);
1139 max_area
= header
->max_area
;
1142 max_area
= 3; /* silly shit */
1145 printf(", bad packet -- 255 areas");
1151 id_length
= header
->id_length
;
1154 id_length
= 6; /* silly shit again */
1156 case 1: /* 1-8 are valid sys-ID lenghts */
1166 id_length
= 0; /* entirely useless */
1169 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1174 printf(", hlen: %u, v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1182 pdu_type
=header
->pdu_type
;
1184 /* first lets see if we know the PDU name*/
1186 tok2str(isis_pdu_values
,
1187 "unknown PDU, type %d",
1194 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1195 printf(", bogus fixed header length %u should be %lu",
1196 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1200 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1201 if (packet_len
>pdu_len
) {
1202 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1206 TCHECK(*header_iih_lan
);
1207 printf("\n\t\t source-id: %s, holding time: %u, %s",
1208 isis_print_sysid(header_iih_lan
->source_id
),
1209 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1210 tok2str(isis_iih_circuit_type_values
,
1211 "unknown circuit type 0x%02x",
1212 header_iih_lan
->circuit_type
));
1214 printf("\n\t\t lan-id: %s, Priority: %u, PDU length: %u",
1215 isis_print_nodeid(header_iih_lan
->lan_id
),
1216 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1219 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1220 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1224 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1225 printf(", bogus fixed header length %u should be %lu",
1226 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1230 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
1231 if (packet_len
>pdu_len
) {
1232 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1236 TCHECK(*header_iih_ptp
);
1237 printf("\n\t\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1238 isis_print_sysid(header_iih_ptp
->source_id
),
1239 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1240 header_iih_ptp
->circuit_id
,
1241 tok2str(isis_iih_circuit_type_values
,
1242 "unknown circuit type 0x%02x",
1243 header_iih_ptp
->circuit_type
),
1246 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1247 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1252 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1253 printf(", bogus fixed header length %u should be %lu",
1254 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1258 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1259 if (packet_len
>pdu_len
) {
1260 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1264 TCHECK(*header_lsp
);
1265 printf("\n\t\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1266 isis_print_lspid(header_lsp
->lsp_id
),
1267 EXTRACT_32BITS(header_lsp
->sequence_number
),
1268 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1269 /* verify the checksum -
1270 * checking starts at the lsp-id field
1271 * which is 12 bytes after the packet start*/
1272 printf("\n\t\t chksum: 0x%04x (%s), PDU length: %u",
1273 EXTRACT_16BITS(header_lsp
->checksum
),
1274 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1277 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1279 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1280 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1281 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1282 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1283 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1284 printf("ATT bit set, ");
1286 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1287 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1289 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1290 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1295 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1296 printf(", bogus fixed header length %u should be %lu",
1297 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1301 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
1302 if (packet_len
>pdu_len
) {
1303 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1307 TCHECK(*header_csnp
);
1308 printf("\n\t\t source-id: %s, PDU length: %u",
1309 isis_print_nodeid(header_csnp
->source_id
),
1311 printf("\n\t\t start lsp-id: %s",
1312 isis_print_lspid(header_csnp
->start_lsp_id
));
1313 printf("\n\t\t end lsp-id: %s",
1314 isis_print_lspid(header_csnp
->end_lsp_id
));
1316 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1317 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1322 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1323 printf("- bogus fixed header length %u should be %lu",
1324 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1328 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1329 if (packet_len
>pdu_len
) {
1330 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1334 TCHECK(*header_psnp
);
1335 printf("\n\t\t source-id: %s",
1336 isis_print_nodeid(header_psnp
->source_id
));
1338 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1339 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1343 if(!isis_print_unknown_data(pptr
,"\n\t\t ",length
))
1349 * Now print the TLV's.
1352 while (packet_len
>= 2) {
1353 if (pptr
== snapend
) {
1357 if (!TTEST2(*pptr
, 2)) {
1358 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
1359 (long)(pptr
-snapend
));
1364 tmp
=len
; /* copy temporary len & pointer to packet data */
1367 if (len
> packet_len
) {
1371 /* first lets see if we know the TLVs name*/
1372 printf("\n\t\t %s TLV #%u, length: %u",
1373 tok2str(isis_tlv_values
,
1379 /* now check if we have a decoder otherwise do a hexdump at the end*/
1382 if (!TTEST2(*tptr
, 1))
1385 while (tmp
&& alen
< tmp
) {
1386 printf("\n\t\t\tArea address (%u): ",alen
);
1387 if (!print_nsap(tptr
, alen
))
1391 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1393 if (!TTEST2(*tptr
, 1))
1399 while (tmp
>= ETHER_ADDR_LEN
) {
1400 printf("\n\t\t\tIS Neighbor: %s",isis_print_sysid(tptr
));
1401 tmp
-= ETHER_ADDR_LEN
;
1402 tptr
+= ETHER_ADDR_LEN
;
1409 case TLV_MT_IS_REACH
:
1411 if (!TTEST2(*tptr
, 2))
1413 printf("\n\t\t\t%s",
1414 tok2str(isis_mt_values
,
1415 "Reserved for IETF Consensus",
1416 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1418 printf(" Topology (0x%03x)",
1419 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1421 printf("\n\t\t\t IS Neighbor: %s", isis_print_nodeid(tptr
));
1422 tptr
+=(SYSTEM_ID_LEN
+1);
1423 if (!TTEST2(*tptr
, 3))
1425 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1427 if (!TTEST2(*tptr
, 1))
1430 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1432 printf(" (%u)",tslen
);
1434 if (!TTEST2(*tptr
,2))
1438 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1445 tmp
-=(SYSTEM_ID_LEN
+7);
1449 case TLV_EXT_IS_REACH
:
1451 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
+1))
1453 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1454 tptr
+=(SYSTEM_ID_LEN
+1);
1456 if (!TTEST2(*tptr
, 3))
1458 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1461 if (!TTEST2(*tptr
, 1))
1463 tslen
=*(tptr
++); /* read out subTLV length */
1464 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1466 printf(" (%u)",tslen
);
1468 if (!TTEST2(*tptr
,2))
1472 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1479 tmp
-=(SYSTEM_ID_LEN
+5);
1483 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1486 printf("\n\t\t\t%s",
1487 tok2str(isis_is_reach_virtual_values
,
1488 "bogus virtual flag 0x%02x",
1491 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1493 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1494 if (!TTEST(*tlv_is_reach
))
1497 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1498 printf(", Default Metric: %d, %s",
1499 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_default
),
1500 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_default
) ? "External" : "Internal");
1502 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_delay
))
1503 printf("\n\t\t\t Delay Metric: %d, %s",
1504 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_delay
),
1505 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_delay
) ? "External" : "Internal");
1507 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_expense
))
1508 printf("\n\t\t\t Expense Metric: %d, %s",
1509 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_expense
),
1510 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_expense
) ? "External" : "Internal");
1512 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_error
))
1513 printf("\n\t\t\t Error Metric: %d, %s",
1514 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_error
),
1515 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_error
) ? "External" : "Internal");
1517 tmp
-= sizeof(struct isis_tlv_is_reach
);
1522 /* those two TLVs share the same format */
1524 case TLV_IP_REACH_EXT
:
1525 if (!isis_print_tlv_ip_reach(pptr
, len
))
1529 case TLV_MT_IP_REACH
:
1531 if (!TTEST2(*tptr
, 2))
1534 printf("\n\t\t\t%s",
1535 tok2str(isis_mt_values
,
1536 "Reserved for IETF Consensus",
1537 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1539 printf(" Topology (0x%03x)",
1540 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1543 memset (prefix
, 0, 4);
1544 if (!TTEST2(*tptr
, 4))
1546 metric
= EXTRACT_32BITS(tptr
);
1549 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1552 bit_length
= (*(tptr
)++&0x3f);
1553 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1555 if (!TTEST2(*tptr
, byte_length
))
1557 memcpy(prefix
,tptr
,byte_length
);
1559 printf("\n\t\t\tIPv4 prefix: %s/%d",
1560 ipaddr_string(prefix
),
1563 printf("\n\t\t\t Metric: %u, Distribution: %s",
1565 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1567 printf(", %ssub-TLVs present",
1568 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1570 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1571 /* assume that one prefix can hold more
1572 than one subTLV - therefore the first byte must reflect
1573 the aggregate bytecount of the subTLVs for this prefix
1575 if (!TTEST2(*tptr
, 1))
1579 printf(" (%u)",tslen
); /* print out subTLV length */
1582 if (!TTEST2(*tptr
,2))
1586 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1593 tmp
-=(7+byte_length
);
1597 case TLV_EXT_IP_REACH
:
1599 memset (prefix
, 0, 4);
1600 if (!TTEST2(*tptr
, 4))
1602 metric
= EXTRACT_32BITS(tptr
);
1605 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1608 bit_length
= (*(tptr
)++&0x3f);
1609 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1611 if (!TTEST2(*tptr
, byte_length
))
1613 memcpy(prefix
,tptr
,byte_length
);
1615 printf("\n\t\t\tIPv4 prefix: %s/%d",
1616 ipaddr_string(prefix
),
1619 printf("\n\t\t\t Metric: %u, Distribution: %s",
1621 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1623 printf(", %ssub-TLVs present",
1624 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1626 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1627 /* assume that one prefix can hold more
1628 than one subTLV - therefore the first byte must reflect
1629 the aggregate bytecount of the subTLVs for this prefix
1631 if (!TTEST2(*tptr
, 1))
1635 printf(" (%u)",tslen
); /* print out subTLV length */
1638 if (!TTEST2(*tptr
,2))
1642 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1649 tmp
-=(5+byte_length
);
1657 if (!TTEST2(*tptr
, 4))
1659 metric
= EXTRACT_32BITS(tptr
);
1662 if (!TTEST2(*tptr
, 2))
1665 bit_length
= (*(tptr
)++);
1666 byte_length
= (bit_length
+ 7) / 8;
1667 if (!TTEST2(*tptr
, byte_length
))
1670 memset(prefix6
, 0, 16);
1671 memcpy(prefix6
,tptr
,byte_length
);
1673 printf("\n\t\t\tIPv6 prefix: %s/%u",
1674 ip6addr_string(prefix6
),
1677 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1679 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1680 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1681 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1683 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1684 /* assume that one prefix can hold more
1685 than one subTLV - therefore the first byte must reflect
1686 the aggregate bytecount of the subTLVs for this prefix
1688 if (!TTEST2(*tptr
, 1))
1692 printf(" (%u)",tslen
); /* print out subTLV length */
1695 if (!TTEST2(*tptr
,2))
1699 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1706 tmp
-=(6+byte_length
);
1715 if (!TTEST2(*tptr
, 16))
1718 printf("\n\t\t\tIPv6 interface address: %s",
1719 ip6addr_string(tptr
));
1727 if (!TTEST2(*tptr
, 1))
1730 printf("\n\t\t\t%s: ",
1731 tok2str(isis_subtlv_auth_values
,
1732 "unknown Authentication type 0x%02x",
1736 case SUBTLV_AUTH_SIMPLE
:
1737 for(i
=1;i
<len
;i
++) {
1738 if (!TTEST2(*(tptr
+i
), 1))
1740 printf("%c",*(tptr
+i
));
1743 case SUBTLV_AUTH_MD5
:
1744 for(i
=1;i
<len
;i
++) {
1745 if (!TTEST2(*(tptr
+i
), 1))
1747 printf("%02x",*(tptr
+i
));
1749 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1750 printf(", (malformed subTLV) ");
1752 case SUBTLV_AUTH_PRIVATE
:
1754 if(!isis_print_unknown_data(tptr
+1,"\n\t\t\t ",len
-1))
1761 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1763 if (!TTEST2(*tptr
, 1))
1765 printf("\n\t\t\tAdjacency State: %s",
1766 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1770 if (!TTEST2(tlv_ptp_adj
->ext_local_circuit_id
, 4))
1772 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1773 EXTRACT_32BITS(tlv_ptp_adj
->ext_local_circuit_id
));
1777 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, 6))
1779 printf("\n\t\t\tNeighbor SystemID: %s",
1780 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
));
1784 if (!TTEST2(tlv_ptp_adj
->neighbor_ext_local_circuit_id
, 4))
1786 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1787 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_ext_local_circuit_id
));
1792 printf("\n\t\t\tNLPID(s): ");
1794 if (!TTEST2(*(tptr
), 1))
1797 tok2str(isis_nlpid_values
,
1800 if (tmp
>1) /* further NPLIDs ? - put comma */
1806 case TLV_TE_ROUTER_ID
:
1807 if (!TTEST2(*pptr
, 4))
1809 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1814 if (!TTEST2(*tptr
, 4))
1816 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1823 printf("\n\t\t\tHostname: ");
1825 if (!TTEST2(*tptr
, 1))
1827 printf("%c",*tptr
++);
1832 case TLV_SHARED_RISK_GROUP
:
1833 if (!TTEST2(*tptr
, 7))
1835 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1836 tptr
+=(SYSTEM_ID_LEN
+1);
1837 len
-=(SYSTEM_ID_LEN
+1);
1839 if (!TTEST2(*tptr
, 1))
1841 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1844 if (!TTEST2(*tptr
,4))
1846 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1850 if (!TTEST2(*tptr
,4))
1852 printf("\n\t\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1857 if (!TTEST2(*tptr
, 4))
1859 printf("\n\t\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1866 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1868 printf("\n\t\t\tlsp-id: %s",
1869 isis_print_nodeid(tlv_lsp
->lsp_id
));
1870 if (!TTEST((tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]))
1872 printf("-%02x",(tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]);
1873 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1875 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1876 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1878 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1879 if (!TTEST2(tlv_lsp
->checksum
, 2))
1881 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1882 tmp
-=sizeof(struct isis_tlv_lsp
);
1888 if (!TTEST2(*tptr
, 2))
1890 printf("\n\t\t\tchecksum: 0x%04x (%s)",
1891 EXTRACT_16BITS(tptr
),
1892 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1895 case TLV_MT_SUPPORTED
:
1897 /* length can only be a multiple of 2, otherwise there is
1898 something broken -> so decode down until length is 1 */
1900 if (!TTEST2(*tptr
, 2))
1902 printf("\n\t\t\t%s",
1903 tok2str(isis_mt_values
,
1904 "Reserved for IETF Consensus",
1905 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1907 printf(" Topology (0x%03x)%s%s",
1908 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1909 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1910 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1912 printf("\n\t\t\tmalformed MT-ID");
1920 case TLV_RESTART_SIGNALING
:
1921 if (!TTEST2(*tptr
, 3))
1923 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1924 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1926 time_remain
= EXTRACT_16BITS(tptr
);
1927 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1928 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
1932 if (!TTEST2(*tptr
, 1))
1934 printf("\n\t\t\tInter-Domain Information Type: %s",
1935 tok2str(isis_subtlv_idrp_values
,
1939 case SUBTLV_IDRP_ASN
:
1940 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
1942 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
1944 case SUBTLV_IDRP_LOCAL
:
1945 case SUBTLV_IDRP_RES
:
1947 if(!isis_print_unknown_data(tptr
,"\n\t\t\t",len
-1))
1954 * FIXME those are the defined TLVs that lack a decoder
1955 * you are welcome to contribute code ;-)
1961 case TLV_LSP_BUFFERSIZE
:
1962 case TLV_IS_ALIAS_ID
:
1963 case TLV_DECNET_PHASE4
:
1964 case TLV_LUCENT_PRIVATE
:
1966 case TLV_NORTEL_PRIVATE1
:
1967 case TLV_NORTEL_PRIVATE2
:
1968 case TLV_MT_IP6_REACH
:
1971 if(!isis_print_unknown_data(pptr
,"\n\t\t\t",len
))
1980 if (packet_len
!= 0) {
1981 printf("\n\t\t\t %d straggler bytes", packet_len
);
1986 fputs("[|isis]", stdout
);
1990 printf("\n\t\t\t packet exceeded snapshot");
1995 * Verify the checksum. See 8473-1, Appendix C, section C.4.
1999 osi_cksum(const u_char
*tptr
, u_int len
)
2001 int32_t c0
= 0, c1
= 0;
2003 while ((int)--len
>= 0) {