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.73 2002-12-11 07:14:04 guy 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
54 #define IPV4 1 /* AFI value */
55 #define IPV6 2 /* AFI value */
58 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
61 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
62 #define NODE_ID_LEN SYSTEM_ID_LEN+1
63 #define LSP_ID_LEN SYSTEM_ID_LEN+2
65 #define ISIS_VERSION 1
66 #define PDU_TYPE_MASK 0x1F
67 #define PRIORITY_MASK 0x7F
79 static struct tok isis_pdu_values
[] = {
80 { L1_LAN_IIH
, "L1 Lan IIH"},
81 { L2_LAN_IIH
, "L2 Lan IIH"},
82 { PTP_IIH
, "p2p IIH"},
85 { L1_CSNP
, "L1 CSNP"},
86 { L2_CSNP
, "L2 CSNP"},
87 { L1_PSNP
, "L1 PSNP"},
88 { L2_PSNP
, "L2 PSNP"},
93 * A TLV is a tuple of a type, length and a value and is normally used for
94 * encoding information in all sorts of places. This is an enumeration of
95 * the well known types.
97 * list taken from rfc3359 plus some memory from veterans ;-)
100 #define TLV_AREA_ADDR 1 /* iso10589 */
101 #define TLV_IS_REACH 2 /* iso10589 */
102 #define TLV_ESNEIGH 3 /* iso10589 */
103 #define TLV_PART_DIS 4 /* iso10589 */
104 #define TLV_PREFIX_NEIGH 5 /* iso10589 */
105 #define TLV_ISNEIGH 6 /* iso10589 */
106 #define TLV_ISNEIGH_VARLEN 7 /* iso10589 */
107 #define TLV_PADDING 8 /* iso10589 */
108 #define TLV_LSP 9 /* iso10589 */
109 #define TLV_AUTH 10 /* iso10589, draft-ietf-isis-hmac-03 */
110 #define TLV_CHECKSUM 12 /* rfc3358 */
111 #define TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */
112 #define TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-04 */
113 #define TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */
114 #define TLV_DECNET_PHASE4 42
115 #define TLV_LUCENT_PRIVATE 66
116 #define TLV_IP_REACH 128 /* rfc1195, rfc2966 */
117 #define TLV_PROTOCOLS 129 /* rfc1195 */
118 #define TLV_IP_REACH_EXT 130 /* rfc1195, rfc2966 */
119 #define TLV_IDRP_INFO 131 /* rfc1195 */
120 #define TLV_IPADDR 132 /* rfc1195 */
121 #define TLV_IPAUTH 133 /* rfc1195 */
122 #define TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-04 */
123 #define TLV_EXT_IP_REACH 135 /* draft-ietf-isis-traffic-04 */
124 #define TLV_HOSTNAME 137 /* rfc2763 */
125 #define TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions-14 */
126 #define TLV_NORTEL_PRIVATE1 176
127 #define TLV_NORTEL_PRIVATE2 177
128 #define TLV_HOLDTIME 198 /* ES-IS */
129 #define TLV_RESTART_SIGNALING 211 /* draft-ietf-isis-restart-01 */
130 #define TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
131 #define TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
132 #define TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */
133 #define TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */
134 #define TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */
135 #define TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
136 #define TLV_PTP_ADJ 240 /* rfc3373 */
137 #define TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
138 #define TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */
140 static struct tok isis_tlv_values
[] = {
141 { TLV_AREA_ADDR
, "Area address(es)"},
142 { TLV_IS_REACH
, "IS Reachability"},
143 { TLV_ESNEIGH
, "ES Neighbor(s)"},
144 { TLV_PART_DIS
, "Partition DIS"},
145 { TLV_PREFIX_NEIGH
, "Prefix Neighbors"},
146 { TLV_ISNEIGH
, "IS Neighbor(s)"},
147 { TLV_ISNEIGH_VARLEN
, "IS Neighbor(s) (variable length)"},
148 { TLV_PADDING
, "Padding"},
149 { TLV_LSP
, "LSP entries"},
150 { TLV_AUTH
, "Authentication"},
151 { TLV_CHECKSUM
, "Checksum"},
152 { TLV_LSP_BUFFERSIZE
, "LSP Buffersize"},
153 { TLV_EXT_IS_REACH
, "Extended IS Reachability"},
154 { TLV_IS_ALIAS_ID
, "IS Alias ID"},
155 { TLV_DECNET_PHASE4
, "DECnet Phase IV"},
156 { TLV_LUCENT_PRIVATE
, "Lucent Proprietary"},
157 { TLV_IP_REACH
, "IPv4 Internal reachability"},
158 { TLV_PROTOCOLS
, "Protocols supported"},
159 { TLV_IP_REACH_EXT
, "IPv4 External reachability"},
160 { TLV_IDRP_INFO
, "Inter-Domain Information Type"},
161 { TLV_IPADDR
, "IPv4 Interface address(es)"},
162 { TLV_IPAUTH
, "IPv4 authentication (deprecated)"},
163 { TLV_TE_ROUTER_ID
, "Traffic Engineering Router ID"},
164 { TLV_EXT_IP_REACH
, "Extended IPv4 reachability"},
165 { TLV_HOSTNAME
, "Hostname"},
166 { TLV_SHARED_RISK_GROUP
, "Shared Risk Link Group"},
167 { TLV_NORTEL_PRIVATE1
, "Nortel Proprietary"},
168 { TLV_NORTEL_PRIVATE2
, "Nortel Proprietary"},
169 { TLV_HOLDTIME
, "Holdtime"},
170 { TLV_RESTART_SIGNALING
, "Restart Signaling"},
171 { TLV_MT_IS_REACH
, "Multi Topology IS Reachability"},
172 { TLV_MT_SUPPORTED
, "Multi Topology"},
173 { TLV_IP6ADDR
, "IPv6 Interface address(es)"},
174 { TLV_MT_IP_REACH
, "Multi-Topology IPv4 reachability"},
175 { TLV_IP6_REACH
, "IPv6 reachability"},
176 { TLV_MT_IP6_REACH
, "Multi-Topology IP6 reachability"},
177 { TLV_PTP_ADJ
, "Point-to-point Adjacency State"},
178 { TLV_IIH_SEQNR
, "Hello PDU Sequence Number"},
179 { TLV_VENDOR_PRIVATE
, "Vendor Private"},
183 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
184 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
185 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
186 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
187 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
188 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
189 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
190 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
191 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
192 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
193 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
195 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
196 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
198 #define SUBTLV_AUTH_SIMPLE 1
199 #define SUBTLV_AUTH_MD5 54
200 #define SUBTLV_AUTH_MD5_LEN 16
201 #define SUBTLV_AUTH_PRIVATE 255
203 static struct tok isis_subtlv_auth_values
[] = {
204 { SUBTLV_AUTH_SIMPLE
, "simple text password"},
205 { SUBTLV_AUTH_MD5
, "HMAC-MD5 password"},
206 { SUBTLV_AUTH_PRIVATE
, "Routing Domain private password"},
210 #define SUBTLV_IDRP_RES 0
211 #define SUBTLV_IDRP_LOCAL 1
212 #define SUBTLV_IDRP_ASN 2
214 static struct tok isis_subtlv_idrp_values
[] = {
215 { SUBTLV_IDRP_RES
, "Reserved"},
216 { SUBTLV_IDRP_LOCAL
, "Routing-Domain Specific"},
217 { SUBTLV_IDRP_ASN
, "AS Number Tag"},
221 #define ISIS_8BIT_MASK(x) ((x)&0xff)
223 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
224 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
225 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
226 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
227 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
228 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
229 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
230 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
232 #define ISIS_MASK_MTID(x) ((x)&0xfff)
233 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
234 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
236 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
237 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
239 #define ISIS_MASK_TLV_EXT_IP6_IE(x) ((x)&0x40)
240 #define ISIS_MASK_TLV_EXT_IP6_SUBTLV(x) ((x)&0x20)
242 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
243 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
245 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
246 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
247 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
248 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
250 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
252 static struct tok isis_gmpls_link_prot_values
[] = {
253 { 0x01, "Extra Traffic"},
254 { 0x02, "Unprotected"},
256 { 0x08, "Dedicated 1:1"},
257 { 0x10, "Dedicated 1+1"},
264 static struct tok isis_gmpls_sw_cap_values
[] = {
265 { 1, "Packet-Switch Capable-1"},
266 { 2, "Packet-Switch Capable-2"},
267 { 3, "Packet-Switch Capable-3"},
268 { 4, "Packet-Switch Capable-4"},
269 { 51, "Layer-2 Switch Capable"},
270 { 100, "Time-Division-Multiplex"},
271 { 150, "Lambda-Switch Capable"},
272 { 200, "Fiber-Switch Capable"},
276 static struct tok isis_gmpls_lsp_enc_values
[] = {
278 { 2, "Ethernet V2/DIX"},
281 { 5, "SDH ITU-T G.707"},
282 { 6, "SONET ANSI T1.105"},
283 { 7, "Digital Wrapper"},
284 { 8, "Lambda (photonic)"},
286 { 10, "Ethernet 802.3"},
287 { 11, "FiberChannel"},
291 static struct tok isis_mt_values
[] = {
292 { 0, "IPv4 unicast"},
293 { 1, "In-Band Management"},
294 { 2, "IPv6 unicast"},
296 { 4095, "Development, Experimental or Proprietary"},
300 static struct tok isis_iih_circuit_type_values
[] = {
301 { 1, "Level 1 only"},
302 { 2, "Level 2 only"},
303 { 3, "Level 1, Level 2"},
307 #define ISIS_LSP_TYPE_UNUSED0 0
308 #define ISIS_LSP_TYPE_LEVEL_1 1
309 #define ISIS_LSP_TYPE_UNUSED2 2
310 #define ISIS_LSP_TYPE_LEVEL_2 3
312 static struct tok isis_lsp_istype_values
[] = {
313 { ISIS_LSP_TYPE_UNUSED0
, "Unused 0x0 (invalid)"},
314 { ISIS_LSP_TYPE_LEVEL_1
, "L1 IS"},
315 { ISIS_LSP_TYPE_UNUSED2
, "Unused 0x2 (invalid)"},
316 { ISIS_LSP_TYPE_LEVEL_2
, "L1L2 IS"},
320 static struct tok osi_nlpid_values
[] = {
321 { NLPID_CLNS
, "CLNS"},
323 { NLPID_IP6
, "IPv6"},
328 * Katz's point to point adjacency TLV uses codes to tell us the state of
329 * the remote adjacency. Enumerate them.
332 #define ISIS_PTP_ADJ_UP 0
333 #define ISIS_PTP_ADJ_INIT 1
334 #define ISIS_PTP_ADJ_DOWN 2
337 static struct tok isis_ptp_adjancey_values
[] = {
338 { ISIS_PTP_ADJ_UP
, "Up" },
339 { ISIS_PTP_ADJ_INIT
, "Initializing" },
340 { ISIS_PTP_ADJ_DOWN
, "Down" },
344 struct isis_tlv_ptp_adj
{
345 u_int8_t adjacency_state
;
346 u_int8_t extd_local_circuit_id
[4];
347 u_int8_t neighbor_sysid
[SYSTEM_ID_LEN
];
348 u_int8_t neighbor_extd_local_circuit_id
[4];
351 static int osi_cksum(const u_int8_t
*, u_int
);
352 static void esis_print(const u_int8_t
*, u_int
);
353 static int isis_print(const u_int8_t
*, u_int
);
355 struct isis_metric_block
{
356 u_int8_t metric_default
;
357 u_int8_t metric_delay
;
358 u_int8_t metric_expense
;
359 u_int8_t metric_error
;
362 struct isis_tlv_is_reach
{
363 struct isis_metric_block isis_metric_block
;
364 u_int8_t neighbor_nodeid
[NODE_ID_LEN
];
367 struct isis_tlv_es_reach
{
368 struct isis_metric_block isis_metric_block
;
369 u_int8_t neighbor_sysid
[SYSTEM_ID_LEN
];
372 struct isis_tlv_ip_reach
{
373 struct isis_metric_block isis_metric_block
;
378 static struct tok isis_is_reach_virtual_values
[] = {
379 { 0, "IsNotVirtual"},
384 struct isis_common_header
{
387 u_int8_t version
; /* Protocol version? */
389 u_int8_t pdu_type
; /* 3 MSbs are reserved */
390 u_int8_t pdu_version
; /* Packet format version? */
395 struct isis_iih_lan_header
{
396 u_int8_t circuit_type
;
397 u_int8_t source_id
[SYSTEM_ID_LEN
];
398 u_int8_t holding_time
[2];
401 u_int8_t lan_id
[NODE_ID_LEN
];
404 struct isis_iih_ptp_header
{
405 u_int8_t circuit_type
;
406 u_int8_t source_id
[SYSTEM_ID_LEN
];
407 u_int8_t holding_time
[2];
412 struct isis_lsp_header
{
414 u_int8_t remaining_lifetime
[2];
415 u_int8_t lsp_id
[LSP_ID_LEN
];
416 u_int8_t sequence_number
[4];
417 u_int8_t checksum
[2];
421 struct isis_csnp_header
{
423 u_int8_t source_id
[NODE_ID_LEN
];
424 u_int8_t start_lsp_id
[LSP_ID_LEN
];
425 u_int8_t end_lsp_id
[LSP_ID_LEN
];
428 struct isis_psnp_header
{
430 u_int8_t source_id
[NODE_ID_LEN
];
433 struct isis_tlv_lsp
{
434 u_int8_t remaining_lifetime
[2];
435 u_int8_t lsp_id
[LSP_ID_LEN
];
436 u_int8_t sequence_number
[4];
437 u_int8_t checksum
[2];
441 /* allocate space for the following string
442 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
443 * 32 bytes plus one termination byte */
445 print_nsap(register const u_int8_t
*pptr
, register int nsap_length
)
448 static char nsap_ascii_output
[33];
449 char *junk_buf
= nsap_ascii_output
;
451 if (nsap_length
< 1 || nsap_length
> 13) {
452 junk_buf
+=sprintf(junk_buf
, "illegal length");
454 return (nsap_ascii_output
);
457 for (nsap_idx
= 0; nsap_idx
< nsap_length
; nsap_idx
++) {
458 if (!TTEST2(*pptr
, 1))
460 junk_buf
+=sprintf(junk_buf
, "%02x", *pptr
++);
461 if (((nsap_idx
& 1) == 0) &&
462 (nsap_idx
+ 1 < nsap_length
)) {
463 junk_buf
+=sprintf(junk_buf
, ".");
467 return (nsap_ascii_output
);
470 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
471 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
472 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
473 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
474 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
475 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
477 void isoclns_print(const u_int8_t
*p
, u_int length
, u_int caplen
,
478 const u_int8_t
*esrc
, const u_int8_t
*edst
)
481 const struct isis_common_header
*header
;
483 header
= (const struct isis_common_header
*)p
;
484 pdu_type
= header
->pdu_type
& PDU_TYPE_MASK
;
486 printf("%sOSI ", caplen
< 1 ? "|" : "");
487 if (!eflag
&& esrc
!= NULL
&& edst
!= NULL
)
488 (void)printf("%s > %s, ",
489 etheraddr_string(esrc
),
490 etheraddr_string(edst
));
492 if (caplen
< 1) /* enough bytes on the wire ? */
498 (void)printf("CLNS, length: %u", length
);
502 esis_print(p
, length
);
506 if (!isis_print(p
, length
))
507 print_unknown_data(p
,"\n\t",caplen
);
511 (void)printf("ISO NULLNS, length: %u", length
);
515 (void)printf("Unknown NLPID 0x%02x, length: %u", p
[0], length
);
517 print_unknown_data(p
,"\n\t",caplen
);
522 #define ESIS_REDIRECT 6
526 static struct tok esis_values
[] = {
527 { ESIS_REDIRECT
, "redirect"},
542 esis_print(const u_int8_t
*p
, u_int length
)
546 const struct esis_hdr
*eh
;
552 printf(" no header at all!");
556 eh
= (const struct esis_hdr
*) &p
[2];
562 printf(" LI(%d) > PDU size (%d)!", li
, length
);
565 if (li
< sizeof(struct esis_hdr
) + 2) {
569 printf(" too short for esis header %d:", li
);
570 while (--length
!= 0)
571 printf("%02X", *p
++);
576 printf("ES-IS, %s, length: %u",
577 tok2str(esis_values
,"unknown type: %u",eh
->type
& 0x1f),
583 if (vflag
&& osi_cksum(p
, li
)) {
584 printf(" bad cksum (got 0x%02x%02x)",
585 eh
->cksum
[1], eh
->cksum
[0]);
586 default_print(p
, length
);
589 if (eh
->version
!= 1) {
590 printf(" unsupported version %d", eh
->version
);
593 p
+= sizeof(*eh
) + 2;
594 li
-= sizeof(*eh
) + 2; /* protoid * li */
596 switch (eh
->type
& 0x1f) {
597 case ESIS_REDIRECT
: {
598 const u_int8_t
*dst
, *snpa
, *is
;
600 dst
= p
; p
+= *p
+ 1;
603 printf("\n\t\t %s", isonsap_string(dst
));
604 snpa
= p
; p
+= *p
+ 1;
613 printf(" > %s", etheraddr_string(&snpa
[1]));
615 printf(" > %s", isonsap_string(is
));
634 printf("\n\tNET: %s", print_nsap(is
+1,*is
));
642 print_unknown_data(p
,"\n\t ",snapend
-p
);
647 /* hexdump - FIXME ? */
650 print_unknown_data(p
,"\n\t ",snapend
-p
);
653 while (p
< ep
&& li
) {
660 printf(", bad opts/li");
667 printf(", opt (%d) too long", op
);
677 if (op
== TLV_HOLDTIME
&& opli
== 2) {
678 printf("\n\tholdtime: %us", EXTRACT_16BITS(q
));
682 if (op
== TLV_PROTOCOLS
&& opli
>= 1) {
683 printf("\n\t%s (length: %u): %s",
684 tok2str(isis_tlv_values
, "unknown", op
),
686 tok2str(osi_nlpid_values
,"Unknown 0x%02x",*q
));
690 print_unknown_data(q
,"\n\t ",opli
);
694 /* allocate space for the following string
696 * 14 bytes plus one termination byte */
698 isis_print_sysid(const u_int8_t
*cp
, int sysid_len
)
701 static char sysid
[15];
704 for (i
= 1; i
<= sysid_len
; i
++) {
707 pos
+=sprintf(pos
, "%02x", *cp
++);
709 pos
+=sprintf(pos
, ".");
717 /* allocate space for the following string
719 * 17 bytes plus one termination byte */
721 isis_print_nodeid(const u_int8_t
*cp
)
724 static char nodeid
[18];
727 for (i
= 1; i
<= 7; i
++) {
730 pos
+=sprintf(pos
, "%02x", *cp
++);
732 pos
+=sprintf(pos
, ".");
739 /* allocate space for the following string
740 * xxxx.xxxx.xxxx.yy-zz
741 * 20 bytes plus one termination byte */
743 isis_print_lspid(const u_int8_t
*cp
)
746 static char lspid
[21];
749 for (i
= 1; i
<= 7; i
++) {
750 pos
+=sprintf(pos
, "%02x", *cp
++);
752 pos
+=sprintf(pos
, ".");
754 pos
+=sprintf(pos
, "-%02x", *cp
);
758 /* print the 4-byte metric block which is common found in the old-style TLVs */
761 isis_print_metric_block (const struct isis_metric_block
*isis_metric_block
)
763 printf(", Default Metric: %d, %s",
764 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_default
),
765 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_default
) ? "External" : "Internal");
766 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_delay
))
767 printf("\n\t\t Delay Metric: %d, %s",
768 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_delay
),
769 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_delay
) ? "External" : "Internal");
770 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_expense
))
771 printf("\n\t\t Expense Metric: %d, %s",
772 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_expense
),
773 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_expense
) ? "External" : "Internal");
774 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block
->metric_error
))
775 printf("\n\t\t Error Metric: %d, %s",
776 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block
->metric_error
),
777 ISIS_LSP_TLV_METRIC_IE(isis_metric_block
->metric_error
) ? "External" : "Internal");
779 return(1); /* everything is ok */
783 isis_print_tlv_ip_reach (const u_int8_t
*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 ((size_t)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\tIPv4 prefix: %s mask %s",
829 ipaddr_string((tlv_ip_reach
->prefix
)),
830 ipaddr_string((tlv_ip_reach
->mask
)));
832 printf("\n\t\tIPv4 prefix: %s/%u",
833 ipaddr_string((tlv_ip_reach
->prefix
)),
836 printf("\n\t\t Default Metric: %02d, %s, Distribution: %s",
837 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_default
),
838 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "External" : "Internal",
839 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach
->isis_metric_block
.metric_default
) ? "down" : "up");
841 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_delay
))
842 printf("\n\t\t Delay Metric: %02d, %s",
843 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_delay
),
844 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_delay
) ? "External" : "Internal");
846 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_expense
))
847 printf("\n\t\t Expense Metric: %02d, %s",
848 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_expense
),
849 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.metric_expense
) ? "External" : "Internal");
851 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach
->isis_metric_block
.metric_error
))
852 printf("\n\t\t Error Metric: %02d, %s",
853 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach
->isis_metric_block
.metric_error
),
854 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach
->isis_metric_block
.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_int8_t
*tptr
,int subt
,int subl
,const char *ident
) {
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(!print_unknown_data(tptr
,"\n\t\t ",
899 printf("%spacket exceeded snapshot",ident
);
904 * this is the common IS-REACH subTLV decoder it is called
905 * from isis_print_ext_is_reach()
909 isis_print_is_reach_subtlv (const u_int8_t
*tptr
,int subt
,int subl
,const char *ident
) {
912 union { /* int to float conversion buffer for several subTLVs */
918 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP
:
919 if (!TTEST2(*tptr
,4))
921 printf("%sAdministrative groups: 0x%08x",
923 EXTRACT_32BITS(tptr
));
925 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID
:
926 if (!TTEST2(*tptr
,4))
928 printf("%sLink Local Identifier: 0x%08x",
930 EXTRACT_32BITS(tptr
));
932 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID
:
933 if (!TTEST2(*tptr
,4))
935 printf("%sLink Remote Identifier: 0x%08x",
937 EXTRACT_32BITS(tptr
));
939 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW
:
940 if (!TTEST2(*tptr
,4))
942 bw
.i
= EXTRACT_32BITS(tptr
);
943 printf("%sMaximum link bandwidth : %.3f Mbps",
947 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW
:
948 if (!TTEST2(*tptr
,4))
950 bw
.i
= EXTRACT_32BITS(tptr
);
951 printf("%sReservable link bandwidth: %.3f Mbps",
955 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW
:
956 printf("%sUnreserved bandwidth:",ident
);
957 for (i
= 0; i
< 8; i
++) {
958 if (!TTEST2(*(tptr
+i
*4),4))
960 bw
.i
= 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))
991 printf("%sLink Protection Type: %s, Priority %u",
993 bittok2str(isis_gmpls_link_prot_values
, "none", *tptr
),
996 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR
:
997 printf("%sInterface Switching Capability",ident
);
999 if (!TTEST2(*tptr
,1))
1001 printf("%s Interface Switching Capability:%s",
1003 tok2str(isis_gmpls_sw_cap_values
, "Unknown", *(tptr
)));
1005 if (!TTEST2(*(tptr
+1),1))
1007 printf(", LSP Encoding: %s",
1008 tok2str(isis_gmpls_lsp_enc_values
, "Unknown", *(tptr
+1)));
1010 if (!TTEST2(*(tptr
+2),2)) /* skip 2 res. bytes */
1013 printf("%s Max LSP Bandwidth:",ident
);
1014 for (i
= 0; i
< 8; i
++) {
1015 if (!TTEST2(*(tptr
+(i
*4)+4),4))
1017 bw
.i
= EXTRACT_32BITS(tptr
);
1018 printf("%s priority level %d: %.3f Mbps",
1024 /* there is some optional stuff left to decode but this is as of yet
1025 not specified so just lets hexdump what is left */
1027 if(!print_unknown_data(tptr
,"\n\t\t ",
1037 printf("%sReserved for cisco specific extensions, type %d, length %d",
1043 printf("%sReserved for future expansion, type %d, length %d",
1049 printf("%sunknown subTLV, type %d, length %d",
1053 if(!print_unknown_data(tptr
,"\n\t\t ",
1061 printf("%spacket exceeded snapshot",ident
);
1067 * this is the common IS-REACH decoder it is called
1068 * from various EXTD-IS REACH style TLVs (22,24,222)
1072 isis_print_ext_is_reach (const u_int8_t
*tptr
,const char *ident
) {
1074 char ident_buffer
[20];
1075 int subt
,subl
,tslen
;
1076 int proc_bytes
= 0; /* how many bytes did we process ? */
1078 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1081 printf("%sIS Neighbor: %s", ident
, isis_print_nodeid(tptr
));
1082 tptr
+=(NODE_ID_LEN
);
1084 if (!TTEST2(*tptr
, 3))
1086 printf(", Metric: %d",EXTRACT_24BITS(tptr
));
1089 if (!TTEST2(*tptr
, 1))
1091 tslen
=*(tptr
++); /* read out subTLV length */
1092 proc_bytes
=NODE_ID_LEN
+3+1;
1093 printf(", %ssub-TLVs present",tslen
? "" : "no ");
1095 printf(" (%u)",tslen
);
1097 if (!TTEST2(*tptr
,2))
1101 /* prepend the ident string */
1102 snprintf(ident_buffer
, sizeof(ident_buffer
), "%s ",ident
);
1103 if(!isis_print_is_reach_subtlv(tptr
,subt
,subl
,ident_buffer
))
1107 proc_bytes
+=(subl
+2);
1114 * this is the common Multi Topology ID decoder
1115 * it is called from various MT-TLVs (222,229,235,237)
1119 isis_print_mtid (const u_int8_t
*tptr
,const char *ident
) {
1121 if (!TTEST2(*tptr
, 2))
1126 tok2str(isis_mt_values
,
1127 "Reserved for IETF Consensus",
1128 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
))));
1130 printf(" Topology (0x%03x)%s%s",
1131 ISIS_MASK_MTID(EXTRACT_16BITS(tptr
)),
1132 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr
)) ? "" : ", no sub-TLVs present",
1133 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr
)) ? ", ATT bit set" : "" );
1139 * this is the common extended IP reach decoder
1140 * it is called from TLVs (135,235,236,237)
1141 * we process the TLV and optional subTLVs and return
1142 * the amount of processed bytes
1146 isis_print_extd_ip_reach (const u_int8_t
*tptr
, const char *ident
, u_int16_t afi
) {
1148 char ident_buffer
[20];
1149 u_int8_t prefix
[14]; /* shared copy buffer for IPv4 and IPv6 prefixes */
1150 u_int metric
, status_byte
, bit_length
, byte_length
, sublen
, processed
, subtlvtype
, subtlvlen
;
1152 if (!TTEST2(*tptr
, 4))
1154 metric
= EXTRACT_32BITS(tptr
);
1159 if (!TTEST2(*tptr
, 1)) /* fetch status byte */
1161 status_byte
=*(tptr
++);
1162 bit_length
= status_byte
&0x3f;
1165 } else if (afi
== IPV6
) {
1166 if (!TTEST2(*tptr
, 1)) /* fetch status & prefix_len byte */
1168 status_byte
=*(tptr
++);
1169 bit_length
=*(tptr
++);
1173 return (0); /* somebody is fooling us */
1175 byte_length
= (bit_length
+ 7) / 8; /* prefix has variable length encoding */
1177 if (!TTEST2(*tptr
, byte_length
))
1179 memset(prefix
, 0, 16); /* clear the copy buffer */
1180 memcpy(prefix
,tptr
,byte_length
); /* copy as much as is stored in the TLV */
1182 processed
+=byte_length
;
1185 printf("%sIPv4 prefix: %s/%d",
1187 ipaddr_string(prefix
),
1191 printf("%sIPv6 prefix: %s/%d",
1193 ip6addr_string(prefix
),
1197 printf("%s Metric: %u, Distribution: %s",
1200 ISIS_MASK_TLV_EXT_IP_UPDOWN(status_byte
) ? "down" : "up");
1203 printf(", %ssub-TLVs present",
1204 ISIS_MASK_TLV_EXT_IP_SUBTLV(status_byte
) ? "" : "no ");
1207 printf(", %s, %ssub-TLVs present",
1208 ISIS_MASK_TLV_EXT_IP6_IE(status_byte
) ? "External" : "Internal",
1209 ISIS_MASK_TLV_EXT_IP6_SUBTLV(status_byte
) ? "" : "no ");
1212 if ((ISIS_MASK_TLV_EXT_IP_SUBTLV(status_byte
) && afi
== IPV4
) ||
1213 (ISIS_MASK_TLV_EXT_IP6_SUBTLV(status_byte
) && afi
== IPV6
)) {
1214 /* assume that one prefix can hold more
1215 than one subTLV - therefore the first byte must reflect
1216 the aggregate bytecount of the subTLVs for this prefix
1218 if (!TTEST2(*tptr
, 1))
1222 printf(" (%u)",sublen
); /* print out subTLV length */
1225 if (!TTEST2(*tptr
,2))
1227 subtlvtype
=*(tptr
++);
1228 subtlvlen
=*(tptr
++);
1229 /* prepend the ident string */
1230 snprintf(ident_buffer
, sizeof(ident_buffer
), "%s ",ident
);
1231 if(!isis_print_ip_reach_subtlv(tptr
,subtlvtype
,subtlvlen
,ident_buffer
))
1234 sublen
-=(subtlvlen
+2);
1242 * Decode IS-IS packets. Return 0 on error.
1245 static int isis_print (const u_int8_t
*p
, u_int length
)
1247 const struct isis_common_header
*header
;
1249 const struct isis_iih_lan_header
*header_iih_lan
;
1250 const struct isis_iih_ptp_header
*header_iih_ptp
;
1251 const struct isis_lsp_header
*header_lsp
;
1252 const struct isis_csnp_header
*header_csnp
;
1253 const struct isis_psnp_header
*header_psnp
;
1255 const struct isis_tlv_lsp
*tlv_lsp
;
1256 const struct isis_tlv_ptp_adj
*tlv_ptp_adj
;
1257 const struct isis_tlv_is_reach
*tlv_is_reach
;
1258 const struct isis_tlv_es_reach
*tlv_es_reach
;
1260 u_int8_t pdu_type
, max_area
, id_length
, type
, len
, tmp
, alen
, lan_alen
, prefix_len
;
1261 u_int8_t ext_is_len
, ext_ip_len
, mt_len
;
1262 const u_int8_t
*optr
, *pptr
, *tptr
;
1263 u_short packet_len
,pdu_len
,time_remain
;
1267 optr
= p
; /* initialize the _o_riginal pointer to the packet start -
1268 need it for parsing the checksum TLV */
1269 header
= (const struct isis_common_header
*)p
;
1271 pptr
= p
+(ISIS_COMMON_HEADER_SIZE
);
1272 header_iih_lan
= (const struct isis_iih_lan_header
*)pptr
;
1273 header_iih_ptp
= (const struct isis_iih_ptp_header
*)pptr
;
1274 header_lsp
= (const struct isis_lsp_header
*)pptr
;
1275 header_csnp
= (const struct isis_csnp_header
*)pptr
;
1276 header_psnp
= (const struct isis_psnp_header
*)pptr
;
1279 * Sanity checking of the header.
1282 if (header
->version
!= ISIS_VERSION
) {
1283 printf(", version %d packet not supported", header
->version
);
1287 if ((header
->id_length
!= SYSTEM_ID_LEN
) && (header
->id_length
!= 0)) {
1288 printf(", system ID length of %d is not supported",
1293 if (header
->pdu_version
!= ISIS_VERSION
) {
1294 printf(", version %d packet not supported", header
->pdu_version
);
1298 max_area
= header
->max_area
;
1301 max_area
= 3; /* silly shit */
1304 printf(", bad packet -- 255 areas");
1310 id_length
= header
->id_length
;
1313 id_length
= 6; /* silly shit again */
1315 case 1: /* 1-8 are valid sys-ID lenghts */
1325 id_length
= 0; /* entirely useless */
1328 printf(", bad packet -- illegal sys-ID length (%u)", id_length
);
1333 pdu_type
=header
->pdu_type
;
1335 /* in non-verbose mode just lets print the basic PDU Type*/
1337 printf("IS-IS, %s, length: %u",
1338 tok2str(isis_pdu_values
,"unknown PDU-Type %u",pdu_type
),
1343 /* ok they seem to want to know everything - lets fully decode it */
1344 printf("IS-IS, length: %u",length
);
1346 printf("\n\thlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1349 header
->pdu_version
,
1355 /* first lets see if we know the PDU name*/
1356 printf(", pdu-type: %s",
1357 tok2str(isis_pdu_values
,
1362 if(!print_unknown_data(optr
,"\n\t",8)) /* provide the _o_riginal pointer */
1363 return(0); /* for optionally debugging the common header */
1370 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
)) {
1371 printf(", bogus fixed header length %u should be %lu",
1372 header
->fixed_len
, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE
);
1376 pdu_len
=EXTRACT_16BITS(header_iih_lan
->pdu_len
);
1377 if (packet_len
>pdu_len
) {
1378 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1382 TCHECK(*header_iih_lan
);
1383 printf("\n\t source-id: %s, holding time: %u, %s",
1384 isis_print_sysid(header_iih_lan
->source_id
,SYSTEM_ID_LEN
),
1385 EXTRACT_16BITS(header_iih_lan
->holding_time
),
1386 tok2str(isis_iih_circuit_type_values
,
1387 "unknown circuit type 0x%02x",
1388 header_iih_lan
->circuit_type
));
1390 printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
1391 isis_print_nodeid(header_iih_lan
->lan_id
),
1392 (header_iih_lan
->priority
) & PRIORITY_MASK
,
1396 if(!print_unknown_data(pptr
,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE
))
1400 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1401 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_LAN_HEADER_SIZE
);
1405 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
)) {
1406 printf(", bogus fixed header length %u should be %lu",
1407 header
->fixed_len
, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE
);
1411 pdu_len
=EXTRACT_16BITS(header_iih_ptp
->pdu_len
);
1412 if (packet_len
>pdu_len
) {
1413 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1417 TCHECK(*header_iih_ptp
);
1418 printf("\n\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1419 isis_print_sysid(header_iih_ptp
->source_id
,SYSTEM_ID_LEN
),
1420 EXTRACT_16BITS(header_iih_ptp
->holding_time
),
1421 header_iih_ptp
->circuit_id
,
1422 tok2str(isis_iih_circuit_type_values
,
1423 "unknown circuit type 0x%02x",
1424 header_iih_ptp
->circuit_type
),
1428 if(!print_unknown_data(pptr
,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE
))
1432 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1433 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_IIH_PTP_HEADER_SIZE
);
1438 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
)) {
1439 printf(", bogus fixed header length %u should be %lu",
1440 header
->fixed_len
, (unsigned long)ISIS_LSP_HEADER_SIZE
);
1444 pdu_len
=EXTRACT_16BITS(header_lsp
->pdu_len
);
1445 if (packet_len
>pdu_len
) {
1446 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1450 TCHECK(*header_lsp
);
1451 printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1452 isis_print_lspid(header_lsp
->lsp_id
),
1453 EXTRACT_32BITS(header_lsp
->sequence_number
),
1454 EXTRACT_16BITS(header_lsp
->remaining_lifetime
));
1455 /* verify the checksum -
1456 * checking starts at the lsp-id field
1457 * which is 12 bytes after the packet start*/
1458 printf("\n\t chksum: 0x%04x (%s), PDU length: %u",
1459 EXTRACT_16BITS(header_lsp
->checksum
),
1460 (osi_cksum(optr
+12, length
-12)) ? "incorrect" : "correct",
1463 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp
->typeblock
) ? "Overload bit set, " : "");
1465 if (ISIS_MASK_LSP_ATT_BITS(header_lsp
->typeblock
)) {
1466 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp
->typeblock
) ? "default " : "");
1467 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp
->typeblock
) ? "delay " : "");
1468 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp
->typeblock
) ? "expense " : "");
1469 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp
->typeblock
) ? "error " : "");
1470 printf("ATT bit set, ");
1472 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp
->typeblock
) ? "P bit set, " : "");
1473 printf("%s", tok2str(isis_lsp_istype_values
,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp
->typeblock
)));
1476 if(!print_unknown_data(pptr
,"\n\t ",ISIS_LSP_HEADER_SIZE
))
1480 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1481 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_LSP_HEADER_SIZE
);
1486 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
)) {
1487 printf(", bogus fixed header length %u should be %lu",
1488 header
->fixed_len
, (unsigned long)ISIS_CSNP_HEADER_SIZE
);
1492 pdu_len
=EXTRACT_16BITS(header_csnp
->pdu_len
);
1493 if (packet_len
>pdu_len
) {
1494 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1498 TCHECK(*header_csnp
);
1499 printf("\n\t source-id: %s, PDU length: %u",
1500 isis_print_nodeid(header_csnp
->source_id
),
1502 printf("\n\t start lsp-id: %s",
1503 isis_print_lspid(header_csnp
->start_lsp_id
));
1504 printf("\n\t end lsp-id: %s",
1505 isis_print_lspid(header_csnp
->end_lsp_id
));
1508 if(!print_unknown_data(pptr
,"\n\t ",ISIS_CSNP_HEADER_SIZE
))
1512 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1513 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_CSNP_HEADER_SIZE
);
1518 if (header
->fixed_len
!= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
)) {
1519 printf("- bogus fixed header length %u should be %lu",
1520 header
->fixed_len
, (unsigned long)ISIS_PSNP_HEADER_SIZE
);
1524 pdu_len
=EXTRACT_16BITS(header_psnp
->pdu_len
);
1525 if (packet_len
>pdu_len
) {
1526 packet_len
=pdu_len
; /* do TLV decoding as long as it makes sense */
1530 TCHECK(*header_psnp
);
1531 printf("\n\t source-id: %s",
1532 isis_print_nodeid(header_psnp
->source_id
));
1535 if(!print_unknown_data(pptr
,"\n\t ",ISIS_PSNP_HEADER_SIZE
))
1539 packet_len
-= (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1540 pptr
= p
+ (ISIS_COMMON_HEADER_SIZE
+ISIS_PSNP_HEADER_SIZE
);
1544 if(!print_unknown_data(pptr
,"\n\t ",length
))
1550 * Now print the TLV's.
1553 while (packet_len
>= 2) {
1554 if (pptr
== snapend
) {
1558 if (!TTEST2(*pptr
, 2)) {
1559 printf("\n\t\t packet exceeded snapshot (%ld) bytes",
1560 (long)(pptr
-snapend
));
1565 tmp
=len
; /* copy temporary len & pointer to packet data */
1568 if (len
> packet_len
) {
1572 /* first lets see if we know the TLVs name*/
1573 printf("\n\t %s TLV #%u, length: %u",
1574 tok2str(isis_tlv_values
,
1580 /* now check if we have a decoder otherwise do a hexdump at the end*/
1583 if (!TTEST2(*tptr
, 1))
1586 while (tmp
&& alen
< tmp
) {
1587 printf("\n\t\tArea address (length: %u): %s",
1589 print_nsap(tptr
, alen
));
1592 if (tmp
==0) /* if this is the last area address do not attemt a boundary check */
1594 if (!TTEST2(*tptr
, 1))
1600 while (tmp
>= ETHER_ADDR_LEN
) {
1601 if (!TTEST2(*tptr
, ETHER_ADDR_LEN
))
1603 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,ETHER_ADDR_LEN
));
1604 tmp
-= ETHER_ADDR_LEN
;
1605 tptr
+= ETHER_ADDR_LEN
;
1609 case TLV_ISNEIGH_VARLEN
:
1610 if (!TTEST2(*tptr
, 1))
1612 lan_alen
= *tptr
++; /* LAN adress length */
1614 printf("\n\t\tLAN address length %u bytes ",lan_alen
);
1615 while (tmp
>= lan_alen
) {
1616 if (!TTEST2(*tptr
, lan_alen
))
1618 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr
,lan_alen
));
1627 case TLV_MT_IS_REACH
:
1628 while (tmp
>= 2+NODE_ID_LEN
+3+1) {
1629 mt_len
= isis_print_mtid(tptr
, "\n\t\t");
1630 if (mt_len
== 0) /* did something go wrong ? */
1635 ext_is_len
= isis_print_ext_is_reach(tptr
,"\n\t\t");
1636 if (ext_is_len
== 0) /* did something go wrong ? */
1644 case TLV_IS_ALIAS_ID
:
1645 while (tmp
>= NODE_ID_LEN
+3+1) { /* is it worth attempting a decode ? */
1646 ext_is_len
= isis_print_ext_is_reach(tptr
,"\n\t\t");
1647 if (ext_is_len
== 0) /* did something go wrong ? */
1654 case TLV_EXT_IS_REACH
:
1655 while (tmp
>= NODE_ID_LEN
+3+1) { /* is it worth attempting a decode ? */
1656 ext_is_len
= isis_print_ext_is_reach(tptr
,"\n\t\t");
1657 if (ext_is_len
== 0) /* did something go wrong ? */
1664 if (!TTEST2(*tptr
,1)) /* check if there is one byte left to read out the virtual flag */
1667 tok2str(isis_is_reach_virtual_values
,
1668 "bogus virtual flag 0x%02x",
1670 tlv_is_reach
= (const struct isis_tlv_is_reach
*)tptr
;
1671 while (tmp
>= sizeof(struct isis_tlv_is_reach
)) {
1672 if (!TTEST(*tlv_is_reach
))
1674 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach
->neighbor_nodeid
));
1675 isis_print_metric_block(&tlv_is_reach
->isis_metric_block
);
1676 tmp
-= sizeof(struct isis_tlv_is_reach
);
1682 tlv_es_reach
= (const struct isis_tlv_es_reach
*)tptr
;
1683 while (tmp
>= sizeof(struct isis_tlv_es_reach
)) {
1684 if (!TTEST(*tlv_es_reach
))
1686 printf("\n\t\tES Neighbor: %s",
1687 isis_print_sysid(tlv_es_reach
->neighbor_sysid
,SYSTEM_ID_LEN
));
1688 isis_print_metric_block(&tlv_es_reach
->isis_metric_block
);
1689 tmp
-= sizeof(struct isis_tlv_es_reach
);
1694 /* those two TLVs share the same format */
1696 case TLV_IP_REACH_EXT
:
1697 if (!isis_print_tlv_ip_reach(pptr
, len
))
1701 case TLV_EXT_IP_REACH
:
1703 ext_ip_len
= isis_print_extd_ip_reach(tptr
, "\n\t\t", IPV4
);
1704 if (ext_ip_len
== 0) /* did something go wrong ? */
1711 case TLV_MT_IP_REACH
:
1713 mt_len
= isis_print_mtid(tptr
, "\n\t\t");
1714 if (mt_len
== 0) /* did something go wrong ? */
1719 ext_ip_len
= isis_print_extd_ip_reach(tptr
, "\n\t\t", IPV4
);
1720 if (ext_ip_len
== 0) /* did something go wrong ? */
1730 ext_ip_len
= isis_print_extd_ip_reach(tptr
, "\n\t\t", IPV6
);
1731 if (ext_ip_len
== 0) /* did something go wrong ? */
1738 case TLV_MT_IP6_REACH
:
1740 mt_len
= isis_print_mtid(tptr
, "\n\t\t");
1741 if (mt_len
== 0) /* did something go wrong ? */
1746 ext_ip_len
= isis_print_extd_ip_reach(tptr
, "\n\t\t", IPV6
);
1747 if (ext_ip_len
== 0) /* did something go wrong ? */
1756 if (!TTEST2(*tptr
, 16))
1759 printf("\n\t\tIPv6 interface address: %s",
1760 ip6addr_string(tptr
));
1768 if (!TTEST2(*tptr
, 1))
1771 printf("\n\t\t%s: ",
1772 tok2str(isis_subtlv_auth_values
,
1773 "unknown Authentication type 0x%02x",
1777 case SUBTLV_AUTH_SIMPLE
:
1778 for(i
=1;i
<len
;i
++) {
1779 if (!TTEST2(*(tptr
+i
), 1))
1781 printf("%c",*(tptr
+i
));
1784 case SUBTLV_AUTH_MD5
:
1785 for(i
=1;i
<len
;i
++) {
1786 if (!TTEST2(*(tptr
+i
), 1))
1788 printf("%02x",*(tptr
+i
));
1790 if (len
!= SUBTLV_AUTH_MD5_LEN
+1)
1791 printf(", (malformed subTLV) ");
1793 case SUBTLV_AUTH_PRIVATE
:
1795 if(!print_unknown_data(tptr
+1,"\n\t\t ",len
-1))
1802 tlv_ptp_adj
= (const struct isis_tlv_ptp_adj
*)tptr
;
1804 if (!TTEST2(*tptr
, 1))
1806 printf("\n\t\tAdjacency State: %s",
1807 tok2str(isis_ptp_adjancey_values
, "0x%02x", *tptr
));
1810 if(tmp
>sizeof(tlv_ptp_adj
->extd_local_circuit_id
)) {
1811 if (!TTEST2(tlv_ptp_adj
->extd_local_circuit_id
,
1812 sizeof(tlv_ptp_adj
->extd_local_circuit_id
)))
1814 printf("\n\t\tExtended Local circuit ID: 0x%08x",
1815 EXTRACT_32BITS(tlv_ptp_adj
->extd_local_circuit_id
));
1816 tmp
-=sizeof(tlv_ptp_adj
->extd_local_circuit_id
);
1818 if(tmp
>=SYSTEM_ID_LEN
) {
1819 if (!TTEST2(tlv_ptp_adj
->neighbor_sysid
, SYSTEM_ID_LEN
))
1821 printf("\n\t\tNeighbor SystemID: %s",
1822 isis_print_sysid(tlv_ptp_adj
->neighbor_sysid
,SYSTEM_ID_LEN
));
1825 if(tmp
>=sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)) {
1826 if (!TTEST2(tlv_ptp_adj
->neighbor_extd_local_circuit_id
,
1827 sizeof(tlv_ptp_adj
->neighbor_extd_local_circuit_id
)))
1829 printf("\n\t\tNeighbor Extended Local circuit ID: 0x%08x",
1830 EXTRACT_32BITS(tlv_ptp_adj
->neighbor_extd_local_circuit_id
));
1835 printf("\n\t\tNLPID(s): ");
1837 if (!TTEST2(*(tptr
), 1))
1840 tok2str(osi_nlpid_values
,
1843 if (tmp
>1) /* further NPLIDs ? - put comma */
1849 case TLV_TE_ROUTER_ID
:
1850 if (!TTEST2(*pptr
, 4))
1852 printf("\n\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr
));
1857 if (!TTEST2(*tptr
, 4))
1859 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1866 printf("\n\t\tHostname: ");
1868 if (!TTEST2(*tptr
, 1))
1870 printf("%c",*tptr
++);
1875 case TLV_SHARED_RISK_GROUP
:
1876 if (!TTEST2(*tptr
, NODE_ID_LEN
))
1878 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr
));
1879 tptr
+=(NODE_ID_LEN
);
1882 if (!TTEST2(*tptr
, 1))
1884 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr
++) ? "numbered" : "unnumbered");
1887 if (!TTEST2(*tptr
,4))
1889 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr
));
1893 if (!TTEST2(*tptr
,4))
1895 printf("\n\t\tIPv4 neighbor address: %s", ipaddr_string(tptr
));
1900 if (!TTEST2(*tptr
, 4))
1902 printf("\n\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr
));
1909 tlv_lsp
= (const struct isis_tlv_lsp
*)tptr
;
1911 printf("\n\t\tlsp-id: %s",
1912 isis_print_nodeid(tlv_lsp
->lsp_id
));
1913 if (!TTEST((tlv_lsp
->lsp_id
)[NODE_ID_LEN
]))
1915 printf("-%02x",(tlv_lsp
->lsp_id
)[NODE_ID_LEN
]);
1916 if (!TTEST2(tlv_lsp
->sequence_number
, 4))
1918 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp
->sequence_number
));
1919 if (!TTEST2(tlv_lsp
->remaining_lifetime
, 2))
1921 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp
->remaining_lifetime
));
1922 if (!TTEST2(tlv_lsp
->checksum
, 2))
1924 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp
->checksum
));
1925 tmp
-=sizeof(struct isis_tlv_lsp
);
1931 if (!TTEST2(*tptr
, 2))
1933 printf("\n\t\tchecksum: 0x%04x (%s)",
1934 EXTRACT_16BITS(tptr
),
1935 (osi_cksum(optr
, length
)) ? "incorrect" : "correct");
1938 case TLV_MT_SUPPORTED
:
1940 /* length can only be a multiple of 2, otherwise there is
1941 something broken -> so decode down until length is 1 */
1943 mt_len
= isis_print_mtid(tptr
, "\n\t\t");
1944 if (mt_len
== 0) /* did something go wrong ? */
1949 printf("\n\t\tmalformed MT-ID");
1955 case TLV_RESTART_SIGNALING
:
1956 if (!TTEST2(*tptr
, 3))
1958 rr
= ISIS_MASK_TLV_RESTART_RR(*tptr
);
1959 ra
= ISIS_MASK_TLV_RESTART_RA(*tptr
);
1961 time_remain
= EXTRACT_16BITS(tptr
);
1962 printf("\n\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\tRemaining holding time: %us",
1963 rr
? "set" : "clear", ra
? "set" : "clear", time_remain
);
1967 if (!TTEST2(*tptr
, 1))
1969 printf("\n\t\tInter-Domain Information Type: %s",
1970 tok2str(isis_subtlv_idrp_values
,
1974 case SUBTLV_IDRP_ASN
:
1975 if (!TTEST2(*tptr
, 2)) /* fetch AS number */
1977 printf("AS Number: %u",EXTRACT_16BITS(tptr
));
1979 case SUBTLV_IDRP_LOCAL
:
1980 case SUBTLV_IDRP_RES
:
1982 if(!print_unknown_data(tptr
,"\n\t\t",len
-1))
1988 case TLV_LSP_BUFFERSIZE
:
1989 if (!TTEST2(*tptr
, 2))
1991 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr
));
1995 while (tmp
>= SYSTEM_ID_LEN
) {
1996 if (!TTEST2(*tptr
, SYSTEM_ID_LEN
))
1998 printf("%s",isis_print_sysid(tptr
,SYSTEM_ID_LEN
));
1999 tptr
+=SYSTEM_ID_LEN
;
2004 case TLV_PREFIX_NEIGH
:
2005 if (!TTEST2(*tptr
, sizeof(struct isis_metric_block
)))
2007 printf("Metric Block");
2008 isis_print_metric_block((const struct isis_metric_block
*)tptr
);
2009 tptr
+=sizeof(struct isis_metric_block
);
2010 tmp
-=sizeof(struct isis_metric_block
);
2013 if (!TTEST2(*tptr
, 1))
2015 prefix_len
=*tptr
++; /* read out prefix length in semioctets*/
2017 if (!TTEST2(*tptr
, prefix_len
/2))
2019 printf("\n\t\tAddress: %s/%u",
2020 print_nsap(tptr
,prefix_len
/2),
2028 if (!TTEST2(*tptr
, 4)) /* check if four bytes are on the wire */
2030 printf("\n\t\tSequence number: %u", EXTRACT_32BITS(tptr
) );
2033 case TLV_VENDOR_PRIVATE
:
2034 if (!TTEST2(*tptr
, 3)) /* check if enough byte for a full oui */
2036 printf("\n\t\tVendor OUI Code: 0x%06x", EXTRACT_24BITS(tptr
) );
2039 if (tmp
> 0) /* hexdump the rest */
2040 if(!print_unknown_data(tptr
,"\n\t\t",tmp
))
2044 * FIXME those are the defined TLVs that lack a decoder
2045 * you are welcome to contribute code ;-)
2048 case TLV_DECNET_PHASE4
:
2049 case TLV_LUCENT_PRIVATE
:
2051 case TLV_NORTEL_PRIVATE1
:
2052 case TLV_NORTEL_PRIVATE2
:
2056 if(!print_unknown_data(pptr
,"\n\t\t",len
))
2061 /* do we want to see an additionally hexdump ? */
2063 if(!print_unknown_data(pptr
,"\n\t\t",len
))
2071 if (packet_len
!= 0) {
2072 printf("\n\t\t %d straggler bytes", packet_len
);
2077 fputs("[|isis]", stdout
);
2081 printf("\n\t\t packet exceeded snapshot");
2086 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2090 osi_cksum(const u_int8_t
*tptr
, u_int len
)
2092 int32_t c0
= 0, c1
= 0;
2094 while ((int)--len
>= 0) {