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.50 2002-05-31 23:23:35 hannes 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 NODE_ID_LEN SYSTEM_ID_LEN+1
64 #define LSP_ID_LEN SYSTEM_ID_LEN+2
66 #define ISIS_VERSION 1
67 #define PDU_TYPE_MASK 0x1F
68 #define PRIORITY_MASK 0x7F
80 static struct tok isis_pdu_values
[] = {
81 { L1_LAN_IIH
, "L1 Lan IIH"},
82 { L2_LAN_IIH
, "L2 Lan IIH"},
83 { PTP_IIH
, "p2p IIH"},
86 { L1_CSNP
, "L1 CSNP"},
87 { L2_CSNP
, "L2 CSNP"},
88 { L1_PSNP
, "L1 PSNP"},
89 { L2_PSNP
, "L2 PSNP"},
94 * A TLV is a tuple of a type, length and a value and is normally used for
95 * encoding information in all sorts of places. This is an enumeration of
96 * the well known types.
98 * list taken from draft-ietf-isis-wg-tlv-codepoints-01.txt
101 #define TLV_AREA_ADDR 1
102 #define TLV_IS_REACH 2
103 #define TLV_ESNEIGH 3
104 #define TLV_PART_DIS 4
105 #define TLV_PREFIX_NEIGH 5
106 #define TLV_ISNEIGH 6
107 #define TLV_ISNEIGH_VARLEN 7
108 #define TLV_PADDING 8
111 #define TLV_CHECKSUM 12
112 #define TLV_LSP_BUFFERSIZE 14
113 #define TLV_EXT_IS_REACH 22
114 #define TLV_IS_ALIAS_ID 24
115 #define TLV_DECNET_PHASE4 42
116 #define TLV_LUCENT_PRIVATE 66
117 #define TLV_IP_REACH 128
118 #define TLV_PROTOCOLS 129
119 #define TLV_IP_REACH_EXT 130
120 #define TLV_IDRP_INFO 131
121 #define TLV_IPADDR 132
122 #define TLV_IPAUTH 133
123 #define TLV_TE_ROUTER_ID 134
124 #define TLV_EXT_IP_REACH 135
125 #define TLV_HOSTNAME 137
126 #define TLV_SHARED_RISK_GROUP 138
127 #define TLV_NORTEL_PRIVATE1 176
128 #define TLV_NORTEL_PRIVATE2 177
129 #define TLV_RESTART_SIGNALING 211
130 #define TLV_MT_IS_REACH 222
131 #define TLV_MT_SUPPORTED 229
132 #define TLV_IP6ADDR 232
133 #define TLV_MT_IP_REACH 235
134 #define TLV_IP6_REACH 236
135 #define TLV_MT_IP6_REACH 237
136 #define TLV_PTP_ADJ 240
138 static struct tok isis_tlv_values
[] = {
139 { TLV_AREA_ADDR
, "Area address(es)"},
140 { TLV_IS_REACH
, "IS Reachability"},
141 { TLV_ESNEIGH
, "ES Neighbor(s)"},
142 { TLV_PART_DIS
, "Partition DIS"},
143 { TLV_PREFIX_NEIGH
, "Prefix Neighbors"},
144 { TLV_ISNEIGH
, "IS Neighbor(s)"},
145 { TLV_ISNEIGH_VARLEN
, "IS Neighbor(s) (variable length)"},
146 { TLV_PADDING
, "Padding"},
147 { TLV_LSP
, "LSP entries"},
148 { TLV_AUTH
, "Authentication"},
149 { TLV_CHECKSUM
, "Checksum"},
150 { TLV_LSP_BUFFERSIZE
, "LSP Buffersize"},
151 { TLV_EXT_IS_REACH
, "Extended IS Reachability"},
152 { TLV_IS_ALIAS_ID
, "IS Alias ID"},
153 { TLV_DECNET_PHASE4
, "DECnet Phase IV"},
154 { TLV_LUCENT_PRIVATE
, "Lucent Proprietary"},
155 { TLV_IP_REACH
, "IPv4 Internal reachability"},
156 { TLV_PROTOCOLS
, "Protocols supported"},
157 { TLV_IP_REACH_EXT
, "IPv4 External reachability"},
158 { TLV_IDRP_INFO
, "Inter-Domain Information Type"},
159 { TLV_IPADDR
, "IPv4 Interface address(es)"},
160 { TLV_IPAUTH
, "IPv4 authentication (deprecated)"},
161 { TLV_TE_ROUTER_ID
, "Traffic Engineering Router ID"},
162 { TLV_EXT_IP_REACH
, "Extended IPv4 reachability"},
163 { TLV_HOSTNAME
, "Hostname"},
164 { TLV_SHARED_RISK_GROUP
, "Shared Risk Link Group"},
165 { TLV_NORTEL_PRIVATE1
, "Nortel Proprietary"},
166 { TLV_NORTEL_PRIVATE2
, "Nortel Proprietary"},
167 { TLV_RESTART_SIGNALING
, "Restart Signaling"},
168 { TLV_MT_IS_REACH
, "Multi Topology IS Reachability"},
169 { TLV_MT_SUPPORTED
, "Multi Topology"},
170 { TLV_IP6ADDR
, "IPv6 Interface address(es)"},
171 { TLV_MT_IP_REACH
, "Multi-Topology IPv4 reachability"},
172 { TLV_IP6_REACH
, "IPv6 reachability"},
173 { TLV_MT_IP6_REACH
, "Multi-Topology IP6 reachability"},
174 { TLV_PTP_ADJ
, "Point-to-point Adjacency State"},
178 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
179 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
180 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
181 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
182 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
183 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
184 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
185 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
186 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
187 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
188 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
190 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
191 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
193 #define SUBTLV_AUTH_SIMPLE 1
194 #define SUBTLV_AUTH_MD5 54
195 #define SUBTLV_AUTH_MD5_LEN 16
196 #define SUBTLV_AUTH_PRIVATE 255
198 static struct tok isis_subtlv_auth_values
[] = {
199 { SUBTLV_AUTH_SIMPLE
, "simple text password"},
200 { SUBTLV_AUTH_MD5
, "HMAC-MD5 password"},
201 { SUBTLV_AUTH_PRIVATE
, "Routing Domain private password"},
205 #define SUBTLV_IDRP_RES 0
206 #define SUBTLV_IDRP_LOCAL 1
207 #define SUBTLV_IDRP_ASN 2
209 static struct tok isis_subtlv_idrp_values
[] = {
210 { SUBTLV_IDRP_RES
, "Reserved"},
211 { SUBTLV_IDRP_LOCAL
, "Routing-Domain Specific"},
212 { SUBTLV_IDRP_ASN
, "AS Number Tag"},
216 #define ISIS_8BIT_MASK(x) ((x)&0xff)
218 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
219 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
220 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
221 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
222 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
223 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
224 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
225 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
227 #define ISIS_MASK_MTID(x) ((x)&0xfff)
228 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
229 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
231 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
232 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
234 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
235 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
236 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
238 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
239 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
241 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
242 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
243 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
244 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
246 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
248 static const char *isis_gmpls_link_prot_values
[] = {
259 static struct tok isis_gmpls_sw_cap_values
[] = {
260 { 1, "Packet-Switch Capable-1"},
261 { 2, "Packet-Switch Capable-2"},
262 { 3, "Packet-Switch Capable-3"},
263 { 4, "Packet-Switch Capable-4"},
264 { 51, "Layer-2 Switch Capable"},
265 { 100, "Time-Division-Multiplex"},
266 { 150, "Lambda-Switch Capable"},
267 { 200, "Fiber-Switch Capable"},
271 static struct tok isis_gmpls_lsp_enc_values
[] = {
273 { 2, "Ethernet V2/DIX"},
276 { 5, "SDH ITU-T G.707"},
277 { 6, "SONET ANSI T1.105"},
278 { 7, "Digital Wrapper"},
279 { 8, "Lambda (photonic)"},
281 { 10, "Ethernet 802.3"},
282 { 11, "FiberChannel"},
286 static struct tok isis_mt_values
[] = {
287 { 0, "IPv4 unicast"},
288 { 1, "In-Band Management"},
289 { 2, "IPv6 unicast"},
291 { 4095, "Development, Experimental or Proprietary"},
295 static struct tok isis_iih_circuit_type_values
[] = {
296 { 1, "Level 1 only"},
297 { 2, "Level 2 only"},
298 { 3, "Level 1, Level 2"},
302 #define ISIS_LSP_TYPE_UNUSED0 0
303 #define ISIS_LSP_TYPE_LEVEL_1 1
304 #define ISIS_LSP_TYPE_UNUSED2 2
305 #define ISIS_LSP_TYPE_LEVEL_2 3
307 static struct tok isis_lsp_istype_values
[] = {
308 { ISIS_LSP_TYPE_UNUSED0
, "Unused 0x0 (invalid)"},
309 { ISIS_LSP_TYPE_LEVEL_1
, "L1 IS"},
310 { ISIS_LSP_TYPE_UNUSED2
, "Unused 0x2 (invalid)"},
311 { ISIS_LSP_TYPE_LEVEL_2
, "L1L2 IS"},
315 static struct tok isis_nlpid_values
[] = {
316 { NLPID_CLNS
, "CLNS"},
318 { NLPID_IP6
, "IPv6"},
323 * Katz's point to point adjacency TLV uses codes to tell us the state of
324 * the remote adjacency. Enumerate them.
327 #define ISIS_PTP_ADJ_UP 0
328 #define ISIS_PTP_ADJ_INIT 1
329 #define ISIS_PTP_ADJ_DOWN 2
332 static struct tok isis_ptp_adjancey_values
[] = {
333 { ISIS_PTP_ADJ_UP
, "Up" },
334 { ISIS_PTP_ADJ_INIT
, "Initializing" },
335 { ISIS_PTP_ADJ_DOWN
, "Down" },
339 struct isis_tlv_ptp_adj
{
340 u_char adjacency_state
;
341 u_char extd_local_circuit_id
[4];
342 u_char neighbor_sysid
[SYSTEM_ID_LEN
];
343 u_char neighbor_extd_local_circuit_id
[4];
346 static int osi_cksum(const u_char
*, u_int
);
347 static void esis_print(const u_char
*, u_int
);
348 static int isis_print(const u_char
*, u_int
);
350 struct isis_metric_block
{
351 u_char metric_default
;
353 u_char metric_expense
;
357 struct isis_tlv_is_reach
{
358 struct isis_metric_block isis_metric_block
;
359 u_char neighbor_nodeid
[NODE_ID_LEN
];
362 struct isis_tlv_es_reach
{
363 struct isis_metric_block isis_metric_block
;
364 u_char neighbor_sysid
[SYSTEM_ID_LEN
];
367 struct isis_tlv_ip_reach
{
368 struct isis_metric_block isis_metric_block
;
373 static struct tok isis_is_reach_virtual_values
[] = {
374 { 0, "IsNotVirtual"},
379 struct isis_common_header
{
382 u_char version
; /* Protocol version? */
384 u_char pdu_type
; /* 3 MSbs are reserved */
385 u_char pkt_version
; /* Packet format version? */
390 struct isis_iih_lan_header
{
392 u_char source_id
[SYSTEM_ID_LEN
];
393 u_char holding_time
[2];
396 u_char lan_id
[NODE_ID_LEN
];
399 struct isis_iih_ptp_header
{
401 u_char source_id
[SYSTEM_ID_LEN
];
402 u_char holding_time
[2];
407 struct isis_lsp_header
{
409 u_char remaining_lifetime
[2];
410 u_char lsp_id
[LSP_ID_LEN
];
411 u_char sequence_number
[4];
416 struct isis_csnp_header
{
418 u_char source_id
[NODE_ID_LEN
];
419 u_char start_lsp_id
[LSP_ID_LEN
];
420 u_char end_lsp_id
[LSP_ID_LEN
];
423 struct isis_psnp_header
{
425 u_char source_id
[NODE_ID_LEN
];
428 struct isis_tlv_lsp
{
429 u_char remaining_lifetime
[2];
430 u_char lsp_id
[LSP_ID_LEN
];
431 u_char sequence_number
[4];
435 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
436 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
437 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
438 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
439 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
440 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
442 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
443 const u_char
*esrc
, const u_char
*edst
)
446 const struct isis_common_header
*header
;
448 header
= (const struct isis_common_header
*)p
;
449 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
452 printf("[|iso-clns] ");
453 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
455 etheraddr_string(esrc
),
456 etheraddr_string(edst
));
463 (void)printf("CLNS(%d)", length
);
464 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
465 (void)printf(", %s > %s",
466 etheraddr_string(esrc
),
467 etheraddr_string(edst
));
471 (void)printf("ESIS");
472 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
473 (void)printf(", %s > %s",
474 etheraddr_string(esrc
),
475 etheraddr_string(edst
));
476 esis_print(p
, length
);
480 (void)printf("ISIS(%d)", length
);
481 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
482 (void)printf(", %s > %s",
483 etheraddr_string(esrc
),
484 etheraddr_string(edst
));
485 if (!isis_print(p
, length
))
486 default_print_unaligned(p
, caplen
);
490 (void)printf("ISO NULLNS(%d)", length
);
491 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
492 (void)printf(", %s > %s",
493 etheraddr_string(esrc
),
494 etheraddr_string(edst
));
498 (void)printf("CLNS %02x(%d)", p
[0], length
);
499 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
500 (void)printf(", %s > %s",
501 etheraddr_string(esrc
),
502 etheraddr_string(edst
));
504 default_print_unaligned(p
, caplen
);
509 #define ESIS_REDIRECT 6
522 esis_print(const u_char
*p
, u_int length
)
526 const struct esis_hdr
*eh
;
532 printf(" no header at all!");
536 eh
= (const struct esis_hdr
*) &p
[2];
542 printf(" LI(%d) > PDU size (%d)!", li
, length
);
545 if (li
< sizeof(struct esis_hdr
) + 2) {
549 printf(" too short for esis header %d:", li
);
550 while (--length
!= 0)
551 printf("%02X", *p
++);
555 switch (eh
->type
& 0x1f) {
570 printf(" type %d", eh
->type
& 0x1f);
573 if (vflag
&& osi_cksum(p
, li
)) {
574 printf(" bad cksum (got 0x%02x%02x)",
575 eh
->cksum
[1], eh
->cksum
[0]);
576 default_print(p
, length
);
579 if (eh
->version
!= 1) {
580 printf(" unsupported version %d", eh
->version
);
583 p
+= sizeof(*eh
) + 2;
584 li
-= sizeof(*eh
) + 2; /* protoid * li */
586 switch (eh
->type
& 0x1f) {
587 case ESIS_REDIRECT
: {
588 const u_char
*dst
, *snpa
, *is
;
590 dst
= p
; p
+= *p
+ 1;
593 printf("\n\t\t\t %s", isonsap_string(dst
));
594 snpa
= p
; p
+= *p
+ 1;
603 printf(" > %s", etheraddr_string(&snpa
[1]));
605 printf(" > %s", isonsap_string(is
));
625 printf("\n\t\t\t %s", isonsap_string(is
));
631 (void)printf(" len=%d", length
);
632 if (length
&& p
< snapend
) {
633 length
= snapend
- p
;
634 default_print(p
, length
);
639 while (p
< ep
&& li
) {
646 printf(" bad opts/li");
653 printf(" opt (%d) too long", op
);
661 if (op
== 198 && opli
== 2) {
662 printf(" tmo=%d", q
[0] * 256 + q
[1]);
665 printf (" %d:<", op
);
667 printf("%02x", *q
++);
672 /* allocate space for the following string
673 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
674 * 32 bytes plus one termination byte */
676 print_nsap(register const u_char
*cp
, register int length
)
679 static char nsap
[33];
688 for (i
= 0; i
< length
; i
++) {
691 pos
+=sprintf(pos
, "%02x", *cp
++);
692 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
693 pos
+=sprintf(pos
, ".");
700 /* allocate space for the following string
702 * 14 bytes plus one termination byte */
704 isis_print_sysid(const u_char
*cp
, int sysid_len
)
707 static char sysid
[15];
710 for (i
= 1; i
<= sysid_len
; i
++) {
713 pos
+=sprintf(pos
, "%02x", *cp
++);
715 pos
+=sprintf(pos
, ".");
723 /* allocate space for the following string
725 * 17 bytes plus one termination byte */
727 isis_print_nodeid(const u_char
*cp
)
730 static char nodeid
[18];
733 for (i
= 1; i
<= 7; i
++) {
736 pos
+=sprintf(pos
, "%02x", *cp
++);
738 pos
+=sprintf(pos
, ".");
745 /* allocate space for the following string
746 * xxxx.xxxx.xxxx.yy-zz
747 * 20 bytes plus one termination byte */
749 isis_print_lspid(const u_char
*cp
)
752 static char lspid
[21];
755 for (i
= 1; i
<= 7; i
++) {
756 pos
+=sprintf(pos
, "%02x", *cp
++);
758 pos
+=sprintf(pos
, ".");
760 pos
+=sprintf(pos
, "-%02x", *cp
);
765 * this is a generic routine for printing unknown data;
766 * as it is called from various places (TLV and subTLV parsing routines)
767 * we pass on the linefeed plus indentation string to
768 * get a proper output - returns 0 on error
772 isis_print_unknown_data(const u_char
*cp
,const char *lf
,int len
)
776 printf("%s0x0000: ",lf
);
778 if (!TTEST2(*(cp
+i
), 1))
780 printf("%02x",*(cp
+i
));
783 if (i
/16!=(i
+1)/16) {
785 printf("%s0x%04x: ",lf
,i
);
788 return(1); /* everything is ok */
791 printf("%spacket exceeded snapshot",lf
);
796 /* print the 4-byte metric block which is common found in the old-style TLVs */
799 isis_print_metric_block (const struct isis_metric_block
*isis_metric_block
)
801 printf(", Default Metric: %d, %s",
802 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_default
),
803 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_default
) ? "External" : "Internal");
804 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_delay
))
805 printf("\n\t\t\t Delay Metric: %d, %s",
806 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_delay
),
807 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_delay
) ? "External" : "Internal");
808 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_expense
))
809 printf("\n\t\t\t Expense Metric: %d, %s",
810 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_expense
),
811 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_expense
) ? "External" : "Internal");
812 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_error
))
813 printf("\n\t\t\t Error Metric: %d, %s",
814 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_error
),
815 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_error
) ? "External" : "Internal");
817 return(1); /* everything is ok */
821 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
823 u_int bitmasks
[33] = {
825 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
826 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
827 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
828 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
829 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
830 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
831 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
832 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
836 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
838 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
841 if (length
< sizeof(*tlv_ip_reach
)) {
842 printf("short IPv4 reachability (%d vs %lu)", length
,
843 (unsigned long)sizeof(*tlv_ip_reach
));
847 if (!TTEST(*tlv_ip_reach
))
850 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
853 /* lets see if we can transform the mask into a prefixlen */
854 while (prefix_len
<= 33) {
855 if (bitmasks
[prefix_len
++] == mask
) {
862 * 34 indicates no match -> must be a discontiguous netmask
863 * lets dump the mask, otherwise print the prefix_len
865 if (prefix_len
== 34)
866 printf("\n\t\t\tIPv4 prefix: %s mask %s",
867 ipaddr_string((tlv_ip_reach
->prefix
)),
868 ipaddr_string((tlv_ip_reach
->mask
)));
870 printf("\n\t\t\tIPv4 prefix: %s/%u",
871 ipaddr_string((tlv_ip_reach
->prefix
)),
874 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
875 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_default
),
876 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "External" : "Internal",
877 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "down" : "up");
879 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_delay
))
880 printf("\n\t\t\t Delay Metric: %02d, %s",
881 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_delay
),
882 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_delay
) ? "External" : "Internal");
884 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_expense
))
885 printf("\n\t\t\t Expense Metric: %02d, %s",
886 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_expense
),
887 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_expense
) ? "External" : "Internal");
889 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_error
))
890 printf("\n\t\t\t Error Metric: %02d, %s",
891 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_error
),
892 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_error
) ? "External" : "Internal");
894 length
-= sizeof(struct isis_tlv_ip_reach
);
901 * this is the common IP-REACH subTLV decoder it is called
902 * from various EXTD-IP REACH TLVs (135,235,236,237)
906 isis_print_ip_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
909 case SUBTLV_IP_REACH_ADMIN_TAG32
:
910 if (!TTEST2(*tptr
,4))
912 printf("%s32-Bit Administrative tag: 0x%08x",
914 EXTRACT_32BITS(tptr
));
916 case SUBTLV_IP_REACH_ADMIN_TAG64
:
917 if (!TTEST2(*tptr
,8))
919 printf("%s64-Bit Administrative tag: 0x%08x%08x",
921 EXTRACT_32BITS(tptr
),
922 EXTRACT_32BITS(tptr
+4));
925 printf("%sunknown subTLV, type %d, length %d",
929 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
937 printf("%spacket exceeded snapshot",lf
);
942 * this is the common IS-REACH subTLV decoder it is called
943 * from various EXTD-IS REACH TLVs (22,24,222)
947 isis_print_is_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
950 float bw
; /* copy buffer for several subTLVs */
953 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
954 if (!TTEST2(*tptr
,4))
956 printf("%sAdministrative groups: 0x%08x",
958 EXTRACT_32BITS(tptr
));
960 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
961 if (!TTEST2(*tptr
,4))
963 printf("%sLink Local Identifier: 0x%08x",
965 EXTRACT_32BITS(tptr
));
967 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
968 if (!TTEST2(*tptr
,4))
970 printf("%sLink Remote Identifier: 0x%08x",
972 EXTRACT_32BITS(tptr
));
974 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
975 if (!TTEST2(*tptr
,4))
977 j
= EXTRACT_32BITS(tptr
);
979 printf("%sMaximum link bandwidth : %.3f Mbps",
983 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
984 if (!TTEST2(*tptr
,4))
986 j
= EXTRACT_32BITS(tptr
);
988 printf("%sReservable link bandwidth: %.3f Mbps",
992 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
993 printf("%sUnreserved bandwidth:",lf
);
994 for (i
= 0; i
< 8; i
++) {
995 if (!TTEST2(*(tptr
+i
*4),4))
997 j
= EXTRACT_32BITS(tptr
);
999 printf("%s priority level %d: %.3f Mbps",
1005 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
1006 if (!TTEST2(*tptr
,3))
1008 printf("%sTraffic Engineering Metric: %d",
1010 EXTRACT_24BITS(tptr
));
1012 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
1013 if (!TTEST2(*tptr
,4))
1015 printf("%sIPv4 interface address: %s",
1017 ipaddr_string(tptr
));
1019 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
1020 if (!TTEST2(*tptr
,4))
1022 printf("%sIPv4 neighbor address: %s",
1024 ipaddr_string(tptr
));
1026 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE
:
1027 if (!TTEST2(*tptr
,2))
1030 j
= (ISIS_8BIT_MASK(*tptr
)); /* fetch the typecode and make sure
1031 that no high-order LSBs are set */
1032 printf("%sLink Protection Type: %s",
1034 (j
) ? "" : "none" );
1035 /* scan through the bits until the typecode is zero */
1037 printf("%s", isis_gmpls_link_prot_values
[i
]);
1039 if (j
) /*any other bit set ?*/
1043 printf(", Priority %u", *(tptr
+1));
1045 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
1046 printf("%sInterface Switching Capability",lf
);
1048 if (!TTEST2(*tptr
,1))
1050 printf("%s Interface Switching Capability:%s",
1052 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1054 if (!TTEST2(*(tptr
+1),1))
1056 printf(", LSP Encoding: %s",
1057 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1059 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1062 printf("%s Max LSP Bandwidth:",lf
);
1063 for (i
= 0; i
< 8; i
++) {
1064 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1066 j
= EXTRACT_32BITS(tptr
);
1067 memcpy (&bw
, &j
, 4);
1068 printf("%s priority level %d: %.3f Mbps",
1074 /* there is some optional stuff left to decode but this is as of yet
1075 not specified so just lets hexdump what is left */
1077 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1087 printf("%sReserved for cisco specific extensions, type %d, length %d",
1093 printf("%sReserved for future expansion, type %d, length %d",
1099 printf("%sunknown subTLV, type %d, length %d",
1103 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1111 printf("%spacket exceeded snapshot",lf
);
1118 * Decode IS-IS packets. Return 0 on error.
1121 static int isis_print (const u_char
*p
, u_int length
)
1123 const struct isis_common_header
*header
;
1125 const struct isis_iih_lan_header
*header_iih_lan
;
1126 const struct isis_iih_ptp_header
*header_iih_ptp
;
1127 const struct isis_lsp_header
*header_lsp
;
1128 const struct isis_csnp_header
*header_csnp
;
1129 const struct isis_psnp_header
*header_psnp
;
1131 const struct isis_tlv_lsp
*tlv_lsp
;
1132 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1133 const struct isis_tlv_is_reach
*tlv_is_reach
;
1134 const struct isis_tlv_es_reach
*tlv_es_reach
;
1136 u_char pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, lan_alen
, prefix_len
, subl
, subt
, tslen
;
1137 const u_char
*optr
, *pptr
, *tptr
;
1138 u_short packet_len
,pdu_len
,time_remain
;
1139 u_int i
,j
,bit_length
,byte_length
,metric
,ra
,rr
;
1140 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
1142 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
1145 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1146 need it for parsing the checksum TLV */
1147 header
= (const struct isis_common_header
*)p
;
1149 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1150 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1151 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1152 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1153 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1154 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1157 * Sanity checking of the header.
1159 if (header
->nlpid
!= NLPID_ISIS
) {
1160 printf(", coding error!");
1164 if (header
->version
!= ISIS_VERSION
) {
1165 printf(", version %d packet not supported", header
->version
);
1169 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1170 printf(", system ID length of %d is not supported",
1175 if (header
->pkt_version
!= ISIS_VERSION
) {
1176 printf(", version %d packet not supported", header
->pkt_version
);
1180 max_area
= header
->max_area
;
1183 max_area
= 3; /* silly shit */
1186 printf(", bad packet -- 255 areas");
1192 id_length
= header
->id_length
;
1195 id_length
= 6; /* silly shit again */
1197 case 1: /* 1-8 are valid sys-ID lenghts */
1207 id_length
= 0; /* entirely useless */
1210 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1215 printf(", hlen: %u, v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1223 pdu_type
=header
->pdu_type
;
1225 /* first lets see if we know the PDU name*/
1227 tok2str(isis_pdu_values
,
1228 "unknown PDU, type %d",
1235 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1236 printf(", bogus fixed header length %u should be %lu",
1237 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1241 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1242 if (packet_len
>pdu_len
) {
1243 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1247 TCHECK(*header_iih_lan
);
1248 printf("\n\t\t source-id: %s, holding time: %u, %s",
1249 isis_print_sysid(header_iih_lan
->source_id
,SYSTEM_ID_LEN
),
1250 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1251 tok2str(isis_iih_circuit_type_values
,
1252 "unknown circuit type 0x%02x",
1253 header_iih_lan
->circuit_type
));
1255 printf("\n\t\t lan-id: %s, Priority: %u, PDU length: %u",
1256 isis_print_nodeid(header_iih_lan
->lan_id
),
1257 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1260 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1261 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1265 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1266 printf(", bogus fixed header length %u should be %lu",
1267 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1271 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
1272 if (packet_len
>pdu_len
) {
1273 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1277 TCHECK(*header_iih_ptp
);
1278 printf("\n\t\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1279 isis_print_sysid(header_iih_ptp
->source_id
,SYSTEM_ID_LEN
),
1280 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1281 header_iih_ptp
->circuit_id
,
1282 tok2str(isis_iih_circuit_type_values
,
1283 "unknown circuit type 0x%02x",
1284 header_iih_ptp
->circuit_type
),
1287 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1288 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1293 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1294 printf(", bogus fixed header length %u should be %lu",
1295 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1299 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1300 if (packet_len
>pdu_len
) {
1301 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1305 TCHECK(*header_lsp
);
1306 printf("\n\t\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1307 isis_print_lspid(header_lsp
->lsp_id
),
1308 EXTRACT_32BITS(header_lsp
->sequence_number
),
1309 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1310 /* verify the checksum -
1311 * checking starts at the lsp-id field
1312 * which is 12 bytes after the packet start*/
1313 printf("\n\t\t chksum: 0x%04x (%s), PDU length: %u",
1314 EXTRACT_16BITS(header_lsp
->checksum
),
1315 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1318 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1320 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1321 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1322 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1323 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1324 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1325 printf("ATT bit set, ");
1327 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1328 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1330 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1331 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1336 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1337 printf(", bogus fixed header length %u should be %lu",
1338 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1342 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
1343 if (packet_len
>pdu_len
) {
1344 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1348 TCHECK(*header_csnp
);
1349 printf("\n\t\t source-id: %s, PDU length: %u",
1350 isis_print_nodeid(header_csnp
->source_id
),
1352 printf("\n\t\t start lsp-id: %s",
1353 isis_print_lspid(header_csnp
->start_lsp_id
));
1354 printf("\n\t\t end lsp-id: %s",
1355 isis_print_lspid(header_csnp
->end_lsp_id
));
1357 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1358 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1363 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1364 printf("- bogus fixed header length %u should be %lu",
1365 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1369 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1370 if (packet_len
>pdu_len
) {
1371 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1375 TCHECK(*header_psnp
);
1376 printf("\n\t\t source-id: %s",
1377 isis_print_nodeid(header_psnp
->source_id
));
1379 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1380 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1384 if(!isis_print_unknown_data(pptr
,"\n\t\t ",length
))
1390 * Now print the TLV's.
1393 while (packet_len
>= 2) {
1394 if (pptr
== snapend
) {
1398 if (!TTEST2(*pptr
, 2)) {
1399 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
1400 (long)(pptr
-snapend
));
1405 tmp
=len
; /* copy temporary len & pointer to packet data */
1408 if (len
> packet_len
) {
1412 /* first lets see if we know the TLVs name*/
1413 printf("\n\t\t %s TLV #%u, length: %u",
1414 tok2str(isis_tlv_values
,
1420 /* now check if we have a decoder otherwise do a hexdump at the end*/
1423 if (!TTEST2(*tptr
, 1))
1426 while (tmp
&& alen
< tmp
) {
1427 printf("\n\t\t\tArea address (%u): %s",
1429 print_nsap(tptr
, alen
));
1432 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1434 if (!TTEST2(*tptr
, 1))
1440 while (tmp
>= ETHER_ADDR_LEN
) {
1441 if (!TTEST2(*tptr
, ETHER_ADDR_LEN
))
1443 printf("\n\t\t\tIS Neighbor: %s",isis_print_sysid(tptr
,ETHER_ADDR_LEN
));
1444 tmp
-= ETHER_ADDR_LEN
;
1445 tptr
+= ETHER_ADDR_LEN
;
1449 case TLV_ISNEIGH_VARLEN
:
1450 if (!TTEST2(*tptr
, 1))
1452 lan_alen
= *tptr
++; /* LAN adress length */
1454 printf("\n\t\t\tLAN address length %u bytes ",lan_alen
);
1455 while (tmp
>= lan_alen
) {
1456 if (!TTEST2(*tptr
, lan_alen
))
1458 printf("\n\t\t\tIS Neighbor: %s",isis_print_sysid(tptr
,lan_alen
));
1467 case TLV_MT_IS_REACH
:
1469 if (!TTEST2(*tptr
, 2))
1471 printf("\n\t\t\t%s",
1472 tok2str(isis_mt_values
,
1473 "Reserved for IETF Consensus",
1474 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1476 printf(" Topology (0x%03x)",
1477 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1479 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1481 printf("\n\t\t\t IS Neighbor: %s", isis_print_nodeid(tptr
));
1482 tptr
+=(NODE_ID_LEN
);
1483 if (!TTEST2(*tptr
, 3))
1485 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1487 if (!TTEST2(*tptr
, 1))
1490 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1492 printf(" (%u)",tslen
);
1494 if (!TTEST2(*tptr
,2))
1498 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1505 tmp
-=(SYSTEM_ID_LEN
+7);
1509 case TLV_EXT_IS_REACH
:
1511 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1513 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1514 tptr
+=(NODE_ID_LEN
);
1516 if (!TTEST2(*tptr
, 3))
1518 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1521 if (!TTEST2(*tptr
, 1))
1523 tslen
=*(tptr
++); /* read out subTLV length */
1524 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1526 printf(" (%u)",tslen
);
1528 if (!TTEST2(*tptr
,2))
1532 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1539 tmp
-=(SYSTEM_ID_LEN
+5);
1543 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1545 printf("\n\t\t\t%s",
1546 tok2str(isis_is_reach_virtual_values
,
1547 "bogus virtual flag 0x%02x",
1549 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1550 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1551 if (!TTEST(*tlv_is_reach
))
1553 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1554 isis_print_metric_block(&tlv_is_reach
->isis_metric_block
);
1555 tmp
-= sizeof(struct isis_tlv_is_reach
);
1561 tlv_es_reach
= (const struct isis_tlv_es_reach
*)tptr
;
1562 while (tmp
>= sizeof(struct isis_tlv_es_reach
)) {
1563 if (!TTEST(*tlv_es_reach
))
1565 printf("\n\t\t\tES Neighbor: %s",
1566 isis_print_sysid(tlv_es_reach
->neighbor_sysid
,SYSTEM_ID_LEN
));
1567 isis_print_metric_block(&tlv_es_reach
->isis_metric_block
);
1568 tmp
-= sizeof(struct isis_tlv_es_reach
);
1573 /* those two TLVs share the same format */
1575 case TLV_IP_REACH_EXT
:
1576 if (!isis_print_tlv_ip_reach(pptr
, len
))
1580 case TLV_MT_IP_REACH
:
1582 if (!TTEST2(*tptr
, 2))
1585 printf("\n\t\t\t%s",
1586 tok2str(isis_mt_values
,
1587 "Reserved for IETF Consensus",
1588 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1590 printf(" Topology (0x%03x)",
1591 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1594 memset (prefix
, 0, 4);
1595 if (!TTEST2(*tptr
, 4))
1597 metric
= EXTRACT_32BITS(tptr
);
1600 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1603 bit_length
= (*(tptr
)++&0x3f);
1604 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1606 if (!TTEST2(*tptr
, byte_length
))
1608 memcpy(prefix
,tptr
,byte_length
);
1610 printf("\n\t\t\tIPv4 prefix: %s/%d",
1611 ipaddr_string(prefix
),
1614 printf("\n\t\t\t Metric: %u, Distribution: %s",
1616 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1618 printf(", %ssub-TLVs present",
1619 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1621 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1622 /* assume that one prefix can hold more
1623 than one subTLV - therefore the first byte must reflect
1624 the aggregate bytecount of the subTLVs for this prefix
1626 if (!TTEST2(*tptr
, 1))
1630 printf(" (%u)",tslen
); /* print out subTLV length */
1633 if (!TTEST2(*tptr
,2))
1637 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1644 tmp
-=(7+byte_length
);
1648 case TLV_EXT_IP_REACH
:
1650 memset (prefix
, 0, 4);
1651 if (!TTEST2(*tptr
, 4))
1653 metric
= EXTRACT_32BITS(tptr
);
1656 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1659 bit_length
= (*(tptr
)++&0x3f);
1660 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1662 if (!TTEST2(*tptr
, byte_length
))
1664 memcpy(prefix
,tptr
,byte_length
);
1666 printf("\n\t\t\tIPv4 prefix: %s/%d",
1667 ipaddr_string(prefix
),
1670 printf("\n\t\t\t Metric: %u, Distribution: %s",
1672 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1674 printf(", %ssub-TLVs present",
1675 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1677 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1678 /* assume that one prefix can hold more
1679 than one subTLV - therefore the first byte must reflect
1680 the aggregate bytecount of the subTLVs for this prefix
1682 if (!TTEST2(*tptr
, 1))
1686 printf(" (%u)",tslen
); /* print out subTLV length */
1689 if (!TTEST2(*tptr
,2))
1693 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1700 tmp
-=(5+byte_length
);
1708 if (!TTEST2(*tptr
, 4))
1710 metric
= EXTRACT_32BITS(tptr
);
1713 if (!TTEST2(*tptr
, 2))
1716 bit_length
= (*(tptr
)++);
1717 byte_length
= (bit_length
+ 7) / 8;
1718 if (!TTEST2(*tptr
, byte_length
))
1721 memset(prefix6
, 0, 16);
1722 memcpy(prefix6
,tptr
,byte_length
);
1724 printf("\n\t\t\tIPv6 prefix: %s/%u",
1725 ip6addr_string(prefix6
),
1728 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1730 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1731 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1732 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1734 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1735 /* assume that one prefix can hold more
1736 than one subTLV - therefore the first byte must reflect
1737 the aggregate bytecount of the subTLVs for this prefix
1739 if (!TTEST2(*tptr
, 1))
1743 printf(" (%u)",tslen
); /* print out subTLV length */
1746 if (!TTEST2(*tptr
,2))
1750 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1757 tmp
-=(6+byte_length
);
1766 if (!TTEST2(*tptr
, 16))
1769 printf("\n\t\t\tIPv6 interface address: %s",
1770 ip6addr_string(tptr
));
1778 if (!TTEST2(*tptr
, 1))
1781 printf("\n\t\t\t%s: ",
1782 tok2str(isis_subtlv_auth_values
,
1783 "unknown Authentication type 0x%02x",
1787 case SUBTLV_AUTH_SIMPLE
:
1788 for(i
=1;i
<len
;i
++) {
1789 if (!TTEST2(*(tptr
+i
), 1))
1791 printf("%c",*(tptr
+i
));
1794 case SUBTLV_AUTH_MD5
:
1795 for(i
=1;i
<len
;i
++) {
1796 if (!TTEST2(*(tptr
+i
), 1))
1798 printf("%02x",*(tptr
+i
));
1800 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1801 printf(", (malformed subTLV) ");
1803 case SUBTLV_AUTH_PRIVATE
:
1805 if(!isis_print_unknown_data(tptr
+1,"\n\t\t\t ",len
-1))
1812 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1814 if (!TTEST2(*tptr
, 1))
1816 printf("\n\t\t\tAdjacency State: %s",
1817 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1820 if(tmp
>sizeof(tlv_ptp_adj
->extd_local_circuit_id
)) {
1821 if (!TTEST2(tlv_ptp_adj
->extd_local_circuit_id
,
1822 sizeof(tlv_ptp_adj
->extd_local_circuit_id
)))
1824 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1825 EXTRACT_32BITS(tlv_ptp_adj
->extd_local_circuit_id
));
1826 tmp
-=sizeof(tlv_ptp_adj
->extd_local_circuit_id
);
1828 if(tmp
>=SYSTEM_ID_LEN
) {
1829 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, SYSTEM_ID_LEN
))
1831 printf("\n\t\t\tNeighbor SystemID: %s",
1832 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
,SYSTEM_ID_LEN
));
1835 if(tmp
>=sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)) {
1836 if (!TTEST2(tlv_ptp_adj
->neighbor_extd_local_circuit_id
,
1837 sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)))
1839 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1840 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_extd_local_circuit_id
));
1845 printf("\n\t\t\tNLPID(s): ");
1847 if (!TTEST2(*(tptr
), 1))
1850 tok2str(isis_nlpid_values
,
1853 if (tmp
>1) /* further NPLIDs ? - put comma */
1859 case TLV_TE_ROUTER_ID
:
1860 if (!TTEST2(*pptr
, 4))
1862 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1867 if (!TTEST2(*tptr
, 4))
1869 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1876 printf("\n\t\t\tHostname: ");
1878 if (!TTEST2(*tptr
, 1))
1880 printf("%c",*tptr
++);
1885 case TLV_SHARED_RISK_GROUP
:
1886 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1888 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1889 tptr
+=(NODE_ID_LEN
);
1892 if (!TTEST2(*tptr
, 1))
1894 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1897 if (!TTEST2(*tptr
,4))
1899 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1903 if (!TTEST2(*tptr
,4))
1905 printf("\n\t\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1910 if (!TTEST2(*tptr
, 4))
1912 printf("\n\t\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1919 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1921 printf("\n\t\t\tlsp-id: %s",
1922 isis_print_nodeid(tlv_lsp
->lsp_id
));
1923 if (!TTEST((tlv_lsp
->lsp_id
)[NODE_ID_LEN
]))
1925 printf("-%02x",(tlv_lsp
->lsp_id
)[NODE_ID_LEN
]);
1926 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1928 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1929 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1931 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1932 if (!TTEST2(tlv_lsp
->checksum
, 2))
1934 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1935 tmp
-=sizeof(struct isis_tlv_lsp
);
1941 if (!TTEST2(*tptr
, 2))
1943 printf("\n\t\t\tchecksum: 0x%04x (%s)",
1944 EXTRACT_16BITS(tptr
),
1945 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1948 case TLV_MT_SUPPORTED
:
1950 /* length can only be a multiple of 2, otherwise there is
1951 something broken -> so decode down until length is 1 */
1953 if (!TTEST2(*tptr
, 2))
1955 printf("\n\t\t\t%s",
1956 tok2str(isis_mt_values
,
1957 "Reserved for IETF Consensus",
1958 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1960 printf(" Topology (0x%03x)%s%s",
1961 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1962 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1963 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1965 printf("\n\t\t\tmalformed MT-ID");
1973 case TLV_RESTART_SIGNALING
:
1974 if (!TTEST2(*tptr
, 3))
1976 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1977 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1979 time_remain
= EXTRACT_16BITS(tptr
);
1980 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1981 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
1985 if (!TTEST2(*tptr
, 1))
1987 printf("\n\t\t\tInter-Domain Information Type: %s",
1988 tok2str(isis_subtlv_idrp_values
,
1992 case SUBTLV_IDRP_ASN
:
1993 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
1995 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
1997 case SUBTLV_IDRP_LOCAL
:
1998 case SUBTLV_IDRP_RES
:
2000 if(!isis_print_unknown_data(tptr
,"\n\t\t\t",len
-1))
2006 case TLV_LSP_BUFFERSIZE
:
2007 if (!TTEST2(*tptr
, 2))
2009 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr
));
2013 while (tmp
>= SYSTEM_ID_LEN
) {
2014 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
))
2016 printf("%s",isis_print_sysid(tptr
,SYSTEM_ID_LEN
));
2017 tptr
+=SYSTEM_ID_LEN
;
2022 case TLV_PREFIX_NEIGH
:
2023 if (!TTEST2(*tptr
, sizeof(struct isis_metric_block
)))
2025 printf("Metric Block");
2026 isis_print_metric_block((const struct isis_metric_block
*)tptr
);
2027 tptr
+=sizeof(struct isis_metric_block
);
2028 tmp
-=sizeof(struct isis_metric_block
);
2031 if (!TTEST2(*tptr
, 1))
2033 prefix_len
=*tptr
++; /* read out prefix length in semioctets*/
2035 if (!TTEST2(*tptr
, prefix_len
/2))
2037 printf("\n\t\t\tAddress: %s/%u",
2038 print_nsap(tptr
,prefix_len
/2),
2046 * FIXME those are the defined TLVs that lack a decoder
2047 * you are welcome to contribute code ;-)
2050 case TLV_IS_ALIAS_ID
:
2051 case TLV_DECNET_PHASE4
:
2052 case TLV_LUCENT_PRIVATE
:
2054 case TLV_NORTEL_PRIVATE1
:
2055 case TLV_NORTEL_PRIVATE2
:
2056 case TLV_MT_IP6_REACH
:
2059 if(!isis_print_unknown_data(pptr
,"\n\t\t\t",len
))
2068 if (packet_len
!= 0) {
2069 printf("\n\t\t\t %d straggler bytes", packet_len
);
2074 fputs("[|isis]", stdout
);
2078 printf("\n\t\t\t packet exceeded snapshot");
2083 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2087 osi_cksum(const u_char
*tptr
, u_int len
)
2089 int32_t c0
= 0, c1
= 0;
2091 while ((int)--len
>= 0) {