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.48 2002-05-25 15:11:37 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 ISIS_VERSION 1
64 #define PDU_TYPE_MASK 0x1F
65 #define PRIORITY_MASK 0x7F
77 static struct tok isis_pdu_values
[] = {
78 { L1_LAN_IIH
, "L1 Lan IIH"},
79 { L2_LAN_IIH
, "L2 Lan IIH"},
80 { PTP_IIH
, "p2p IIH"},
83 { L1_CSNP
, "L1 CSNP"},
84 { L2_CSNP
, "L2 CSNP"},
85 { L1_PSNP
, "L1 PSNP"},
86 { L2_PSNP
, "L2 PSNP"},
91 * A TLV is a tuple of a type, length and a value and is normally used for
92 * encoding information in all sorts of places. This is an enumeration of
93 * the well known types.
95 * list taken from draft-ietf-isis-wg-tlv-codepoints-01.txt
98 #define TLV_AREA_ADDR 1
99 #define TLV_IS_REACH 2
100 #define TLV_ESNEIGH 3
101 #define TLV_PART_DIS 4
102 #define TLV_SUMMARY 5
103 #define TLV_ISNEIGH 6
104 #define TLV_PADDING 8
107 #define TLV_CHECKSUM 12
108 #define TLV_LSP_BUFFERSIZE 14
109 #define TLV_EXT_IS_REACH 22
110 #define TLV_IS_ALIAS_ID 24
111 #define TLV_DECNET_PHASE4 42
112 #define TLV_LUCENT_PRIVATE 66
113 #define TLV_IP_REACH 128
114 #define TLV_PROTOCOLS 129
115 #define TLV_IP_REACH_EXT 130
116 #define TLV_IDRP_INFO 131
117 #define TLV_IPADDR 132
118 #define TLV_IPAUTH 133
119 #define TLV_TE_ROUTER_ID 134
120 #define TLV_EXT_IP_REACH 135
121 #define TLV_HOSTNAME 137
122 #define TLV_SHARED_RISK_GROUP 138
123 #define TLV_NORTEL_PRIVATE1 176
124 #define TLV_NORTEL_PRIVATE2 177
125 #define TLV_RESTART_SIGNALING 211
126 #define TLV_MT_IS_REACH 222
127 #define TLV_MT_SUPPORTED 229
128 #define TLV_IP6ADDR 232
129 #define TLV_MT_IP_REACH 235
130 #define TLV_IP6_REACH 236
131 #define TLV_MT_IP6_REACH 237
132 #define TLV_PTP_ADJ 240
134 static struct tok isis_tlv_values
[] = {
135 { TLV_AREA_ADDR
, "Area address(es)"},
136 { TLV_IS_REACH
, "IS Reachability"},
137 { TLV_ESNEIGH
, "IS Neighbor(s)"},
138 { TLV_PART_DIS
, "Partition DIS"},
139 { TLV_SUMMARY
, "Prefix Neighbors"},
140 { TLV_ISNEIGH
, "IS Neighbor(s)"},
141 { TLV_PADDING
, "Padding"},
142 { TLV_LSP
, "LSP entries"},
143 { TLV_AUTH
, "Authentication"},
144 { TLV_CHECKSUM
, "Checksum"},
145 { TLV_LSP_BUFFERSIZE
, "LSP Buffersize"},
146 { TLV_EXT_IS_REACH
, "Extended IS Reachability"},
147 { TLV_IS_ALIAS_ID
, "IS Alias ID"},
148 { TLV_DECNET_PHASE4
, "DECnet Phase IV"},
149 { TLV_LUCENT_PRIVATE
, "Lucent Proprietary"},
150 { TLV_IP_REACH
, "IPv4 Internal reachability"},
151 { TLV_PROTOCOLS
, "Protocols supported"},
152 { TLV_IP_REACH_EXT
, "IPv4 External reachability"},
153 { TLV_IDRP_INFO
, "Inter-Domain Information Type"},
154 { TLV_IPADDR
, "IPv4 Interface address(es)"},
155 { TLV_IPAUTH
, "IPv4 authentication (deprecated)"},
156 { TLV_TE_ROUTER_ID
, "Traffic Engineering Router ID"},
157 { TLV_EXT_IP_REACH
, "Extended IPv4 reachability"},
158 { TLV_HOSTNAME
, "Hostname"},
159 { TLV_SHARED_RISK_GROUP
, "Shared Risk Link Group"},
160 { TLV_NORTEL_PRIVATE1
, "Nortel Proprietary"},
161 { TLV_NORTEL_PRIVATE2
, "Nortel Proprietary"},
162 { TLV_RESTART_SIGNALING
, "Restart Signaling"},
163 { TLV_MT_IS_REACH
, "Multi Topology IS Reachability"},
164 { TLV_MT_SUPPORTED
, "Multi Topology"},
165 { TLV_IP6ADDR
, "IPv6 Interface address(es)"},
166 { TLV_MT_IP_REACH
, "Multi-Topology IPv4 reachability"},
167 { TLV_IP6_REACH
, "IPv6 reachability"},
168 { TLV_MT_IP6_REACH
, "Multi-Topology IP6 reachability"},
169 { TLV_PTP_ADJ
, "Point-to-point Adjacency State"},
173 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
174 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
175 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
176 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
177 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
178 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
179 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
180 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
181 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
182 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
183 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
185 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
186 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
188 #define SUBTLV_AUTH_SIMPLE 1
189 #define SUBTLV_AUTH_MD5 54
190 #define SUBTLV_AUTH_MD5_LEN 16
191 #define SUBTLV_AUTH_PRIVATE 255
193 static struct tok isis_subtlv_auth_values
[] = {
194 { SUBTLV_AUTH_SIMPLE
, "simple text password"},
195 { SUBTLV_AUTH_MD5
, "HMAC-MD5 password"},
196 { SUBTLV_AUTH_PRIVATE
, "Routing Domain private password"},
200 #define SUBTLV_IDRP_RES 0
201 #define SUBTLV_IDRP_LOCAL 1
202 #define SUBTLV_IDRP_ASN 2
204 static struct tok isis_subtlv_idrp_values
[] = {
205 { SUBTLV_IDRP_RES
, "Reserved"},
206 { SUBTLV_IDRP_LOCAL
, "Routing-Domain Specific"},
207 { SUBTLV_IDRP_ASN
, "AS Number Tag"},
211 #define ISIS_8BIT_MASK(x) ((x)&0xff)
213 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
214 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
215 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
216 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
217 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
218 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
219 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
220 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
222 #define ISIS_MASK_MTID(x) ((x)&0xfff)
223 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
224 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
226 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
227 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
229 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
230 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
231 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
233 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
234 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
236 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
237 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
238 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
239 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
241 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
243 static const char *isis_gmpls_link_prot_values
[] = {
254 static struct tok isis_gmpls_sw_cap_values
[] = {
255 { 1, "Packet-Switch Capable-1"},
256 { 2, "Packet-Switch Capable-2"},
257 { 3, "Packet-Switch Capable-3"},
258 { 4, "Packet-Switch Capable-4"},
259 { 51, "Layer-2 Switch Capable"},
260 { 100, "Time-Division-Multiplex"},
261 { 150, "Lambda-Switch Capable"},
262 { 200, "Fiber-Switch Capable"},
266 static struct tok isis_gmpls_lsp_enc_values
[] = {
268 { 2, "Ethernet V2/DIX"},
271 { 5, "SDH ITU-T G.707"},
272 { 6, "SONET ANSI T1.105"},
273 { 7, "Digital Wrapper"},
274 { 8, "Lambda (photonic)"},
276 { 10, "Ethernet 802.3"},
277 { 11, "FiberChannel"},
281 static struct tok isis_mt_values
[] = {
282 { 0, "IPv4 unicast"},
283 { 1, "In-Band Management"},
284 { 2, "IPv6 unicast"},
286 { 4095, "Development, Experimental or Proprietary"},
290 static struct tok isis_iih_circuit_type_values
[] = {
291 { 1, "Level 1 only"},
292 { 2, "Level 2 only"},
293 { 3, "Level 1, Level 2"},
297 #define ISIS_LSP_TYPE_UNUSED0 0
298 #define ISIS_LSP_TYPE_LEVEL_1 1
299 #define ISIS_LSP_TYPE_UNUSED2 2
300 #define ISIS_LSP_TYPE_LEVEL_2 3
302 static struct tok isis_lsp_istype_values
[] = {
303 { ISIS_LSP_TYPE_UNUSED0
, "Unused 0x0 (invalid)"},
304 { ISIS_LSP_TYPE_LEVEL_1
, "L1 IS"},
305 { ISIS_LSP_TYPE_UNUSED2
, "Unused 0x2 (invalid)"},
306 { ISIS_LSP_TYPE_LEVEL_2
, "L1L2 IS"},
310 static struct tok isis_nlpid_values
[] = {
311 { NLPID_CLNS
, "CLNS"},
313 { NLPID_IP6
, "IPv6"},
318 * Katz's point to point adjacency TLV uses codes to tell us the state of
319 * the remote adjacency. Enumerate them.
322 #define ISIS_PTP_ADJ_UP 0
323 #define ISIS_PTP_ADJ_INIT 1
324 #define ISIS_PTP_ADJ_DOWN 2
327 static struct tok isis_ptp_adjancey_values
[] = {
328 { ISIS_PTP_ADJ_UP
, "Up" },
329 { ISIS_PTP_ADJ_INIT
, "Initializing" },
330 { ISIS_PTP_ADJ_DOWN
, "Down" },
334 struct isis_tlv_ptp_adj
{
335 u_char adjacency_state
;
336 u_char ext_local_circuit_id
[4];
337 u_char neighbor_sysid
[SYSTEM_ID_LEN
];
338 u_char neighbor_ext_local_circuit_id
[4];
341 static int osi_cksum(const u_char
*, u_int
);
342 static void esis_print(const u_char
*, u_int
);
343 static int isis_print(const u_char
*, u_int
);
345 struct isis_tlv_ip_reach
{
346 u_char metric_default
;
348 u_char metric_expense
;
354 struct isis_tlv_is_reach
{
355 u_char metric_default
;
357 u_char metric_expense
;
359 u_char neighbor_nodeid
[SYSTEM_ID_LEN
+1];
362 static struct tok isis_is_reach_virtual_values
[] = {
363 { 0, "IsNotVirtual"},
368 struct isis_common_header
{
371 u_char version
; /* Protocol version? */
373 u_char pdu_type
; /* 3 MSbs are reserved */
374 u_char pkt_version
; /* Packet format version? */
379 struct isis_iih_lan_header
{
381 u_char source_id
[SYSTEM_ID_LEN
];
382 u_char holding_time
[2];
385 u_char lan_id
[SYSTEM_ID_LEN
+1];
388 struct isis_iih_ptp_header
{
390 u_char source_id
[SYSTEM_ID_LEN
];
391 u_char holding_time
[2];
396 struct isis_lsp_header
{
398 u_char remaining_lifetime
[2];
399 u_char lsp_id
[SYSTEM_ID_LEN
+2];
400 u_char sequence_number
[4];
405 struct isis_csnp_header
{
407 u_char source_id
[SYSTEM_ID_LEN
+1];
408 u_char start_lsp_id
[SYSTEM_ID_LEN
+2];
409 u_char end_lsp_id
[SYSTEM_ID_LEN
+2];
412 struct isis_psnp_header
{
414 u_char source_id
[SYSTEM_ID_LEN
+1];
417 struct isis_tlv_lsp
{
418 u_char remaining_lifetime
[2];
419 u_char lsp_id
[SYSTEM_ID_LEN
+2];
420 u_char sequence_number
[4];
424 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
425 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
426 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
427 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
428 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
429 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
431 void isoclns_print(const u_char
*p
, u_int length
, u_int caplen
,
432 const u_char
*esrc
, const u_char
*edst
)
435 const struct isis_common_header
*header
;
437 header
= (const struct isis_common_header
*)p
;
438 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
441 printf("[|iso-clns] ");
442 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
444 etheraddr_string(esrc
),
445 etheraddr_string(edst
));
452 (void)printf("CLNS(%d)", length
);
453 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
454 (void)printf(", %s > %s",
455 etheraddr_string(esrc
),
456 etheraddr_string(edst
));
460 (void)printf("ESIS");
461 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
462 (void)printf(", %s > %s",
463 etheraddr_string(esrc
),
464 etheraddr_string(edst
));
465 esis_print(p
, length
);
469 (void)printf("ISIS(%d)", length
);
470 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
471 (void)printf(", %s > %s",
472 etheraddr_string(esrc
),
473 etheraddr_string(edst
));
474 if (!isis_print(p
, length
))
475 default_print_unaligned(p
, caplen
);
479 (void)printf("ISO NULLNS(%d)", length
);
480 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
481 (void)printf(", %s > %s",
482 etheraddr_string(esrc
),
483 etheraddr_string(edst
));
487 (void)printf("CLNS %02x(%d)", p
[0], length
);
488 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
489 (void)printf(", %s > %s",
490 etheraddr_string(esrc
),
491 etheraddr_string(edst
));
493 default_print_unaligned(p
, caplen
);
498 #define ESIS_REDIRECT 6
511 esis_print(const u_char
*p
, u_int length
)
515 const struct esis_hdr
*eh
;
521 printf(" no header at all!");
525 eh
= (const struct esis_hdr
*) &p
[2];
531 printf(" LI(%d) > PDU size (%d)!", li
, length
);
534 if (li
< sizeof(struct esis_hdr
) + 2) {
538 printf(" too short for esis header %d:", li
);
539 while (--length
!= 0)
540 printf("%02X", *p
++);
544 switch (eh
->type
& 0x1f) {
559 printf(" type %d", eh
->type
& 0x1f);
562 if (vflag
&& osi_cksum(p
, li
)) {
563 printf(" bad cksum (got 0x%02x%02x)",
564 eh
->cksum
[1], eh
->cksum
[0]);
565 default_print(p
, length
);
568 if (eh
->version
!= 1) {
569 printf(" unsupported version %d", eh
->version
);
572 p
+= sizeof(*eh
) + 2;
573 li
-= sizeof(*eh
) + 2; /* protoid * li */
575 switch (eh
->type
& 0x1f) {
576 case ESIS_REDIRECT
: {
577 const u_char
*dst
, *snpa
, *is
;
579 dst
= p
; p
+= *p
+ 1;
582 printf("\n\t\t\t %s", isonsap_string(dst
));
583 snpa
= p
; p
+= *p
+ 1;
592 printf(" > %s", etheraddr_string(&snpa
[1]));
594 printf(" > %s", isonsap_string(is
));
614 printf("\n\t\t\t %s", isonsap_string(is
));
620 (void)printf(" len=%d", length
);
621 if (length
&& p
< snapend
) {
622 length
= snapend
- p
;
623 default_print(p
, length
);
628 while (p
< ep
&& li
) {
635 printf(" bad opts/li");
642 printf(" opt (%d) too long", op
);
650 if (op
== 198 && opli
== 2) {
651 printf(" tmo=%d", q
[0] * 256 + q
[1]);
654 printf (" %d:<", op
);
656 printf("%02x", *q
++);
661 /* allocate space for the following string
662 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
663 * 32 bytes plus one termination byte */
666 print_nsap(register const u_char
*cp
, register int length
)
671 for (i
= 0; i
< length
; i
++) {
674 pos
+=sprintf(pos
, "%02x", *cp
++);
675 if (((i
& 1) == 0) && (i
+ 1 < length
)) {
676 pos
+=sprintf(pos
, ".");
683 char *isis_print_sysid (const u_char
*);
684 /* allocate space for the following string
686 * 14 bytes plus one termination byte */
689 isis_print_sysid(const u_char
*cp
)
694 for (i
= 1; i
<= 6; i
++) {
697 pos
+=sprintf(pos
, "%02x", *cp
++);
699 pos
+=sprintf(pos
, ".");
707 char *isis_print_nodeid (const u_char
*);
708 /* allocate space for the following string
710 * 17 bytes plus one termination byte */
713 isis_print_nodeid(const u_char
*cp
)
718 for (i
= 1; i
<= 7; i
++) {
721 pos
+=sprintf(pos
, "%02x", *cp
++);
723 pos
+=sprintf(pos
, ".");
730 char *isis_print_lspid (const u_char
*);
731 /* allocate space for the following string
732 * xxxx.xxxx.xxxx.yy-zz
733 * 20 bytes plus one termination byte */
736 isis_print_lspid(const u_char
*cp
)
741 for (i
= 1; i
<= 7; i
++) {
742 pos
+=sprintf(pos
, "%02x", *cp
++);
744 pos
+=sprintf(pos
, ".");
746 pos
+=sprintf(pos
, "-%02x", *cp
);
751 * this is a generic routine for printing unknown data;
752 * as it is called from various places (TLV and subTLV parsing routines)
753 * we pass on the linefeed plus indentation string to
754 * get a proper output - returns 0 on error
758 isis_print_unknown_data(const u_char
*cp
,const char *lf
,int len
)
762 printf("%s0x0000: ",lf
);
764 if (!TTEST2(*(cp
+i
), 1))
766 printf("%02x",*(cp
+i
));
769 if (i
/16!=(i
+1)/16) {
771 printf("%s0x%04x: ",lf
,i
);
774 return(1); /* everything is ok */
777 printf("%spacket exceeded snapshot",lf
);
783 isis_print_tlv_ip_reach (const u_char
*cp
, int length
)
785 u_int bitmasks
[33] = {
787 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
788 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
789 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
790 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
791 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
792 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
793 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
794 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
798 const struct isis_tlv_ip_reach
*tlv_ip_reach
;
800 tlv_ip_reach
= (const struct isis_tlv_ip_reach
*)cp
;
803 if (length
< sizeof(*tlv_ip_reach
)) {
804 printf("short IPv4 reachability (%d vs %lu)", length
,
805 (unsigned long)sizeof(*tlv_ip_reach
));
809 if (!TTEST(*tlv_ip_reach
))
812 mask
= EXTRACT_32BITS(tlv_ip_reach
->mask
);
815 /* lets see if we can transform the mask into a prefixlen */
816 while (prefix_len
<= 33) {
817 if (bitmasks
[prefix_len
++] == mask
) {
824 * 34 indicates no match -> must be a discontiguous netmask
825 * lets dump the mask, otherwise print the prefix_len
827 if (prefix_len
== 34)
828 printf("\n\t\t\tIPv4 prefix: %s mask %s",
829 ipaddr_string((tlv_ip_reach
->prefix
)),
830 ipaddr_string((tlv_ip_reach
->mask
)));
832 printf("\n\t\t\tIPv4 prefix: %s/%u",
833 ipaddr_string((tlv_ip_reach
->prefix
)),
836 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s",
837 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_default
),
838 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_default
) ? "External" : "Internal",
839 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->metric_default
) ? "down" : "up");
841 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_delay
))
842 printf("\n\t\t\t Delay Metric: %02d, %s",
843 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_delay
),
844 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_delay
) ? "External" : "Internal");
846 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_expense
))
847 printf("\n\t\t\t Expense Metric: %02d, %s",
848 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_expense
),
849 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_expense
) ? "External" : "Internal");
851 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->metric_error
))
852 printf("\n\t\t\t Error Metric: %02d, %s",
853 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->metric_error
),
854 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->metric_error
) ? "External" : "Internal");
856 length
-= sizeof(struct isis_tlv_ip_reach
);
863 * this is the common IP-REACH subTLV decoder it is called
864 * from various EXTD-IP REACH TLVs (135,235,236,237)
868 isis_print_ip_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
871 case SUBTLV_IP_REACH_ADMIN_TAG32
:
872 if (!TTEST2(*tptr
,4))
874 printf("%s32-Bit Administrative tag: 0x%08x",
876 EXTRACT_32BITS(tptr
));
878 case SUBTLV_IP_REACH_ADMIN_TAG64
:
879 if (!TTEST2(*tptr
,8))
881 printf("%s64-Bit Administrative tag: 0x%08x%08x",
883 EXTRACT_32BITS(tptr
),
884 EXTRACT_32BITS(tptr
+4));
887 printf("%sunknown subTLV, type %d, length %d",
891 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
899 printf("%spacket exceeded snapshot",lf
);
904 * this is the common IS-REACH subTLV decoder it is called
905 * from various EXTD-IS REACH TLVs (22,24,222)
909 isis_print_is_reach_subtlv (const u_char
*tptr
,int subt
,int subl
,const char *lf
) {
912 float bw
; /* copy buffer for several subTLVs */
915 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
916 if (!TTEST2(*tptr
,4))
918 printf("%sAdministrative groups: 0x%08x",
920 EXTRACT_32BITS(tptr
));
922 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
923 if (!TTEST2(*tptr
,4))
925 printf("%sLink Local Identifier: 0x%08x",
927 EXTRACT_32BITS(tptr
));
929 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
930 if (!TTEST2(*tptr
,4))
932 printf("%sLink Remote Identifier: 0x%08x",
934 EXTRACT_32BITS(tptr
));
936 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
937 if (!TTEST2(*tptr
,4))
939 j
= EXTRACT_32BITS(tptr
);
941 printf("%sMaximum link bandwidth : %.3f Mbps",
945 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
946 if (!TTEST2(*tptr
,4))
948 j
= EXTRACT_32BITS(tptr
);
950 printf("%sReservable link bandwidth: %.3f Mbps",
954 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
955 printf("%sUnreserved bandwidth:",lf
);
956 for (i
= 0; i
< 8; i
++) {
957 if (!TTEST2(*(tptr
+i
*4),4))
959 j
= EXTRACT_32BITS(tptr
);
961 printf("%s priority level %d: %.3f Mbps",
967 case SUBTLV_EXT_IS_REACH_TE_METRIC
:
968 if (!TTEST2(*tptr
,3))
970 printf("%sTraffic Engineering Metric: %d",
972 EXTRACT_24BITS(tptr
));
974 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR
:
975 if (!TTEST2(*tptr
,4))
977 printf("%sIPv4 interface address: %s",
979 ipaddr_string(tptr
));
981 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR
:
982 if (!TTEST2(*tptr
,4))
984 printf("%sIPv4 neighbor address: %s",
986 ipaddr_string(tptr
));
988 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE
:
989 if (!TTEST2(*tptr
,2))
992 j
= (ISIS_8BIT_MASK(*tptr
)); /* fetch the typecode and make sure
993 that no high-order LSBs are set */
994 printf("%sLink Protection Type: %s",
997 /* scan through the bits until the typecode is zero */
999 printf("%s", isis_gmpls_link_prot_values
[i
]);
1001 if (j
) /*any other bit set ?*/
1005 printf(", Priority %u", *(tptr
+1));
1007 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
1008 printf("%sInterface Switching Capability",lf
);
1010 if (!TTEST2(*tptr
,1))
1012 printf("%s Interface Switching Capability:%s",
1014 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1016 if (!TTEST2(*(tptr
+1),1))
1018 printf(", LSP Encoding: %s",
1019 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1021 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1024 printf("%s Max LSP Bandwidth:",lf
);
1025 for (i
= 0; i
< 8; i
++) {
1026 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1028 j
= EXTRACT_32BITS(tptr
);
1029 memcpy (&bw
, &j
, 4);
1030 printf("%s priority level %d: %.3f Mbps",
1036 /* there is some optional stuff left to decode but this is as of yet
1037 not specified so just lets hexdump what is left */
1039 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1049 printf("%sReserved for cisco specific extensions, type %d, length %d",
1055 printf("%sReserved for future expansion, type %d, length %d",
1061 printf("%sunknown subTLV, type %d, length %d",
1065 if(!isis_print_unknown_data(tptr
,"\n\t\t\t ",
1073 printf("%spacket exceeded snapshot",lf
);
1080 * Decode IS-IS packets. Return 0 on error.
1083 static int isis_print (const u_char
*p
, u_int length
)
1085 const struct isis_common_header
*header
;
1087 const struct isis_iih_lan_header
*header_iih_lan
;
1088 const struct isis_iih_ptp_header
*header_iih_ptp
;
1089 const struct isis_lsp_header
*header_lsp
;
1090 const struct isis_csnp_header
*header_csnp
;
1091 const struct isis_psnp_header
*header_psnp
;
1093 const struct isis_tlv_lsp
*tlv_lsp
;
1094 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1095 const struct isis_tlv_is_reach
*tlv_is_reach
;
1097 u_char pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, subl
, subt
, tslen
;
1098 const u_char
*optr
, *pptr
, *tptr
;
1099 u_short packet_len
,pdu_len
,time_remain
;
1100 u_int i
,j
,bit_length
,byte_length
,metric
,ra
,rr
;
1101 u_char prefix
[4]; /* copy buffer for ipv4 prefixes */
1103 u_char prefix6
[16]; /* copy buffer for ipv6 prefixes */
1106 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1107 need it for parsing the checksum TLV */
1108 header
= (const struct isis_common_header
*)p
;
1110 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1111 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1112 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1113 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1114 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1115 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1118 * Sanity checking of the header.
1120 if (header
->nlpid
!= NLPID_ISIS
) {
1121 printf(", coding error!");
1125 if (header
->version
!= ISIS_VERSION
) {
1126 printf(", version %d packet not supported", header
->version
);
1130 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1131 printf(", system ID length of %d is not supported",
1136 if (header
->pkt_version
!= ISIS_VERSION
) {
1137 printf(", version %d packet not supported", header
->pkt_version
);
1141 max_area
= header
->max_area
;
1144 max_area
= 3; /* silly shit */
1147 printf(", bad packet -- 255 areas");
1153 id_length
= header
->id_length
;
1156 id_length
= 6; /* silly shit again */
1158 case 1: /* 1-8 are valid sys-ID lenghts */
1168 id_length
= 0; /* entirely useless */
1171 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1176 printf(", hlen: %u, v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1184 pdu_type
=header
->pdu_type
;
1186 /* first lets see if we know the PDU name*/
1188 tok2str(isis_pdu_values
,
1189 "unknown PDU, type %d",
1196 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1197 printf(", bogus fixed header length %u should be %lu",
1198 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1202 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1203 if (packet_len
>pdu_len
) {
1204 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1208 TCHECK(*header_iih_lan
);
1209 printf("\n\t\t source-id: %s, holding time: %u, %s",
1210 isis_print_sysid(header_iih_lan
->source_id
),
1211 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1212 tok2str(isis_iih_circuit_type_values
,
1213 "unknown circuit type 0x%02x",
1214 header_iih_lan
->circuit_type
));
1216 printf("\n\t\t lan-id: %s, Priority: %u, PDU length: %u",
1217 isis_print_nodeid(header_iih_lan
->lan_id
),
1218 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1221 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1222 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1226 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1227 printf(", bogus fixed header length %u should be %lu",
1228 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1232 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
1233 if (packet_len
>pdu_len
) {
1234 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1238 TCHECK(*header_iih_ptp
);
1239 printf("\n\t\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1240 isis_print_sysid(header_iih_ptp
->source_id
),
1241 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1242 header_iih_ptp
->circuit_id
,
1243 tok2str(isis_iih_circuit_type_values
,
1244 "unknown circuit type 0x%02x",
1245 header_iih_ptp
->circuit_type
),
1248 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1249 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1254 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1255 printf(", bogus fixed header length %u should be %lu",
1256 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1260 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1261 if (packet_len
>pdu_len
) {
1262 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1266 TCHECK(*header_lsp
);
1267 printf("\n\t\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1268 isis_print_lspid(header_lsp
->lsp_id
),
1269 EXTRACT_32BITS(header_lsp
->sequence_number
),
1270 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1271 /* verify the checksum -
1272 * checking starts at the lsp-id field
1273 * which is 12 bytes after the packet start*/
1274 printf("\n\t\t chksum: 0x%04x (%s), PDU length: %u",
1275 EXTRACT_16BITS(header_lsp
->checksum
),
1276 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1279 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1281 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1282 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1283 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1284 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1285 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1286 printf("ATT bit set, ");
1288 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1289 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1291 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1292 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1297 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1298 printf(", bogus fixed header length %u should be %lu",
1299 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1303 pdu_len
=EXTRACT_16BITS(header_csnp
->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_csnp
);
1310 printf("\n\t\t source-id: %s, PDU length: %u",
1311 isis_print_nodeid(header_csnp
->source_id
),
1313 printf("\n\t\t start lsp-id: %s",
1314 isis_print_lspid(header_csnp
->start_lsp_id
));
1315 printf("\n\t\t end lsp-id: %s",
1316 isis_print_lspid(header_csnp
->end_lsp_id
));
1318 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1319 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1324 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1325 printf("- bogus fixed header length %u should be %lu",
1326 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1330 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1331 if (packet_len
>pdu_len
) {
1332 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1336 TCHECK(*header_psnp
);
1337 printf("\n\t\t source-id: %s",
1338 isis_print_nodeid(header_psnp
->source_id
));
1340 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1341 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1345 if(!isis_print_unknown_data(pptr
,"\n\t\t ",length
))
1351 * Now print the TLV's.
1354 while (packet_len
>= 2) {
1355 if (pptr
== snapend
) {
1359 if (!TTEST2(*pptr
, 2)) {
1360 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes",
1361 (long)(pptr
-snapend
));
1366 tmp
=len
; /* copy temporary len & pointer to packet data */
1369 if (len
> packet_len
) {
1373 /* first lets see if we know the TLVs name*/
1374 printf("\n\t\t %s TLV #%u, length: %u",
1375 tok2str(isis_tlv_values
,
1381 /* now check if we have a decoder otherwise do a hexdump at the end*/
1384 if (!TTEST2(*tptr
, 1))
1387 while (tmp
&& alen
< tmp
) {
1388 printf("\n\t\t\tArea address (%u): %s",
1390 print_nsap(tptr
, alen
));
1393 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1395 if (!TTEST2(*tptr
, 1))
1401 while (tmp
>= ETHER_ADDR_LEN
) {
1402 printf("\n\t\t\tIS Neighbor: %s",isis_print_sysid(tptr
));
1403 tmp
-= ETHER_ADDR_LEN
;
1404 tptr
+= ETHER_ADDR_LEN
;
1411 case TLV_MT_IS_REACH
:
1413 if (!TTEST2(*tptr
, 2))
1415 printf("\n\t\t\t%s",
1416 tok2str(isis_mt_values
,
1417 "Reserved for IETF Consensus",
1418 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1420 printf(" Topology (0x%03x)",
1421 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1423 printf("\n\t\t\t IS Neighbor: %s", isis_print_nodeid(tptr
));
1424 tptr
+=(SYSTEM_ID_LEN
+1);
1425 if (!TTEST2(*tptr
, 3))
1427 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1429 if (!TTEST2(*tptr
, 1))
1432 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1434 printf(" (%u)",tslen
);
1436 if (!TTEST2(*tptr
,2))
1440 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1447 tmp
-=(SYSTEM_ID_LEN
+7);
1451 case TLV_EXT_IS_REACH
:
1453 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
+1))
1455 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1456 tptr
+=(SYSTEM_ID_LEN
+1);
1458 if (!TTEST2(*tptr
, 3))
1460 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1463 if (!TTEST2(*tptr
, 1))
1465 tslen
=*(tptr
++); /* read out subTLV length */
1466 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1468 printf(" (%u)",tslen
);
1470 if (!TTEST2(*tptr
,2))
1474 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1481 tmp
-=(SYSTEM_ID_LEN
+5);
1485 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1488 printf("\n\t\t\t%s",
1489 tok2str(isis_is_reach_virtual_values
,
1490 "bogus virtual flag 0x%02x",
1493 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1495 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1496 if (!TTEST(*tlv_is_reach
))
1499 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1500 printf(", Default Metric: %d, %s",
1501 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_default
),
1502 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_default
) ? "External" : "Internal");
1504 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_delay
))
1505 printf("\n\t\t\t Delay Metric: %d, %s",
1506 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_delay
),
1507 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_delay
) ? "External" : "Internal");
1509 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_expense
))
1510 printf("\n\t\t\t Expense Metric: %d, %s",
1511 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_expense
),
1512 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_expense
) ? "External" : "Internal");
1514 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach
->metric_error
))
1515 printf("\n\t\t\t Error Metric: %d, %s",
1516 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach
->metric_error
),
1517 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach
->metric_error
) ? "External" : "Internal");
1519 tmp
-= sizeof(struct isis_tlv_is_reach
);
1524 /* those two TLVs share the same format */
1526 case TLV_IP_REACH_EXT
:
1527 if (!isis_print_tlv_ip_reach(pptr
, len
))
1531 case TLV_MT_IP_REACH
:
1533 if (!TTEST2(*tptr
, 2))
1536 printf("\n\t\t\t%s",
1537 tok2str(isis_mt_values
,
1538 "Reserved for IETF Consensus",
1539 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1541 printf(" Topology (0x%03x)",
1542 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)));
1545 memset (prefix
, 0, 4);
1546 if (!TTEST2(*tptr
, 4))
1548 metric
= EXTRACT_32BITS(tptr
);
1551 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1554 bit_length
= (*(tptr
)++&0x3f);
1555 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1557 if (!TTEST2(*tptr
, byte_length
))
1559 memcpy(prefix
,tptr
,byte_length
);
1561 printf("\n\t\t\tIPv4 prefix: %s/%d",
1562 ipaddr_string(prefix
),
1565 printf("\n\t\t\t Metric: %u, Distribution: %s",
1567 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1569 printf(", %ssub-TLVs present",
1570 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1572 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1573 /* assume that one prefix can hold more
1574 than one subTLV - therefore the first byte must reflect
1575 the aggregate bytecount of the subTLVs for this prefix
1577 if (!TTEST2(*tptr
, 1))
1581 printf(" (%u)",tslen
); /* print out subTLV length */
1584 if (!TTEST2(*tptr
,2))
1588 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1595 tmp
-=(7+byte_length
);
1599 case TLV_EXT_IP_REACH
:
1601 memset (prefix
, 0, 4);
1602 if (!TTEST2(*tptr
, 4))
1604 metric
= EXTRACT_32BITS(tptr
);
1607 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1610 bit_length
= (*(tptr
)++&0x3f);
1611 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1613 if (!TTEST2(*tptr
, byte_length
))
1615 memcpy(prefix
,tptr
,byte_length
);
1617 printf("\n\t\t\tIPv4 prefix: %s/%d",
1618 ipaddr_string(prefix
),
1621 printf("\n\t\t\t Metric: %u, Distribution: %s",
1623 ISIS_MASK_TLV_EXT_IP_UPDOWN(j
) ? "down" : "up");
1625 printf(", %ssub-TLVs present",
1626 ISIS_MASK_TLV_EXT_IP_SUBTLV(j
) ? "" : "no ");
1628 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j
)) {
1629 /* assume that one prefix can hold more
1630 than one subTLV - therefore the first byte must reflect
1631 the aggregate bytecount of the subTLVs for this prefix
1633 if (!TTEST2(*tptr
, 1))
1637 printf(" (%u)",tslen
); /* print out subTLV length */
1640 if (!TTEST2(*tptr
,2))
1644 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1651 tmp
-=(5+byte_length
);
1659 if (!TTEST2(*tptr
, 4))
1661 metric
= EXTRACT_32BITS(tptr
);
1664 if (!TTEST2(*tptr
, 2))
1667 bit_length
= (*(tptr
)++);
1668 byte_length
= (bit_length
+ 7) / 8;
1669 if (!TTEST2(*tptr
, byte_length
))
1672 memset(prefix6
, 0, 16);
1673 memcpy(prefix6
,tptr
,byte_length
);
1675 printf("\n\t\t\tIPv6 prefix: %s/%u",
1676 ip6addr_string(prefix6
),
1679 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1681 ISIS_MASK_TLV_IP6_IE(j
) ? "External" : "Internal",
1682 ISIS_MASK_TLV_IP6_UPDOWN(j
) ? "down" : "up",
1683 ISIS_MASK_TLV_IP6_SUBTLV(j
) ? "" : "no ");
1685 if (ISIS_MASK_TLV_IP6_SUBTLV(j
)) {
1686 /* assume that one prefix can hold more
1687 than one subTLV - therefore the first byte must reflect
1688 the aggregate bytecount of the subTLVs for this prefix
1690 if (!TTEST2(*tptr
, 1))
1694 printf(" (%u)",tslen
); /* print out subTLV length */
1697 if (!TTEST2(*tptr
,2))
1701 if(!isis_print_ip_reach_subtlv(tptr
,subt
,subl
,"\n\t\t\t "))
1708 tmp
-=(6+byte_length
);
1717 if (!TTEST2(*tptr
, 16))
1720 printf("\n\t\t\tIPv6 interface address: %s",
1721 ip6addr_string(tptr
));
1729 if (!TTEST2(*tptr
, 1))
1732 printf("\n\t\t\t%s: ",
1733 tok2str(isis_subtlv_auth_values
,
1734 "unknown Authentication type 0x%02x",
1738 case SUBTLV_AUTH_SIMPLE
:
1739 for(i
=1;i
<len
;i
++) {
1740 if (!TTEST2(*(tptr
+i
), 1))
1742 printf("%c",*(tptr
+i
));
1745 case SUBTLV_AUTH_MD5
:
1746 for(i
=1;i
<len
;i
++) {
1747 if (!TTEST2(*(tptr
+i
), 1))
1749 printf("%02x",*(tptr
+i
));
1751 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1752 printf(", (malformed subTLV) ");
1754 case SUBTLV_AUTH_PRIVATE
:
1756 if(!isis_print_unknown_data(tptr
+1,"\n\t\t\t ",len
-1))
1763 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1765 if (!TTEST2(*tptr
, 1))
1767 printf("\n\t\t\tAdjacency State: %s",
1768 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1772 if (!TTEST2(tlv_ptp_adj
->ext_local_circuit_id
, 4))
1774 printf("\n\t\t\tExtended Local circuit ID: 0x%08x",
1775 EXTRACT_32BITS(tlv_ptp_adj
->ext_local_circuit_id
));
1779 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, 6))
1781 printf("\n\t\t\tNeighbor SystemID: %s",
1782 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
));
1786 if (!TTEST2(tlv_ptp_adj
->neighbor_ext_local_circuit_id
, 4))
1788 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x",
1789 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_ext_local_circuit_id
));
1794 printf("\n\t\t\tNLPID(s): ");
1796 if (!TTEST2(*(tptr
), 1))
1799 tok2str(isis_nlpid_values
,
1802 if (tmp
>1) /* further NPLIDs ? - put comma */
1808 case TLV_TE_ROUTER_ID
:
1809 if (!TTEST2(*pptr
, 4))
1811 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1816 if (!TTEST2(*tptr
, 4))
1818 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1825 printf("\n\t\t\tHostname: ");
1827 if (!TTEST2(*tptr
, 1))
1829 printf("%c",*tptr
++);
1834 case TLV_SHARED_RISK_GROUP
:
1835 if (!TTEST2(*tptr
, 7))
1837 printf("\n\t\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1838 tptr
+=(SYSTEM_ID_LEN
+1);
1839 len
-=(SYSTEM_ID_LEN
+1);
1841 if (!TTEST2(*tptr
, 1))
1843 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1846 if (!TTEST2(*tptr
,4))
1848 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1852 if (!TTEST2(*tptr
,4))
1854 printf("\n\t\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1859 if (!TTEST2(*tptr
, 4))
1861 printf("\n\t\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1868 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1870 printf("\n\t\t\tlsp-id: %s",
1871 isis_print_nodeid(tlv_lsp
->lsp_id
));
1872 if (!TTEST((tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]))
1874 printf("-%02x",(tlv_lsp
->lsp_id
)[SYSTEM_ID_LEN
+1]);
1875 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1877 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1878 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1880 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1881 if (!TTEST2(tlv_lsp
->checksum
, 2))
1883 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1884 tmp
-=sizeof(struct isis_tlv_lsp
);
1890 if (!TTEST2(*tptr
, 2))
1892 printf("\n\t\t\tchecksum: 0x%04x (%s)",
1893 EXTRACT_16BITS(tptr
),
1894 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1897 case TLV_MT_SUPPORTED
:
1899 /* length can only be a multiple of 2, otherwise there is
1900 something broken -> so decode down until length is 1 */
1902 if (!TTEST2(*tptr
, 2))
1904 printf("\n\t\t\t%s",
1905 tok2str(isis_mt_values
,
1906 "Reserved for IETF Consensus",
1907 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1909 printf(" Topology (0x%03x)%s%s",
1910 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1911 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1912 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1914 printf("\n\t\t\tmalformed MT-ID");
1922 case TLV_RESTART_SIGNALING
:
1923 if (!TTEST2(*tptr
, 3))
1925 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1926 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1928 time_remain
= EXTRACT_16BITS(tptr
);
1929 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us",
1930 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
1934 if (!TTEST2(*tptr
, 1))
1936 printf("\n\t\t\tInter-Domain Information Type: %s",
1937 tok2str(isis_subtlv_idrp_values
,
1941 case SUBTLV_IDRP_ASN
:
1942 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
1944 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
1946 case SUBTLV_IDRP_LOCAL
:
1947 case SUBTLV_IDRP_RES
:
1949 if(!isis_print_unknown_data(tptr
,"\n\t\t\t",len
-1))
1955 case TLV_LSP_BUFFERSIZE
:
1956 if (!TTEST2(*tptr
, 2))
1958 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr
));
1962 * FIXME those are the defined TLVs that lack a decoder
1963 * you are welcome to contribute code ;-)
1969 case TLV_IS_ALIAS_ID
:
1970 case TLV_DECNET_PHASE4
:
1971 case TLV_LUCENT_PRIVATE
:
1973 case TLV_NORTEL_PRIVATE1
:
1974 case TLV_NORTEL_PRIVATE2
:
1975 case TLV_MT_IP6_REACH
:
1978 if(!isis_print_unknown_data(pptr
,"\n\t\t\t",len
))
1987 if (packet_len
!= 0) {
1988 printf("\n\t\t\t %d straggler bytes", packet_len
);
1993 fputs("[|isis]", stdout
);
1997 printf("\n\t\t\t packet exceeded snapshot");
2002 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2006 osi_cksum(const u_char
*tptr
, u_int len
)
2008 int32_t c0
= 0, c1
= 0;
2010 while ((int)--len
>= 0) {