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.63 2002-10-03 16:00:34 hannes Exp $ (LBL)";
36 #include <tcpdump-stdinc.h>
41 #include "interface.h"
42 #include "addrtoname.h"
43 #include "ethertype.h"
47 #define NLPID_CLNS 129 /* 0x81 */
48 #define NLPID_ESIS 130 /* 0x82 */
49 #define NLPID_ISIS 131 /* 0x83 */
50 #define NLPID_IP6 0x8e
52 #define NLPID_NULLNS 0
55 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
58 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
59 #define NODE_ID_LEN SYSTEM_ID_LEN+1
60 #define LSP_ID_LEN SYSTEM_ID_LEN+2
62 #define ISIS_VERSION 1
63 #define PDU_TYPE_MASK 0x1F
64 #define PRIORITY_MASK 0x7F
76 static struct tok isis_pdu_values
[] = {
77 { L1_LAN_IIH
, "L1 Lan IIH"},
78 { L2_LAN_IIH
, "L2 Lan IIH"},
79 { PTP_IIH
, "p2p IIH"},
82 { L1_CSNP
, "L1 CSNP"},
83 { L2_CSNP
, "L2 CSNP"},
84 { L1_PSNP
, "L1 PSNP"},
85 { L2_PSNP
, "L2 PSNP"},
90 * A TLV is a tuple of a type, length and a value and is normally used for
91 * encoding information in all sorts of places. This is an enumeration of
92 * the well known types.
94 * list taken from draft-ietf-isis-wg-tlv-codepoints-01.txt
97 #define TLV_AREA_ADDR 1
98 #define TLV_IS_REACH 2
100 #define TLV_PART_DIS 4
101 #define TLV_PREFIX_NEIGH 5
102 #define TLV_ISNEIGH 6
103 #define TLV_ISNEIGH_VARLEN 7
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_HOLDTIME 198 /* ES-IS */
126 #define TLV_RESTART_SIGNALING 211
127 #define TLV_MT_IS_REACH 222
128 #define TLV_MT_SUPPORTED 229
129 #define TLV_IP6ADDR 232
130 #define TLV_MT_IP_REACH 235
131 #define TLV_IP6_REACH 236
132 #define TLV_MT_IP6_REACH 237
133 #define TLV_PTP_ADJ 240
134 #define TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00.txt */
136 static struct tok isis_tlv_values
[] = {
137 { TLV_AREA_ADDR
, "Area address(es)"},
138 { TLV_IS_REACH
, "IS Reachability"},
139 { TLV_ESNEIGH
, "ES Neighbor(s)"},
140 { TLV_PART_DIS
, "Partition DIS"},
141 { TLV_PREFIX_NEIGH
, "Prefix Neighbors"},
142 { TLV_ISNEIGH
, "IS Neighbor(s)"},
143 { TLV_ISNEIGH_VARLEN
, "IS Neighbor(s) (variable length)"},
144 { TLV_PADDING
, "Padding"},
145 { TLV_LSP
, "LSP entries"},
146 { TLV_AUTH
, "Authentication"},
147 { TLV_CHECKSUM
, "Checksum"},
148 { TLV_LSP_BUFFERSIZE
, "LSP Buffersize"},
149 { TLV_EXT_IS_REACH
, "Extended IS Reachability"},
150 { TLV_IS_ALIAS_ID
, "IS Alias ID"},
151 { TLV_DECNET_PHASE4
, "DECnet Phase IV"},
152 { TLV_LUCENT_PRIVATE
, "Lucent Proprietary"},
153 { TLV_IP_REACH
, "IPv4 Internal reachability"},
154 { TLV_PROTOCOLS
, "Protocols supported"},
155 { TLV_IP_REACH_EXT
, "IPv4 External reachability"},
156 { TLV_IDRP_INFO
, "Inter-Domain Information Type"},
157 { TLV_IPADDR
, "IPv4 Interface address(es)"},
158 { TLV_IPAUTH
, "IPv4 authentication (deprecated)"},
159 { TLV_TE_ROUTER_ID
, "Traffic Engineering Router ID"},
160 { TLV_EXT_IP_REACH
, "Extended IPv4 reachability"},
161 { TLV_HOSTNAME
, "Hostname"},
162 { TLV_SHARED_RISK_GROUP
, "Shared Risk Link Group"},
163 { TLV_NORTEL_PRIVATE1
, "Nortel Proprietary"},
164 { TLV_NORTEL_PRIVATE2
, "Nortel Proprietary"},
165 { TLV_HOLDTIME
, "Holdtime"},
166 { TLV_RESTART_SIGNALING
, "Restart Signaling"},
167 { TLV_MT_IS_REACH
, "Multi Topology IS Reachability"},
168 { TLV_MT_SUPPORTED
, "Multi Topology"},
169 { TLV_IP6ADDR
, "IPv6 Interface address(es)"},
170 { TLV_MT_IP_REACH
, "Multi-Topology IPv4 reachability"},
171 { TLV_IP6_REACH
, "IPv6 reachability"},
172 { TLV_MT_IP6_REACH
, "Multi-Topology IP6 reachability"},
173 { TLV_PTP_ADJ
, "Point-to-point Adjacency State"},
174 { TLV_IIH_SEQNR
, "Hello PDU Sequence Number"},
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 osi_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 pdu_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];
436 /* allocate space for the following string
437 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
438 * 32 bytes plus one termination byte */
440 print_nsap(register const u_char
*pptr
, register int nsap_length
)
443 static char nsap_ascii_output
[33];
444 char *junk_buf
= nsap_ascii_output
;
446 if (nsap_length
< 1 || nsap_length
> 13) {
447 junk_buf
+=sprintf(junk_buf
, "illegal length");
449 return (nsap_ascii_output
);
452 for (nsap_idx
= 0; nsap_idx
< nsap_length
; nsap_idx
++) {
453 if (!TTEST2(*pptr
, 1))
455 junk_buf
+=sprintf(junk_buf
, "%02x", *pptr
++);
456 if (((nsap_idx
& 1) == 0) &&
457 (nsap_idx
+ 1 < nsap_length
)) {
458 junk_buf
+=sprintf(junk_buf
, ".");
462 return (nsap_ascii_output
);
465 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
466 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
467 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
468 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
469 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
470 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
472 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
473 const u_char
*esrc
, const u_char
*edst
)
476 const struct isis_common_header
*header
;
478 header
= (const struct isis_common_header
*)p
;
479 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
482 printf("[|iso-clns] ");
483 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
485 etheraddr_string(esrc
),
486 etheraddr_string(edst
));
493 (void)printf("CLNS, length: %u", length
);
494 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
495 (void)printf(", %s > %s",
496 etheraddr_string(esrc
),
497 etheraddr_string(edst
));
501 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
502 (void)printf("%s > %s, ",
503 etheraddr_string(esrc
),
504 etheraddr_string(edst
));
505 esis_print(p
, length
);
509 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
510 (void)printf("%s > %s, ",
511 etheraddr_string(esrc
),
512 etheraddr_string(edst
));
513 if (!isis_print(p
, length
))
514 default_print_unaligned(p
, caplen
);
518 (void)printf("ISO NULLNS, length: %u", length
);
519 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
520 (void)printf(", %s > %s",
521 etheraddr_string(esrc
),
522 etheraddr_string(edst
));
526 (void)printf("CLNS 0x%02x, length: %u", p
[0], length
);
527 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
528 (void)printf(", %s > %s",
529 etheraddr_string(esrc
),
530 etheraddr_string(edst
));
532 default_print_unaligned(p
, caplen
);
537 #define ESIS_REDIRECT 6
541 static struct tok esis_values
[] = {
542 { ESIS_REDIRECT
, "redirect"},
557 esis_print(const u_char
*p
, u_int length
)
561 const struct esis_hdr
*eh
;
567 printf(" no header at all!");
571 eh
= (const struct esis_hdr
*) &p
[2];
577 printf(" LI(%d) > PDU size (%d)!", li
, length
);
580 if (li
< sizeof(struct esis_hdr
) + 2) {
584 printf(" too short for esis header %d:", li
);
585 while (--length
!= 0)
586 printf("%02X", *p
++);
591 printf("ES-IS, %s, length: %u",
592 tok2str(esis_values
,"unknown type: %u",eh
->type
& 0x1f),
598 if (vflag
&& osi_cksum(p
, li
)) {
599 printf(" bad cksum (got 0x%02x%02x)",
600 eh
->cksum
[1], eh
->cksum
[0]);
601 default_print(p
, length
);
604 if (eh
->version
!= 1) {
605 printf(" unsupported version %d", eh
->version
);
608 p
+= sizeof(*eh
) + 2;
609 li
-= sizeof(*eh
) + 2; /* protoid * li */
611 switch (eh
->type
& 0x1f) {
612 case ESIS_REDIRECT
: {
613 const u_char
*dst
, *snpa
, *is
;
615 dst
= p
; p
+= *p
+ 1;
618 printf("\n\t\t %s", isonsap_string(dst
));
619 snpa
= p
; p
+= *p
+ 1;
628 printf(" > %s", etheraddr_string(&snpa
[1]));
630 printf(" > %s", isonsap_string(is
));
649 printf("\n\tNET: %s", print_nsap(is
+1,*is
));
657 print_unknown_data(p
,"\n\t ",snapend
-p
);
662 /* hexdump - FIXME ? */
665 print_unknown_data(p
,"\n\t ",snapend
-p
);
668 while (p
< ep
&& li
) {
675 printf(", bad opts/li");
682 printf(", opt (%d) too long", op
);
692 if (op
== TLV_HOLDTIME
&& opli
== 2) {
693 printf("\n\tholdtime: %us", EXTRACT_16BITS(q
));
697 if (op
== TLV_PROTOCOLS
&& opli
>= 1) {
698 printf("\n\t%s (length: %u): %s",
699 tok2str(isis_tlv_values
, "unknown", op
),
701 tok2str(osi_nlpid_values
,"Unknown 0x%02x",*q
));
705 print_unknown_data(q
,"\n\t ",opli
);
709 /* allocate space for the following string
711 * 14 bytes plus one termination byte */
713 isis_print_sysid(const u_char
*cp
, int sysid_len
)
716 static char sysid
[15];
719 for (i
= 1; i
<= sysid_len
; i
++) {
722 pos
+=sprintf(pos
, "%02x", *cp
++);
724 pos
+=sprintf(pos
, ".");
732 /* allocate space for the following string
734 * 17 bytes plus one termination byte */
736 isis_print_nodeid(const u_char
*cp
)
739 static char nodeid
[18];
742 for (i
= 1; i
<= 7; i
++) {
745 pos
+=sprintf(pos
, "%02x", *cp
++);
747 pos
+=sprintf(pos
, ".");
754 /* allocate space for the following string
755 * xxxx.xxxx.xxxx.yy-zz
756 * 20 bytes plus one termination byte */
758 isis_print_lspid(const u_char
*cp
)
761 static char lspid
[21];
764 for (i
= 1; i
<= 7; i
++) {
765 pos
+=sprintf(pos
, "%02x", *cp
++);
767 pos
+=sprintf(pos
, ".");
769 pos
+=sprintf(pos
, "-%02x", *cp
);
773 /* print the 4-byte metric block which is common found in the old-style TLVs */
776 isis_print_metric_block (const struct isis_metric_block
*isis_metric_block
)
778 printf(", Default Metric: %d, %s",
779 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_default
),
780 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_default
) ? "External" : "Internal");
781 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_delay
))
782 printf("\n\t\t Delay Metric: %d, %s",
783 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_delay
),
784 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_delay
) ? "External" : "Internal");
785 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_expense
))
786 printf("\n\t\t Expense Metric: %d, %s",
787 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_expense
),
788 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_expense
) ? "External" : "Internal");
789 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_error
))
790 printf("\n\t\t Error Metric: %d, %s",
791 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_error
),
792 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_error
) ? "External" : "Internal");
794 return(1); /* everything is ok */
798 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
800 u_int bitmasks
[33] = {
802 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
803 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
804 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
805 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
806 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
807 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
808 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
809 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
813 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
815 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
818 if ((size_t)length
< sizeof(*tlv_ip_reach
)) {
819 printf("short IPv4 reachability (%d vs %lu)", length
,
820 (unsigned long)sizeof(*tlv_ip_reach
));
824 if (!TTEST(*tlv_ip_reach
))
827 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
830 /* lets see if we can transform the mask into a prefixlen */
831 while (prefix_len
<= 33) {
832 if (bitmasks
[prefix_len
++] == mask
) {
839 * 34 indicates no match -> must be a discontiguous netmask
840 * lets dump the mask, otherwise print the prefix_len
842 if (prefix_len
== 34)
843 printf("\n\t\tIPv4 prefix: %s mask %s",
844 ipaddr_string((tlv_ip_reach
->prefix
)),
845 ipaddr_string((tlv_ip_reach
->mask
)));
847 printf("\n\t\tIPv4 prefix: %s/%u",
848 ipaddr_string((tlv_ip_reach
->prefix
)),
851 printf("\n\t\t Default Metric: %02d, %s, Distribution: %s",
852 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_default
),
853 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "External" : "Internal",
854 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "down" : "up");
856 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_delay
))
857 printf("\n\t\t Delay Metric: %02d, %s",
858 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_delay
),
859 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_delay
) ? "External" : "Internal");
861 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_expense
))
862 printf("\n\t\t Expense Metric: %02d, %s",
863 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_expense
),
864 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_expense
) ? "External" : "Internal");
866 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_error
))
867 printf("\n\t\t Error Metric: %02d, %s",
868 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_error
),
869 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_error
) ? "External" : "Internal");
871 length
-= sizeof(struct isis_tlv_ip_reach
);
878 * this is the common IP-REACH subTLV decoder it is called
879 * from various EXTD-IP REACH TLVs (135,235,236,237)
883 isis_print_ip_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
886 case SUBTLV_IP_REACH_ADMIN_TAG32
:
887 if (!TTEST2(*tptr
,4))
889 printf("%s32-Bit Administrative tag: 0x%08x",
891 EXTRACT_32BITS(tptr
));
893 case SUBTLV_IP_REACH_ADMIN_TAG64
:
894 if (!TTEST2(*tptr
,8))
896 printf("%s64-Bit Administrative tag: 0x%08x%08x",
898 EXTRACT_32BITS(tptr
),
899 EXTRACT_32BITS(tptr
+4));
902 printf("%sunknown subTLV, type %d, length %d",
906 if(!print_unknown_data(tptr
,"\n\t\t ",
914 printf("%spacket exceeded snapshot",lf
);
919 * this is the common IS-REACH subTLV decoder it is called
920 * from various EXTD-IS REACH TLVs (22,24,222)
924 isis_print_is_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
927 float bw
; /* copy buffer for several subTLVs */
930 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
931 if (!TTEST2(*tptr
,4))
933 printf("%sAdministrative groups: 0x%08x",
935 EXTRACT_32BITS(tptr
));
937 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
938 if (!TTEST2(*tptr
,4))
940 printf("%sLink Local Identifier: 0x%08x",
942 EXTRACT_32BITS(tptr
));
944 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
945 if (!TTEST2(*tptr
,4))
947 printf("%sLink Remote Identifier: 0x%08x",
949 EXTRACT_32BITS(tptr
));
951 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
952 if (!TTEST2(*tptr
,4))
954 j
= EXTRACT_32BITS(tptr
);
956 printf("%sMaximum link bandwidth : %.3f Mbps",
960 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
961 if (!TTEST2(*tptr
,4))
963 j
= EXTRACT_32BITS(tptr
);
965 printf("%sReservable link bandwidth: %.3f Mbps",
969 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
970 printf("%sUnreserved bandwidth:",lf
);
971 for (i
= 0; i
< 8; i
++) {
972 if (!TTEST2(*(tptr
+i
*4),4))
974 j
= EXTRACT_32BITS(tptr
);
976 printf("%s priority level %d: %.3f Mbps",
982 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
983 if (!TTEST2(*tptr
,3))
985 printf("%sTraffic Engineering Metric: %d",
987 EXTRACT_24BITS(tptr
));
989 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
990 if (!TTEST2(*tptr
,4))
992 printf("%sIPv4 interface address: %s",
994 ipaddr_string(tptr
));
996 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
997 if (!TTEST2(*tptr
,4))
999 printf("%sIPv4 neighbor address: %s",
1001 ipaddr_string(tptr
));
1003 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE
:
1004 if (!TTEST2(*tptr
,2))
1007 j
= (ISIS_8BIT_MASK(*tptr
)); /* fetch the typecode and make sure
1008 that no high-order LSBs are set */
1009 printf("%sLink Protection Type: %s",
1011 (j
) ? "" : "none" );
1012 /* scan through the bits until the typecode is zero */
1014 printf("%s", isis_gmpls_link_prot_values
[i
]);
1016 if (j
) /*any other bit set ?*/
1020 printf(", Priority %u", *(tptr
+1));
1022 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
1023 printf("%sInterface Switching Capability",lf
);
1025 if (!TTEST2(*tptr
,1))
1027 printf("%s Interface Switching Capability:%s",
1029 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1031 if (!TTEST2(*(tptr
+1),1))
1033 printf(", LSP Encoding: %s",
1034 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1036 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1039 printf("%s Max LSP Bandwidth:",lf
);
1040 for (i
= 0; i
< 8; i
++) {
1041 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1043 j
= EXTRACT_32BITS(tptr
);
1044 memcpy (&bw
, &j
, 4);
1045 printf("%s priority level %d: %.3f Mbps",
1051 /* there is some optional stuff left to decode but this is as of yet
1052 not specified so just lets hexdump what is left */
1054 if(!print_unknown_data(tptr
,"\n\t\t ",
1064 printf("%sReserved for cisco specific extensions, type %d, length %d",
1070 printf("%sReserved for future expansion, type %d, length %d",
1076 printf("%sunknown subTLV, type %d, length %d",
1080 if(!print_unknown_data(tptr
,"\n\t\t ",
1088 printf("%spacket exceeded snapshot",lf
);
1095 * Decode IS-IS packets. Return 0 on error.
1098 static int isis_print (const u_char
*p
, u_int length
)
1100 const struct isis_common_header
*header
;
1102 const struct isis_iih_lan_header
*header_iih_lan
;
1103 const struct isis_iih_ptp_header
*header_iih_ptp
;
1104 const struct isis_lsp_header
*header_lsp
;
1105 const struct isis_csnp_header
*header_csnp
;
1106 const struct isis_psnp_header
*header_psnp
;
1108 const struct isis_tlv_lsp
*tlv_lsp
;
1109 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1110 const struct isis_tlv_is_reach
*tlv_is_reach
;
1111 const struct isis_tlv_es_reach
*tlv_es_reach
;
1113 u_char pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, lan_alen
, prefix_len
, subl
, subt
, tslen
;
1114 const u_char
*optr
, *pptr
, *tptr
;
1115 u_short packet_len
,pdu_len
,time_remain
;
1116 u_int i
,j
,bit_length
,byte_length
,metric
,ra
,rr
;
1117 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
1119 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
1122 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1123 need it for parsing the checksum TLV */
1124 header
= (const struct isis_common_header
*)p
;
1126 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1127 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1128 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1129 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1130 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1131 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1134 * Sanity checking of the header.
1136 if (header
->nlpid
!= NLPID_ISIS
) {
1137 printf(", coding error!");
1141 if (header
->version
!= ISIS_VERSION
) {
1142 printf(", version %d packet not supported", header
->version
);
1146 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1147 printf(", system ID length of %d is not supported",
1152 if (header
->pdu_version
!= ISIS_VERSION
) {
1153 printf(", version %d packet not supported", header
->pdu_version
);
1157 max_area
= header
->max_area
;
1160 max_area
= 3; /* silly shit */
1163 printf(", bad packet -- 255 areas");
1169 id_length
= header
->id_length
;
1172 id_length
= 6; /* silly shit again */
1174 case 1: /* 1-8 are valid sys-ID lenghts */
1184 id_length
= 0; /* entirely useless */
1187 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1192 pdu_type
=header
->pdu_type
;
1194 /* in non-verbose mode just lets print the basic PDU Type*/
1196 printf("IS-IS, %s, length: %u",
1197 tok2str(isis_pdu_values
,"unknown PDU-Type %u",pdu_type
),
1202 /* ok they seem to want to know everything - lets fully decode it */
1203 printf("IS-IS, length: %u",length
);
1205 printf("\n\thlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1208 header
->pdu_version
,
1214 /* first lets see if we know the PDU name*/
1215 printf(", pdu-type: %s",
1216 tok2str(isis_pdu_values
,
1221 if(!print_unknown_data(optr
,"\n\t",8)) /* provide the _o_riginal pointer */
1222 return(0); /* for optionally debugging the common header */
1229 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1230 printf(", bogus fixed header length %u should be %lu",
1231 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1235 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1236 if (packet_len
>pdu_len
) {
1237 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1241 TCHECK(*header_iih_lan
);
1242 printf("\n\t source-id: %s, holding time: %u, %s",
1243 isis_print_sysid(header_iih_lan
->source_id
,SYSTEM_ID_LEN
),
1244 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1245 tok2str(isis_iih_circuit_type_values
,
1246 "unknown circuit type 0x%02x",
1247 header_iih_lan
->circuit_type
));
1249 printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
1250 isis_print_nodeid(header_iih_lan
->lan_id
),
1251 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1255 if(!print_unknown_data(pptr
,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE
))
1259 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1260 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1264 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1265 printf(", bogus fixed header length %u should be %lu",
1266 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1270 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
1271 if (packet_len
>pdu_len
) {
1272 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1276 TCHECK(*header_iih_ptp
);
1277 printf("\n\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1278 isis_print_sysid(header_iih_ptp
->source_id
,SYSTEM_ID_LEN
),
1279 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1280 header_iih_ptp
->circuit_id
,
1281 tok2str(isis_iih_circuit_type_values
,
1282 "unknown circuit type 0x%02x",
1283 header_iih_ptp
->circuit_type
),
1287 if(!print_unknown_data(pptr
,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE
))
1291 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1292 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1297 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1298 printf(", bogus fixed header length %u should be %lu",
1299 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1303 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1304 if (packet_len
>pdu_len
) {
1305 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1309 TCHECK(*header_lsp
);
1310 printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1311 isis_print_lspid(header_lsp
->lsp_id
),
1312 EXTRACT_32BITS(header_lsp
->sequence_number
),
1313 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1314 /* verify the checksum -
1315 * checking starts at the lsp-id field
1316 * which is 12 bytes after the packet start*/
1317 printf("\n\t chksum: 0x%04x (%s), PDU length: %u",
1318 EXTRACT_16BITS(header_lsp
->checksum
),
1319 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1322 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1324 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1325 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1326 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1327 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1328 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1329 printf("ATT bit set, ");
1331 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1332 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1335 if(!print_unknown_data(pptr
,"\n\t ",ISIS_LSP_HEADER_SIZE
))
1339 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1340 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1345 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1346 printf(", bogus fixed header length %u should be %lu",
1347 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1351 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
1352 if (packet_len
>pdu_len
) {
1353 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1357 TCHECK(*header_csnp
);
1358 printf("\n\t source-id: %s, PDU length: %u",
1359 isis_print_nodeid(header_csnp
->source_id
),
1361 printf("\n\t start lsp-id: %s",
1362 isis_print_lspid(header_csnp
->start_lsp_id
));
1363 printf("\n\t end lsp-id: %s",
1364 isis_print_lspid(header_csnp
->end_lsp_id
));
1367 if(!print_unknown_data(pptr
,"\n\t ",ISIS_CSNP_HEADER_SIZE
))
1371 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1372 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1377 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1378 printf("- bogus fixed header length %u should be %lu",
1379 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1383 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1384 if (packet_len
>pdu_len
) {
1385 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1389 TCHECK(*header_psnp
);
1390 printf("\n\t source-id: %s",
1391 isis_print_nodeid(header_psnp
->source_id
));
1394 if(!print_unknown_data(pptr
,"\n\t ",ISIS_PSNP_HEADER_SIZE
))
1398 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1399 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1403 if(!print_unknown_data(pptr
,"\n\t ",length
))
1409 * Now print the TLV's.
1412 while (packet_len
>= 2) {
1413 if (pptr
== snapend
) {
1417 if (!TTEST2(*pptr
, 2)) {
1418 printf("\n\t\t packet exceeded snapshot (%ld) bytes",
1419 (long)(pptr
-snapend
));
1424 tmp
=len
; /* copy temporary len & pointer to packet data */
1427 if (len
> packet_len
) {
1431 /* first lets see if we know the TLVs name*/
1432 printf("\n\t %s TLV #%u, length: %u",
1433 tok2str(isis_tlv_values
,
1439 /* now check if we have a decoder otherwise do a hexdump at the end*/
1442 if (!TTEST2(*tptr
, 1))
1445 while (tmp
&& alen
< tmp
) {
1446 printf("\n\t\tArea address (length: %u): %s",
1448 print_nsap(tptr
, alen
));
1451 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1453 if (!TTEST2(*tptr
, 1))
1459 while (tmp
>= ETHER_ADDR_LEN
) {
1460 if (!TTEST2(*tptr
, ETHER_ADDR_LEN
))
1462 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,ETHER_ADDR_LEN
));
1463 tmp
-= ETHER_ADDR_LEN
;
1464 tptr
+= ETHER_ADDR_LEN
;
1468 case TLV_ISNEIGH_VARLEN
:
1469 if (!TTEST2(*tptr
, 1))
1471 lan_alen
= *tptr
++; /* LAN adress length */
1473 printf("\n\t\tLAN address length %u bytes ",lan_alen
);
1474 while (tmp
>= lan_alen
) {
1475 if (!TTEST2(*tptr
, lan_alen
))
1477 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,lan_alen
));
1486 case TLV_MT_IS_REACH
:
1488 if (!TTEST2(*tptr
, 2))
1491 tok2str(isis_mt_values
,
1492 "Reserved for IETF Consensus",
1493 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1495 printf(" Topology (0x%03x)",
1496 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1498 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1500 printf("\n\t\t IS Neighbor: %s", isis_print_nodeid(tptr
));
1501 tptr
+=(NODE_ID_LEN
);
1502 if (!TTEST2(*tptr
, 3))
1504 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1506 if (!TTEST2(*tptr
, 1))
1509 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1511 printf(" (%u)",tslen
);
1513 if (!TTEST2(*tptr
,2))
1517 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1524 tmp
-=(SYSTEM_ID_LEN
+7);
1528 case TLV_EXT_IS_REACH
:
1530 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1532 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1533 tptr
+=(NODE_ID_LEN
);
1535 if (!TTEST2(*tptr
, 3))
1537 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1540 if (!TTEST2(*tptr
, 1))
1542 tslen
=*(tptr
++); /* read out subTLV length */
1543 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1545 printf(" (%u)",tslen
);
1547 if (!TTEST2(*tptr
,2))
1551 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1558 tmp
-=(SYSTEM_ID_LEN
+5);
1562 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1565 tok2str(isis_is_reach_virtual_values
,
1566 "bogus virtual flag 0x%02x",
1568 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1569 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1570 if (!TTEST(*tlv_is_reach
))
1572 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1573 isis_print_metric_block(&tlv_is_reach
->isis_metric_block
);
1574 tmp
-= sizeof(struct isis_tlv_is_reach
);
1580 tlv_es_reach
= (const struct isis_tlv_es_reach
*)tptr
;
1581 while (tmp
>= sizeof(struct isis_tlv_es_reach
)) {
1582 if (!TTEST(*tlv_es_reach
))
1584 printf("\n\t\tES Neighbor: %s",
1585 isis_print_sysid(tlv_es_reach
->neighbor_sysid
,SYSTEM_ID_LEN
));
1586 isis_print_metric_block(&tlv_es_reach
->isis_metric_block
);
1587 tmp
-= sizeof(struct isis_tlv_es_reach
);
1592 /* those two TLVs share the same format */
1594 case TLV_IP_REACH_EXT
:
1595 if (!isis_print_tlv_ip_reach(pptr
, len
))
1599 case TLV_MT_IP_REACH
:
1601 if (!TTEST2(*tptr
, 2))
1605 tok2str(isis_mt_values
,
1606 "Reserved for IETF Consensus",
1607 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1609 printf(" Topology (0x%03x)",
1610 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1613 memset (prefix
, 0, 4);
1614 if (!TTEST2(*tptr
, 4))
1616 metric
= EXTRACT_32BITS(tptr
);
1619 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1622 bit_length
= (*(tptr
)++&0x3f);
1623 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1625 if (!TTEST2(*tptr
, byte_length
))
1627 memcpy(prefix
,tptr
,byte_length
);
1629 printf("\n\t\tIPv4 prefix: %s/%d",
1630 ipaddr_string(prefix
),
1633 printf("\n\t\t Metric: %u, Distribution: %s",
1635 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1637 printf(", %ssub-TLVs present",
1638 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1640 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1641 /* assume that one prefix can hold more
1642 than one subTLV - therefore the first byte must reflect
1643 the aggregate bytecount of the subTLVs for this prefix
1645 if (!TTEST2(*tptr
, 1))
1649 printf(" (%u)",tslen
); /* print out subTLV length */
1652 if (!TTEST2(*tptr
,2))
1656 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1663 tmp
-=(7+byte_length
);
1667 case TLV_EXT_IP_REACH
:
1669 memset (prefix
, 0, 4);
1670 if (!TTEST2(*tptr
, 4))
1672 metric
= EXTRACT_32BITS(tptr
);
1675 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1678 bit_length
= (*(tptr
)++&0x3f);
1679 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1681 if (!TTEST2(*tptr
, byte_length
))
1683 memcpy(prefix
,tptr
,byte_length
);
1685 printf("\n\t\tIPv4 prefix: %s/%d",
1686 ipaddr_string(prefix
),
1689 printf("\n\t\t Metric: %u, Distribution: %s",
1691 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1693 printf(", %ssub-TLVs present",
1694 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1696 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1697 /* assume that one prefix can hold more
1698 than one subTLV - therefore the first byte must reflect
1699 the aggregate bytecount of the subTLVs for this prefix
1701 if (!TTEST2(*tptr
, 1))
1705 printf(" (%u)",tslen
); /* print out subTLV length */
1708 if (!TTEST2(*tptr
,2))
1712 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1719 tmp
-=(5+byte_length
);
1727 if (!TTEST2(*tptr
, 4))
1729 metric
= EXTRACT_32BITS(tptr
);
1732 if (!TTEST2(*tptr
, 2))
1735 bit_length
= (*(tptr
)++);
1736 byte_length
= (bit_length
+ 7) / 8;
1737 if (!TTEST2(*tptr
, byte_length
))
1740 memset(prefix6
, 0, 16);
1741 memcpy(prefix6
,tptr
,byte_length
);
1743 printf("\n\t\tIPv6 prefix: %s/%u",
1744 ip6addr_string(prefix6
),
1747 printf("\n\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1749 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1750 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1751 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1753 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1754 /* assume that one prefix can hold more
1755 than one subTLV - therefore the first byte must reflect
1756 the aggregate bytecount of the subTLVs for this prefix
1758 if (!TTEST2(*tptr
, 1))
1762 printf(" (%u)",tslen
); /* print out subTLV length */
1765 if (!TTEST2(*tptr
,2))
1769 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1776 tmp
-=(6+byte_length
);
1785 if (!TTEST2(*tptr
, 16))
1788 printf("\n\t\tIPv6 interface address: %s",
1789 ip6addr_string(tptr
));
1797 if (!TTEST2(*tptr
, 1))
1800 printf("\n\t\t%s: ",
1801 tok2str(isis_subtlv_auth_values
,
1802 "unknown Authentication type 0x%02x",
1806 case SUBTLV_AUTH_SIMPLE
:
1807 for(i
=1;i
<len
;i
++) {
1808 if (!TTEST2(*(tptr
+i
), 1))
1810 printf("%c",*(tptr
+i
));
1813 case SUBTLV_AUTH_MD5
:
1814 for(i
=1;i
<len
;i
++) {
1815 if (!TTEST2(*(tptr
+i
), 1))
1817 printf("%02x",*(tptr
+i
));
1819 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1820 printf(", (malformed subTLV) ");
1822 case SUBTLV_AUTH_PRIVATE
:
1824 if(!print_unknown_data(tptr
+1,"\n\t\t ",len
-1))
1831 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1833 if (!TTEST2(*tptr
, 1))
1835 printf("\n\t\tAdjacency State: %s",
1836 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1839 if(tmp
>sizeof(tlv_ptp_adj
->extd_local_circuit_id
)) {
1840 if (!TTEST2(tlv_ptp_adj
->extd_local_circuit_id
,
1841 sizeof(tlv_ptp_adj
->extd_local_circuit_id
)))
1843 printf("\n\t\tExtended Local circuit ID: 0x%08x",
1844 EXTRACT_32BITS(tlv_ptp_adj
->extd_local_circuit_id
));
1845 tmp
-=sizeof(tlv_ptp_adj
->extd_local_circuit_id
);
1847 if(tmp
>=SYSTEM_ID_LEN
) {
1848 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, SYSTEM_ID_LEN
))
1850 printf("\n\t\tNeighbor SystemID: %s",
1851 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
,SYSTEM_ID_LEN
));
1854 if(tmp
>=sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)) {
1855 if (!TTEST2(tlv_ptp_adj
->neighbor_extd_local_circuit_id
,
1856 sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)))
1858 printf("\n\t\tNeighbor Extended Local circuit ID: 0x%08x",
1859 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_extd_local_circuit_id
));
1864 printf("\n\t\tNLPID(s): ");
1866 if (!TTEST2(*(tptr
), 1))
1869 tok2str(osi_nlpid_values
,
1872 if (tmp
>1) /* further NPLIDs ? - put comma */
1878 case TLV_TE_ROUTER_ID
:
1879 if (!TTEST2(*pptr
, 4))
1881 printf("\n\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1886 if (!TTEST2(*tptr
, 4))
1888 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1895 printf("\n\t\tHostname: ");
1897 if (!TTEST2(*tptr
, 1))
1899 printf("%c",*tptr
++);
1904 case TLV_SHARED_RISK_GROUP
:
1905 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1907 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1908 tptr
+=(NODE_ID_LEN
);
1911 if (!TTEST2(*tptr
, 1))
1913 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1916 if (!TTEST2(*tptr
,4))
1918 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1922 if (!TTEST2(*tptr
,4))
1924 printf("\n\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1929 if (!TTEST2(*tptr
, 4))
1931 printf("\n\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1938 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1940 printf("\n\t\tlsp-id: %s",
1941 isis_print_nodeid(tlv_lsp
->lsp_id
));
1942 if (!TTEST((tlv_lsp
->lsp_id
)[NODE_ID_LEN
]))
1944 printf("-%02x",(tlv_lsp
->lsp_id
)[NODE_ID_LEN
]);
1945 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1947 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1948 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1950 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1951 if (!TTEST2(tlv_lsp
->checksum
, 2))
1953 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1954 tmp
-=sizeof(struct isis_tlv_lsp
);
1960 if (!TTEST2(*tptr
, 2))
1962 printf("\n\t\tchecksum: 0x%04x (%s)",
1963 EXTRACT_16BITS(tptr
),
1964 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1967 case TLV_MT_SUPPORTED
:
1969 /* length can only be a multiple of 2, otherwise there is
1970 something broken -> so decode down until length is 1 */
1972 if (!TTEST2(*tptr
, 2))
1975 tok2str(isis_mt_values
,
1976 "Reserved for IETF Consensus",
1977 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1979 printf(" Topology (0x%03x)%s%s",
1980 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1981 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1982 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1984 printf("\n\t\tmalformed MT-ID");
1992 case TLV_RESTART_SIGNALING
:
1993 if (!TTEST2(*tptr
, 3))
1995 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1996 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1998 time_remain
= EXTRACT_16BITS(tptr
);
1999 printf("\n\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\tRemaining holding time: %us",
2000 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
2004 if (!TTEST2(*tptr
, 1))
2006 printf("\n\t\tInter-Domain Information Type: %s",
2007 tok2str(isis_subtlv_idrp_values
,
2011 case SUBTLV_IDRP_ASN
:
2012 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
2014 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
2016 case SUBTLV_IDRP_LOCAL
:
2017 case SUBTLV_IDRP_RES
:
2019 if(!print_unknown_data(tptr
,"\n\t\t",len
-1))
2025 case TLV_LSP_BUFFERSIZE
:
2026 if (!TTEST2(*tptr
, 2))
2028 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr
));
2032 while (tmp
>= SYSTEM_ID_LEN
) {
2033 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
))
2035 printf("%s",isis_print_sysid(tptr
,SYSTEM_ID_LEN
));
2036 tptr
+=SYSTEM_ID_LEN
;
2041 case TLV_PREFIX_NEIGH
:
2042 if (!TTEST2(*tptr
, sizeof(struct isis_metric_block
)))
2044 printf("Metric Block");
2045 isis_print_metric_block((const struct isis_metric_block
*)tptr
);
2046 tptr
+=sizeof(struct isis_metric_block
);
2047 tmp
-=sizeof(struct isis_metric_block
);
2050 if (!TTEST2(*tptr
, 1))
2052 prefix_len
=*tptr
++; /* read out prefix length in semioctets*/
2054 if (!TTEST2(*tptr
, prefix_len
/2))
2056 printf("\n\t\tAddress: %s/%u",
2057 print_nsap(tptr
,prefix_len
/2),
2065 if (!TTEST2(*tptr
, 4)) /* check if four bytes are on the wire */
2067 printf("\n\t\tSequence number: %u", EXTRACT_32BITS(tptr
) );
2071 * FIXME those are the defined TLVs that lack a decoder
2072 * you are welcome to contribute code ;-)
2075 case TLV_IS_ALIAS_ID
:
2076 case TLV_DECNET_PHASE4
:
2077 case TLV_LUCENT_PRIVATE
:
2079 case TLV_NORTEL_PRIVATE1
:
2080 case TLV_NORTEL_PRIVATE2
:
2081 case TLV_MT_IP6_REACH
:
2085 if(!print_unknown_data(pptr
,"\n\t\t",len
))
2090 /* do we want to see an additionally hexdump ? */
2092 if(!print_unknown_data(pptr
,"\n\t\t",len
))
2100 if (packet_len
!= 0) {
2101 printf("\n\t\t %d straggler bytes", packet_len
);
2106 fputs("[|isis]", stdout
);
2110 printf("\n\t\t packet exceeded snapshot");
2115 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2119 osi_cksum(const u_char
*tptr
, u_int len
)
2121 int32_t c0
= 0, c1
= 0;
2123 while ((int)--len
>= 0) {