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.55 2002-07-25 09:00:42 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 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
*cp
, register int length
)
443 static char nsap
[33];
452 for (i
= 0; i
< length
; i
++) {
455 pos
+=sprintf(pos
, "%02x", *cp
++);
456 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
457 pos
+=sprintf(pos
, ".");
464 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
465 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
466 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
467 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
468 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
469 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
471 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
472 const u_char
*esrc
, const u_char
*edst
)
475 const struct isis_common_header
*header
;
477 header
= (const struct isis_common_header
*)p
;
478 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
481 printf("[|iso-clns] ");
482 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
484 etheraddr_string(esrc
),
485 etheraddr_string(edst
));
492 (void)printf("CLNS(%d)", length
);
493 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
494 (void)printf(", %s > %s",
495 etheraddr_string(esrc
),
496 etheraddr_string(edst
));
500 (void)printf("ESIS(%u)", length
);
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 (void)printf("ISIS(%u)", length
);
510 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
511 (void)printf(", %s > %s",
512 etheraddr_string(esrc
),
513 etheraddr_string(edst
));
514 if (!isis_print(p
, length
))
515 default_print_unaligned(p
, caplen
);
519 (void)printf("ISO NULLNS(%d)", length
);
520 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
521 (void)printf(", %s > %s",
522 etheraddr_string(esrc
),
523 etheraddr_string(edst
));
527 (void)printf("CLNS %02x(%d)", p
[0], length
);
528 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
529 (void)printf(", %s > %s",
530 etheraddr_string(esrc
),
531 etheraddr_string(edst
));
533 default_print_unaligned(p
, caplen
);
538 #define ESIS_REDIRECT 6
551 esis_print(const u_char
*p
, u_int length
)
555 const struct esis_hdr
*eh
;
561 printf(" no header at all!");
565 eh
= (const struct esis_hdr
*) &p
[2];
571 printf(" LI(%d) > PDU size (%d)!", li
, length
);
574 if (li
< sizeof(struct esis_hdr
) + 2) {
578 printf(" too short for esis header %d:", li
);
579 while (--length
!= 0)
580 printf("%02X", *p
++);
584 switch (eh
->type
& 0x1f) {
599 printf(" type %d", eh
->type
& 0x1f);
602 if (vflag
&& osi_cksum(p
, li
)) {
603 printf(" bad cksum (got 0x%02x%02x)",
604 eh
->cksum
[1], eh
->cksum
[0]);
605 default_print(p
, length
);
608 if (eh
->version
!= 1) {
609 printf(" unsupported version %d", eh
->version
);
612 p
+= sizeof(*eh
) + 2;
613 li
-= sizeof(*eh
) + 2; /* protoid * li */
615 switch (eh
->type
& 0x1f) {
616 case ESIS_REDIRECT
: {
617 const u_char
*dst
, *snpa
, *is
;
619 dst
= p
; p
+= *p
+ 1;
622 printf("\n\t\t %s", isonsap_string(dst
));
623 snpa
= p
; p
+= *p
+ 1;
632 printf(" > %s", etheraddr_string(&snpa
[1]));
634 printf(" > %s", isonsap_string(is
));
654 printf("\n\tNET: %s", print_nsap(is
+1,*is
));
660 (void)printf(" len=%d", length
);
661 if (length
&& p
< snapend
) {
662 length
= snapend
- p
;
663 default_print(p
, length
);
668 while (p
< ep
&& li
) {
675 printf(" bad opts/li");
682 printf(" opt (%d) too long", op
);
690 if (op
== 198 && opli
== 2) {
691 printf(" tmo=%d", q
[0] * 256 + q
[1]);
694 printf (" %d:<", op
);
696 printf("%02x", *q
++);
701 /* allocate space for the following string
703 * 14 bytes plus one termination byte */
705 isis_print_sysid(const u_char
*cp
, int sysid_len
)
708 static char sysid
[15];
711 for (i
= 1; i
<= sysid_len
; i
++) {
714 pos
+=sprintf(pos
, "%02x", *cp
++);
716 pos
+=sprintf(pos
, ".");
724 /* allocate space for the following string
726 * 17 bytes plus one termination byte */
728 isis_print_nodeid(const u_char
*cp
)
731 static char nodeid
[18];
734 for (i
= 1; i
<= 7; i
++) {
737 pos
+=sprintf(pos
, "%02x", *cp
++);
739 pos
+=sprintf(pos
, ".");
746 /* allocate space for the following string
747 * xxxx.xxxx.xxxx.yy-zz
748 * 20 bytes plus one termination byte */
750 isis_print_lspid(const u_char
*cp
)
753 static char lspid
[21];
756 for (i
= 1; i
<= 7; i
++) {
757 pos
+=sprintf(pos
, "%02x", *cp
++);
759 pos
+=sprintf(pos
, ".");
761 pos
+=sprintf(pos
, "-%02x", *cp
);
765 /* print the 4-byte metric block which is common found in the old-style TLVs */
768 isis_print_metric_block (const struct isis_metric_block
*isis_metric_block
)
770 printf(", Default Metric: %d, %s",
771 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_default
),
772 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_default
) ? "External" : "Internal");
773 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_delay
))
774 printf("\n\t\t Delay Metric: %d, %s",
775 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_delay
),
776 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_delay
) ? "External" : "Internal");
777 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_expense
))
778 printf("\n\t\t Expense Metric: %d, %s",
779 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_expense
),
780 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_expense
) ? "External" : "Internal");
781 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_error
))
782 printf("\n\t\t Error Metric: %d, %s",
783 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_error
),
784 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_error
) ? "External" : "Internal");
786 return(1); /* everything is ok */
790 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
792 u_int bitmasks
[33] = {
794 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
795 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
796 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
797 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
798 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
799 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
800 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
801 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
805 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
807 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
810 if (length
< sizeof(*tlv_ip_reach
)) {
811 printf("short IPv4 reachability (%d vs %lu)", length
,
812 (unsigned long)sizeof(*tlv_ip_reach
));
816 if (!TTEST(*tlv_ip_reach
))
819 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
822 /* lets see if we can transform the mask into a prefixlen */
823 while (prefix_len
<= 33) {
824 if (bitmasks
[prefix_len
++] == mask
) {
831 * 34 indicates no match -> must be a discontiguous netmask
832 * lets dump the mask, otherwise print the prefix_len
834 if (prefix_len
== 34)
835 printf("\n\t\tIPv4 prefix: %s mask %s",
836 ipaddr_string((tlv_ip_reach
->prefix
)),
837 ipaddr_string((tlv_ip_reach
->mask
)));
839 printf("\n\t\tIPv4 prefix: %s/%u",
840 ipaddr_string((tlv_ip_reach
->prefix
)),
843 printf("\n\t\t Default Metric: %02d, %s, Distribution: %s",
844 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_default
),
845 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "External" : "Internal",
846 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "down" : "up");
848 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_delay
))
849 printf("\n\t\t Delay Metric: %02d, %s",
850 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_delay
),
851 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_delay
) ? "External" : "Internal");
853 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_expense
))
854 printf("\n\t\t Expense Metric: %02d, %s",
855 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_expense
),
856 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_expense
) ? "External" : "Internal");
858 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_error
))
859 printf("\n\t\t Error Metric: %02d, %s",
860 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_error
),
861 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_error
) ? "External" : "Internal");
863 length
-= sizeof(struct isis_tlv_ip_reach
);
870 * this is the common IP-REACH subTLV decoder it is called
871 * from various EXTD-IP REACH TLVs (135,235,236,237)
875 isis_print_ip_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
878 case SUBTLV_IP_REACH_ADMIN_TAG32
:
879 if (!TTEST2(*tptr
,4))
881 printf("%s32-Bit Administrative tag: 0x%08x",
883 EXTRACT_32BITS(tptr
));
885 case SUBTLV_IP_REACH_ADMIN_TAG64
:
886 if (!TTEST2(*tptr
,8))
888 printf("%s64-Bit Administrative tag: 0x%08x%08x",
890 EXTRACT_32BITS(tptr
),
891 EXTRACT_32BITS(tptr
+4));
894 printf("%sunknown subTLV, type %d, length %d",
898 if(!print_unknown_data(tptr
,"\n\t\t ",
906 printf("%spacket exceeded snapshot",lf
);
911 * this is the common IS-REACH subTLV decoder it is called
912 * from various EXTD-IS REACH TLVs (22,24,222)
916 isis_print_is_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
919 float bw
; /* copy buffer for several subTLVs */
922 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
923 if (!TTEST2(*tptr
,4))
925 printf("%sAdministrative groups: 0x%08x",
927 EXTRACT_32BITS(tptr
));
929 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
930 if (!TTEST2(*tptr
,4))
932 printf("%sLink Local Identifier: 0x%08x",
934 EXTRACT_32BITS(tptr
));
936 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
937 if (!TTEST2(*tptr
,4))
939 printf("%sLink Remote Identifier: 0x%08x",
941 EXTRACT_32BITS(tptr
));
943 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
944 if (!TTEST2(*tptr
,4))
946 j
= EXTRACT_32BITS(tptr
);
948 printf("%sMaximum link bandwidth : %.3f Mbps",
952 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
953 if (!TTEST2(*tptr
,4))
955 j
= EXTRACT_32BITS(tptr
);
957 printf("%sReservable link bandwidth: %.3f Mbps",
961 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
962 printf("%sUnreserved bandwidth:",lf
);
963 for (i
= 0; i
< 8; i
++) {
964 if (!TTEST2(*(tptr
+i
*4),4))
966 j
= EXTRACT_32BITS(tptr
);
968 printf("%s priority level %d: %.3f Mbps",
974 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
975 if (!TTEST2(*tptr
,3))
977 printf("%sTraffic Engineering Metric: %d",
979 EXTRACT_24BITS(tptr
));
981 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
982 if (!TTEST2(*tptr
,4))
984 printf("%sIPv4 interface address: %s",
986 ipaddr_string(tptr
));
988 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
989 if (!TTEST2(*tptr
,4))
991 printf("%sIPv4 neighbor address: %s",
993 ipaddr_string(tptr
));
995 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE
:
996 if (!TTEST2(*tptr
,2))
999 j
= (ISIS_8BIT_MASK(*tptr
)); /* fetch the typecode and make sure
1000 that no high-order LSBs are set */
1001 printf("%sLink Protection Type: %s",
1003 (j
) ? "" : "none" );
1004 /* scan through the bits until the typecode is zero */
1006 printf("%s", isis_gmpls_link_prot_values
[i
]);
1008 if (j
) /*any other bit set ?*/
1012 printf(", Priority %u", *(tptr
+1));
1014 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
1015 printf("%sInterface Switching Capability",lf
);
1017 if (!TTEST2(*tptr
,1))
1019 printf("%s Interface Switching Capability:%s",
1021 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1023 if (!TTEST2(*(tptr
+1),1))
1025 printf(", LSP Encoding: %s",
1026 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1028 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1031 printf("%s Max LSP Bandwidth:",lf
);
1032 for (i
= 0; i
< 8; i
++) {
1033 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1035 j
= EXTRACT_32BITS(tptr
);
1036 memcpy (&bw
, &j
, 4);
1037 printf("%s priority level %d: %.3f Mbps",
1043 /* there is some optional stuff left to decode but this is as of yet
1044 not specified so just lets hexdump what is left */
1046 if(!print_unknown_data(tptr
,"\n\t\t ",
1056 printf("%sReserved for cisco specific extensions, type %d, length %d",
1062 printf("%sReserved for future expansion, type %d, length %d",
1068 printf("%sunknown subTLV, type %d, length %d",
1072 if(!print_unknown_data(tptr
,"\n\t\t ",
1080 printf("%spacket exceeded snapshot",lf
);
1087 * Decode IS-IS packets. Return 0 on error.
1090 static int isis_print (const u_char
*p
, u_int length
)
1092 const struct isis_common_header
*header
;
1094 const struct isis_iih_lan_header
*header_iih_lan
;
1095 const struct isis_iih_ptp_header
*header_iih_ptp
;
1096 const struct isis_lsp_header
*header_lsp
;
1097 const struct isis_csnp_header
*header_csnp
;
1098 const struct isis_psnp_header
*header_psnp
;
1100 const struct isis_tlv_lsp
*tlv_lsp
;
1101 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1102 const struct isis_tlv_is_reach
*tlv_is_reach
;
1103 const struct isis_tlv_es_reach
*tlv_es_reach
;
1105 u_char pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, lan_alen
, prefix_len
, subl
, subt
, tslen
;
1106 const u_char
*optr
, *pptr
, *tptr
;
1107 u_short packet_len
,pdu_len
,time_remain
;
1108 u_int i
,j
,bit_length
,byte_length
,metric
,ra
,rr
;
1109 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
1111 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
1114 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1115 need it for parsing the checksum TLV */
1116 header
= (const struct isis_common_header
*)p
;
1118 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1119 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1120 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1121 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1122 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1123 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1126 * Sanity checking of the header.
1128 if (header
->nlpid
!= NLPID_ISIS
) {
1129 printf(", coding error!");
1133 if (header
->version
!= ISIS_VERSION
) {
1134 printf(", version %d packet not supported", header
->version
);
1138 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1139 printf(", system ID length of %d is not supported",
1144 if (header
->pdu_version
!= ISIS_VERSION
) {
1145 printf(", version %d packet not supported", header
->pdu_version
);
1149 max_area
= header
->max_area
;
1152 max_area
= 3; /* silly shit */
1155 printf(", bad packet -- 255 areas");
1161 id_length
= header
->id_length
;
1164 id_length
= 6; /* silly shit again */
1166 case 1: /* 1-8 are valid sys-ID lenghts */
1176 id_length
= 0; /* entirely useless */
1179 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1184 printf("\n\thlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1187 header
->pdu_version
,
1193 pdu_type
=header
->pdu_type
;
1195 /* first lets see if we know the PDU name*/
1196 printf(", pdu-type: %s",
1197 tok2str(isis_pdu_values
,
1205 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1206 printf(", bogus fixed header length %u should be %lu",
1207 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1211 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1212 if (packet_len
>pdu_len
) {
1213 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1217 TCHECK(*header_iih_lan
);
1218 printf("\n\t source-id: %s, holding time: %u, %s",
1219 isis_print_sysid(header_iih_lan
->source_id
,SYSTEM_ID_LEN
),
1220 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1221 tok2str(isis_iih_circuit_type_values
,
1222 "unknown circuit type 0x%02x",
1223 header_iih_lan
->circuit_type
));
1225 printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
1226 isis_print_nodeid(header_iih_lan
->lan_id
),
1227 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1230 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1231 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1235 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1236 printf(", bogus fixed header length %u should be %lu",
1237 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1241 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->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_ptp
);
1248 printf("\n\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1249 isis_print_sysid(header_iih_ptp
->source_id
,SYSTEM_ID_LEN
),
1250 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1251 header_iih_ptp
->circuit_id
,
1252 tok2str(isis_iih_circuit_type_values
,
1253 "unknown circuit type 0x%02x",
1254 header_iih_ptp
->circuit_type
),
1257 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1258 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1263 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1264 printf(", bogus fixed header length %u should be %lu",
1265 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1269 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1270 if (packet_len
>pdu_len
) {
1271 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1275 TCHECK(*header_lsp
);
1276 printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1277 isis_print_lspid(header_lsp
->lsp_id
),
1278 EXTRACT_32BITS(header_lsp
->sequence_number
),
1279 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1280 /* verify the checksum -
1281 * checking starts at the lsp-id field
1282 * which is 12 bytes after the packet start*/
1283 printf("\n\t chksum: 0x%04x (%s), PDU length: %u",
1284 EXTRACT_16BITS(header_lsp
->checksum
),
1285 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1288 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1290 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1291 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1292 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1293 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1294 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1295 printf("ATT bit set, ");
1297 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1298 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1300 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1301 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1306 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1307 printf(", bogus fixed header length %u should be %lu",
1308 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1312 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
1313 if (packet_len
>pdu_len
) {
1314 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1318 TCHECK(*header_csnp
);
1319 printf("\n\t source-id: %s, PDU length: %u",
1320 isis_print_nodeid(header_csnp
->source_id
),
1322 printf("\n\t start lsp-id: %s",
1323 isis_print_lspid(header_csnp
->start_lsp_id
));
1324 printf("\n\t end lsp-id: %s",
1325 isis_print_lspid(header_csnp
->end_lsp_id
));
1327 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1328 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1333 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1334 printf("- bogus fixed header length %u should be %lu",
1335 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1339 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1340 if (packet_len
>pdu_len
) {
1341 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1345 TCHECK(*header_psnp
);
1346 printf("\n\t source-id: %s",
1347 isis_print_nodeid(header_psnp
->source_id
));
1349 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1350 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1354 if(!print_unknown_data(pptr
,"\n\t ",length
))
1360 * Now print the TLV's.
1363 while (packet_len
>= 2) {
1364 if (pptr
== snapend
) {
1368 if (!TTEST2(*pptr
, 2)) {
1369 printf("\n\t\t packet exceeded snapshot (%ld) bytes",
1370 (long)(pptr
-snapend
));
1375 tmp
=len
; /* copy temporary len & pointer to packet data */
1378 if (len
> packet_len
) {
1382 /* first lets see if we know the TLVs name*/
1383 printf("\n\t %s TLV #%u, length: %u",
1384 tok2str(isis_tlv_values
,
1390 /* now check if we have a decoder otherwise do a hexdump at the end*/
1393 if (!TTEST2(*tptr
, 1))
1396 while (tmp
&& alen
< tmp
) {
1397 printf("\n\t\tArea address (%u): %s",
1399 print_nsap(tptr
, alen
));
1402 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1404 if (!TTEST2(*tptr
, 1))
1410 while (tmp
>= ETHER_ADDR_LEN
) {
1411 if (!TTEST2(*tptr
, ETHER_ADDR_LEN
))
1413 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,ETHER_ADDR_LEN
));
1414 tmp
-= ETHER_ADDR_LEN
;
1415 tptr
+= ETHER_ADDR_LEN
;
1419 case TLV_ISNEIGH_VARLEN
:
1420 if (!TTEST2(*tptr
, 1))
1422 lan_alen
= *tptr
++; /* LAN adress length */
1424 printf("\n\t\tLAN address length %u bytes ",lan_alen
);
1425 while (tmp
>= lan_alen
) {
1426 if (!TTEST2(*tptr
, lan_alen
))
1428 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,lan_alen
));
1437 case TLV_MT_IS_REACH
:
1439 if (!TTEST2(*tptr
, 2))
1442 tok2str(isis_mt_values
,
1443 "Reserved for IETF Consensus",
1444 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1446 printf(" Topology (0x%03x)",
1447 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1449 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1451 printf("\n\t\t IS Neighbor: %s", isis_print_nodeid(tptr
));
1452 tptr
+=(NODE_ID_LEN
);
1453 if (!TTEST2(*tptr
, 3))
1455 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1457 if (!TTEST2(*tptr
, 1))
1460 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1462 printf(" (%u)",tslen
);
1464 if (!TTEST2(*tptr
,2))
1468 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1475 tmp
-=(SYSTEM_ID_LEN
+7);
1479 case TLV_EXT_IS_REACH
:
1481 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1483 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1484 tptr
+=(NODE_ID_LEN
);
1486 if (!TTEST2(*tptr
, 3))
1488 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1491 if (!TTEST2(*tptr
, 1))
1493 tslen
=*(tptr
++); /* read out subTLV length */
1494 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1496 printf(" (%u)",tslen
);
1498 if (!TTEST2(*tptr
,2))
1502 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1509 tmp
-=(SYSTEM_ID_LEN
+5);
1513 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1516 tok2str(isis_is_reach_virtual_values
,
1517 "bogus virtual flag 0x%02x",
1519 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1520 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1521 if (!TTEST(*tlv_is_reach
))
1523 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1524 isis_print_metric_block(&tlv_is_reach
->isis_metric_block
);
1525 tmp
-= sizeof(struct isis_tlv_is_reach
);
1531 tlv_es_reach
= (const struct isis_tlv_es_reach
*)tptr
;
1532 while (tmp
>= sizeof(struct isis_tlv_es_reach
)) {
1533 if (!TTEST(*tlv_es_reach
))
1535 printf("\n\t\tES Neighbor: %s",
1536 isis_print_sysid(tlv_es_reach
->neighbor_sysid
,SYSTEM_ID_LEN
));
1537 isis_print_metric_block(&tlv_es_reach
->isis_metric_block
);
1538 tmp
-= sizeof(struct isis_tlv_es_reach
);
1543 /* those two TLVs share the same format */
1545 case TLV_IP_REACH_EXT
:
1546 if (!isis_print_tlv_ip_reach(pptr
, len
))
1550 case TLV_MT_IP_REACH
:
1552 if (!TTEST2(*tptr
, 2))
1556 tok2str(isis_mt_values
,
1557 "Reserved for IETF Consensus",
1558 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1560 printf(" Topology (0x%03x)",
1561 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1564 memset (prefix
, 0, 4);
1565 if (!TTEST2(*tptr
, 4))
1567 metric
= EXTRACT_32BITS(tptr
);
1570 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1573 bit_length
= (*(tptr
)++&0x3f);
1574 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1576 if (!TTEST2(*tptr
, byte_length
))
1578 memcpy(prefix
,tptr
,byte_length
);
1580 printf("\n\t\tIPv4 prefix: %s/%d",
1581 ipaddr_string(prefix
),
1584 printf("\n\t\t Metric: %u, Distribution: %s",
1586 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1588 printf(", %ssub-TLVs present",
1589 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1591 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1592 /* assume that one prefix can hold more
1593 than one subTLV - therefore the first byte must reflect
1594 the aggregate bytecount of the subTLVs for this prefix
1596 if (!TTEST2(*tptr
, 1))
1600 printf(" (%u)",tslen
); /* print out subTLV length */
1603 if (!TTEST2(*tptr
,2))
1607 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1614 tmp
-=(7+byte_length
);
1618 case TLV_EXT_IP_REACH
:
1620 memset (prefix
, 0, 4);
1621 if (!TTEST2(*tptr
, 4))
1623 metric
= EXTRACT_32BITS(tptr
);
1626 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1629 bit_length
= (*(tptr
)++&0x3f);
1630 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1632 if (!TTEST2(*tptr
, byte_length
))
1634 memcpy(prefix
,tptr
,byte_length
);
1636 printf("\n\t\tIPv4 prefix: %s/%d",
1637 ipaddr_string(prefix
),
1640 printf("\n\t\t Metric: %u, Distribution: %s",
1642 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1644 printf(", %ssub-TLVs present",
1645 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1647 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1648 /* assume that one prefix can hold more
1649 than one subTLV - therefore the first byte must reflect
1650 the aggregate bytecount of the subTLVs for this prefix
1652 if (!TTEST2(*tptr
, 1))
1656 printf(" (%u)",tslen
); /* print out subTLV length */
1659 if (!TTEST2(*tptr
,2))
1663 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1670 tmp
-=(5+byte_length
);
1678 if (!TTEST2(*tptr
, 4))
1680 metric
= EXTRACT_32BITS(tptr
);
1683 if (!TTEST2(*tptr
, 2))
1686 bit_length
= (*(tptr
)++);
1687 byte_length
= (bit_length
+ 7) / 8;
1688 if (!TTEST2(*tptr
, byte_length
))
1691 memset(prefix6
, 0, 16);
1692 memcpy(prefix6
,tptr
,byte_length
);
1694 printf("\n\t\tIPv6 prefix: %s/%u",
1695 ip6addr_string(prefix6
),
1698 printf("\n\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1700 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1701 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1702 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1704 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1705 /* assume that one prefix can hold more
1706 than one subTLV - therefore the first byte must reflect
1707 the aggregate bytecount of the subTLVs for this prefix
1709 if (!TTEST2(*tptr
, 1))
1713 printf(" (%u)",tslen
); /* print out subTLV length */
1716 if (!TTEST2(*tptr
,2))
1720 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t "))
1727 tmp
-=(6+byte_length
);
1736 if (!TTEST2(*tptr
, 16))
1739 printf("\n\t\tIPv6 interface address: %s",
1740 ip6addr_string(tptr
));
1748 if (!TTEST2(*tptr
, 1))
1751 printf("\n\t\t%s: ",
1752 tok2str(isis_subtlv_auth_values
,
1753 "unknown Authentication type 0x%02x",
1757 case SUBTLV_AUTH_SIMPLE
:
1758 for(i
=1;i
<len
;i
++) {
1759 if (!TTEST2(*(tptr
+i
), 1))
1761 printf("%c",*(tptr
+i
));
1764 case SUBTLV_AUTH_MD5
:
1765 for(i
=1;i
<len
;i
++) {
1766 if (!TTEST2(*(tptr
+i
), 1))
1768 printf("%02x",*(tptr
+i
));
1770 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1771 printf(", (malformed subTLV) ");
1773 case SUBTLV_AUTH_PRIVATE
:
1775 if(!print_unknown_data(tptr
+1,"\n\t\t ",len
-1))
1782 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1784 if (!TTEST2(*tptr
, 1))
1786 printf("\n\t\tAdjacency State: %s",
1787 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1790 if(tmp
>sizeof(tlv_ptp_adj
->extd_local_circuit_id
)) {
1791 if (!TTEST2(tlv_ptp_adj
->extd_local_circuit_id
,
1792 sizeof(tlv_ptp_adj
->extd_local_circuit_id
)))
1794 printf("\n\t\tExtended Local circuit ID: 0x%08x",
1795 EXTRACT_32BITS(tlv_ptp_adj
->extd_local_circuit_id
));
1796 tmp
-=sizeof(tlv_ptp_adj
->extd_local_circuit_id
);
1798 if(tmp
>=SYSTEM_ID_LEN
) {
1799 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, SYSTEM_ID_LEN
))
1801 printf("\n\t\tNeighbor SystemID: %s",
1802 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
,SYSTEM_ID_LEN
));
1805 if(tmp
>=sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)) {
1806 if (!TTEST2(tlv_ptp_adj
->neighbor_extd_local_circuit_id
,
1807 sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)))
1809 printf("\n\t\tNeighbor Extended Local circuit ID: 0x%08x",
1810 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_extd_local_circuit_id
));
1815 printf("\n\t\tNLPID(s): ");
1817 if (!TTEST2(*(tptr
), 1))
1820 tok2str(isis_nlpid_values
,
1823 if (tmp
>1) /* further NPLIDs ? - put comma */
1829 case TLV_TE_ROUTER_ID
:
1830 if (!TTEST2(*pptr
, 4))
1832 printf("\n\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1837 if (!TTEST2(*tptr
, 4))
1839 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1846 printf("\n\t\tHostname: ");
1848 if (!TTEST2(*tptr
, 1))
1850 printf("%c",*tptr
++);
1855 case TLV_SHARED_RISK_GROUP
:
1856 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1858 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1859 tptr
+=(NODE_ID_LEN
);
1862 if (!TTEST2(*tptr
, 1))
1864 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1867 if (!TTEST2(*tptr
,4))
1869 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1873 if (!TTEST2(*tptr
,4))
1875 printf("\n\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1880 if (!TTEST2(*tptr
, 4))
1882 printf("\n\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1889 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1891 printf("\n\t\tlsp-id: %s",
1892 isis_print_nodeid(tlv_lsp
->lsp_id
));
1893 if (!TTEST((tlv_lsp
->lsp_id
)[NODE_ID_LEN
]))
1895 printf("-%02x",(tlv_lsp
->lsp_id
)[NODE_ID_LEN
]);
1896 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1898 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1899 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1901 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1902 if (!TTEST2(tlv_lsp
->checksum
, 2))
1904 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1905 tmp
-=sizeof(struct isis_tlv_lsp
);
1911 if (!TTEST2(*tptr
, 2))
1913 printf("\n\t\tchecksum: 0x%04x (%s)",
1914 EXTRACT_16BITS(tptr
),
1915 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1918 case TLV_MT_SUPPORTED
:
1920 /* length can only be a multiple of 2, otherwise there is
1921 something broken -> so decode down until length is 1 */
1923 if (!TTEST2(*tptr
, 2))
1926 tok2str(isis_mt_values
,
1927 "Reserved for IETF Consensus",
1928 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1930 printf(" Topology (0x%03x)%s%s",
1931 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1932 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1933 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1935 printf("\n\t\tmalformed MT-ID");
1943 case TLV_RESTART_SIGNALING
:
1944 if (!TTEST2(*tptr
, 3))
1946 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1947 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1949 time_remain
= EXTRACT_16BITS(tptr
);
1950 printf("\n\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\tRemaining holding time: %us",
1951 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
1955 if (!TTEST2(*tptr
, 1))
1957 printf("\n\t\tInter-Domain Information Type: %s",
1958 tok2str(isis_subtlv_idrp_values
,
1962 case SUBTLV_IDRP_ASN
:
1963 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
1965 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
1967 case SUBTLV_IDRP_LOCAL
:
1968 case SUBTLV_IDRP_RES
:
1970 if(!print_unknown_data(tptr
,"\n\t\t",len
-1))
1976 case TLV_LSP_BUFFERSIZE
:
1977 if (!TTEST2(*tptr
, 2))
1979 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr
));
1983 while (tmp
>= SYSTEM_ID_LEN
) {
1984 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
))
1986 printf("%s",isis_print_sysid(tptr
,SYSTEM_ID_LEN
));
1987 tptr
+=SYSTEM_ID_LEN
;
1992 case TLV_PREFIX_NEIGH
:
1993 if (!TTEST2(*tptr
, sizeof(struct isis_metric_block
)))
1995 printf("Metric Block");
1996 isis_print_metric_block((const struct isis_metric_block
*)tptr
);
1997 tptr
+=sizeof(struct isis_metric_block
);
1998 tmp
-=sizeof(struct isis_metric_block
);
2001 if (!TTEST2(*tptr
, 1))
2003 prefix_len
=*tptr
++; /* read out prefix length in semioctets*/
2005 if (!TTEST2(*tptr
, prefix_len
/2))
2007 printf("\n\t\tAddress: %s/%u",
2008 print_nsap(tptr
,prefix_len
/2),
2016 * FIXME those are the defined TLVs that lack a decoder
2017 * you are welcome to contribute code ;-)
2020 case TLV_IS_ALIAS_ID
:
2021 case TLV_DECNET_PHASE4
:
2022 case TLV_LUCENT_PRIVATE
:
2024 case TLV_NORTEL_PRIVATE1
:
2025 case TLV_NORTEL_PRIVATE2
:
2026 case TLV_MT_IP6_REACH
:
2029 if(!print_unknown_data(pptr
,"\n\t\t",len
))
2038 if (packet_len
!= 0) {
2039 printf("\n\t\t %d straggler bytes", packet_len
);
2044 fputs("[|isis]", stdout
);
2048 printf("\n\t\t packet exceeded snapshot");
2053 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2057 osi_cksum(const u_char
*tptr
, u_int len
)
2059 int32_t c0
= 0, c1
= 0;
2061 while ((int)--len
>= 0) {