]> The Tcpdump Group git mirrors - tcpdump/blob - print-isoclns.c
Tweak the description of the "-D" flag, add an indication of when "-D"
[tcpdump] / print-isoclns.c
1 /*
2 * Copyright (c) 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
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
16 * written permission.
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.
20 *
21 * Original code by Matt Thomas, Digital Equipment Corporation
22 *
23 * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
24 * complete IS-IS support.
25 */
26
27 #ifndef lint
28 static const char rcsid[] =
29 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.56 2002-08-01 08:53:13 risso Exp $ (LBL)";
30 #endif
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <tcpdump-stdinc.h>
37
38 #include <stdio.h>
39 #include <string.h>
40
41 #include "interface.h"
42 #include "addrtoname.h"
43 #include "ethertype.h"
44 #include "ether.h"
45 #include "extract.h"
46
47 #define NLPID_CLNS 129 /* 0x81 */
48 #define NLPID_ESIS 130 /* 0x82 */
49 #define NLPID_ISIS 131 /* 0x83 */
50 #define NLPID_IP6 0x8e
51 #define NLPID_IP 0xcc
52 #define NLPID_NULLNS 0
53
54 /*
55 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
56 */
57
58 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
59 #define NODE_ID_LEN SYSTEM_ID_LEN+1
60 #define LSP_ID_LEN SYSTEM_ID_LEN+2
61
62 #define ISIS_VERSION 1
63 #define PDU_TYPE_MASK 0x1F
64 #define PRIORITY_MASK 0x7F
65
66 #define L1_LAN_IIH 15
67 #define L2_LAN_IIH 16
68 #define PTP_IIH 17
69 #define L1_LSP 18
70 #define L2_LSP 20
71 #define L1_CSNP 24
72 #define L2_CSNP 25
73 #define L1_PSNP 26
74 #define L2_PSNP 27
75
76 static struct tok isis_pdu_values[] = {
77 { L1_LAN_IIH, "L1 Lan IIH"},
78 { L2_LAN_IIH, "L2 Lan IIH"},
79 { PTP_IIH, "p2p IIH"},
80 { L1_LSP, "L1 LSP"},
81 { L2_LSP, "L2 LSP"},
82 { L1_CSNP, "L1 CSNP"},
83 { L2_CSNP, "L2 CSNP"},
84 { L1_PSNP, "L1 PSNP"},
85 { L2_PSNP, "L2 PSNP"},
86 { 0, NULL}
87 };
88
89 /*
90 * A TLV is a tuple of a type, length and a value and is normally used for
91 * encoding information in all sorts of places. This is an enumeration of
92 * the well known types.
93 *
94 * list taken from draft-ietf-isis-wg-tlv-codepoints-01.txt
95 */
96
97 #define TLV_AREA_ADDR 1
98 #define TLV_IS_REACH 2
99 #define TLV_ESNEIGH 3
100 #define TLV_PART_DIS 4
101 #define TLV_PREFIX_NEIGH 5
102 #define TLV_ISNEIGH 6
103 #define TLV_ISNEIGH_VARLEN 7
104 #define TLV_PADDING 8
105 #define TLV_LSP 9
106 #define TLV_AUTH 10
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
133
134 static struct tok isis_tlv_values[] = {
135 { TLV_AREA_ADDR, "Area address(es)"},
136 { TLV_IS_REACH, "IS Reachability"},
137 { TLV_ESNEIGH, "ES Neighbor(s)"},
138 { TLV_PART_DIS, "Partition DIS"},
139 { TLV_PREFIX_NEIGH, "Prefix Neighbors"},
140 { TLV_ISNEIGH, "IS Neighbor(s)"},
141 { TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"},
142 { TLV_PADDING, "Padding"},
143 { TLV_LSP, "LSP entries"},
144 { TLV_AUTH, "Authentication"},
145 { TLV_CHECKSUM, "Checksum"},
146 { TLV_LSP_BUFFERSIZE, "LSP Buffersize"},
147 { TLV_EXT_IS_REACH, "Extended IS Reachability"},
148 { TLV_IS_ALIAS_ID, "IS Alias ID"},
149 { TLV_DECNET_PHASE4, "DECnet Phase IV"},
150 { TLV_LUCENT_PRIVATE, "Lucent Proprietary"},
151 { TLV_IP_REACH, "IPv4 Internal reachability"},
152 { TLV_PROTOCOLS, "Protocols supported"},
153 { TLV_IP_REACH_EXT, "IPv4 External reachability"},
154 { TLV_IDRP_INFO, "Inter-Domain Information Type"},
155 { TLV_IPADDR, "IPv4 Interface address(es)"},
156 { TLV_IPAUTH, "IPv4 authentication (deprecated)"},
157 { TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"},
158 { TLV_EXT_IP_REACH, "Extended IPv4 reachability"},
159 { TLV_HOSTNAME, "Hostname"},
160 { TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"},
161 { TLV_NORTEL_PRIVATE1, "Nortel Proprietary"},
162 { TLV_NORTEL_PRIVATE2, "Nortel Proprietary"},
163 { TLV_RESTART_SIGNALING, "Restart Signaling"},
164 { TLV_MT_IS_REACH, "Multi Topology IS Reachability"},
165 { TLV_MT_SUPPORTED, "Multi Topology"},
166 { TLV_IP6ADDR, "IPv6 Interface address(es)"},
167 { TLV_MT_IP_REACH, "Multi-Topology IPv4 reachability"},
168 { TLV_IP6_REACH, "IPv6 reachability"},
169 { TLV_MT_IP6_REACH, "Multi-Topology IP6 reachability"},
170 { TLV_PTP_ADJ, "Point-to-point Adjacency State"},
171 { 0, NULL }
172 };
173
174 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
175 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
176 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
177 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
178 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
179 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
180 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
181 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
182 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
183 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
184 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
185
186 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
187 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
188
189 #define SUBTLV_AUTH_SIMPLE 1
190 #define SUBTLV_AUTH_MD5 54
191 #define SUBTLV_AUTH_MD5_LEN 16
192 #define SUBTLV_AUTH_PRIVATE 255
193
194 static struct tok isis_subtlv_auth_values[] = {
195 { SUBTLV_AUTH_SIMPLE, "simple text password"},
196 { SUBTLV_AUTH_MD5, "HMAC-MD5 password"},
197 { SUBTLV_AUTH_PRIVATE, "Routing Domain private password"},
198 { 0, NULL }
199 };
200
201 #define SUBTLV_IDRP_RES 0
202 #define SUBTLV_IDRP_LOCAL 1
203 #define SUBTLV_IDRP_ASN 2
204
205 static struct tok isis_subtlv_idrp_values[] = {
206 { SUBTLV_IDRP_RES, "Reserved"},
207 { SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"},
208 { SUBTLV_IDRP_ASN, "AS Number Tag"},
209 { 0, NULL}
210 };
211
212 #define ISIS_8BIT_MASK(x) ((x)&0xff)
213
214 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
215 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
216 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
217 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
218 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
219 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
220 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
221 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
222
223 #define ISIS_MASK_MTID(x) ((x)&0xfff)
224 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
225 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
226
227 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
228 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
229
230 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80)
231 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40)
232 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20)
233
234 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
235 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
236
237 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
238 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
239 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
240 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
241
242 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
243
244 static const char *isis_gmpls_link_prot_values[] = {
245 "Extra",
246 "Unprotected",
247 "Shared",
248 "Dedicated 1:1",
249 "Dedicated 1+1",
250 "Enhanced",
251 "Reserved",
252 "Reserved"
253 };
254
255 static struct tok isis_gmpls_sw_cap_values[] = {
256 { 1, "Packet-Switch Capable-1"},
257 { 2, "Packet-Switch Capable-2"},
258 { 3, "Packet-Switch Capable-3"},
259 { 4, "Packet-Switch Capable-4"},
260 { 51, "Layer-2 Switch Capable"},
261 { 100, "Time-Division-Multiplex"},
262 { 150, "Lambda-Switch Capable"},
263 { 200, "Fiber-Switch Capable"},
264 { 0, NULL }
265 };
266
267 static struct tok isis_gmpls_lsp_enc_values[] = {
268 { 1, "Packet"},
269 { 2, "Ethernet V2/DIX"},
270 { 3, "ANSI PDH"},
271 { 4, "ETSI PDH"},
272 { 5, "SDH ITU-T G.707"},
273 { 6, "SONET ANSI T1.105"},
274 { 7, "Digital Wrapper"},
275 { 8, "Lambda (photonic)"},
276 { 9, "Fiber"},
277 { 10, "Ethernet 802.3"},
278 { 11, "FiberChannel"},
279 { 0, NULL }
280 };
281
282 static struct tok isis_mt_values[] = {
283 { 0, "IPv4 unicast"},
284 { 1, "In-Band Management"},
285 { 2, "IPv6 unicast"},
286 { 3, "Multicast"},
287 { 4095, "Development, Experimental or Proprietary"},
288 { 0, NULL }
289 };
290
291 static struct tok isis_iih_circuit_type_values[] = {
292 { 1, "Level 1 only"},
293 { 2, "Level 2 only"},
294 { 3, "Level 1, Level 2"},
295 { 0, NULL}
296 };
297
298 #define ISIS_LSP_TYPE_UNUSED0 0
299 #define ISIS_LSP_TYPE_LEVEL_1 1
300 #define ISIS_LSP_TYPE_UNUSED2 2
301 #define ISIS_LSP_TYPE_LEVEL_2 3
302
303 static struct tok isis_lsp_istype_values[] = {
304 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
305 { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
306 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
307 { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"},
308 { 0, NULL }
309 };
310
311 static struct tok isis_nlpid_values[] = {
312 { NLPID_CLNS, "CLNS"},
313 { NLPID_IP, "IPv4"},
314 { NLPID_IP6, "IPv6"},
315 { 0, NULL }
316 };
317
318 /*
319 * Katz's point to point adjacency TLV uses codes to tell us the state of
320 * the remote adjacency. Enumerate them.
321 */
322
323 #define ISIS_PTP_ADJ_UP 0
324 #define ISIS_PTP_ADJ_INIT 1
325 #define ISIS_PTP_ADJ_DOWN 2
326
327
328 static struct tok isis_ptp_adjancey_values[] = {
329 { ISIS_PTP_ADJ_UP, "Up" },
330 { ISIS_PTP_ADJ_INIT, "Initializing" },
331 { ISIS_PTP_ADJ_DOWN, "Down" },
332 { 0, NULL}
333 };
334
335 struct isis_tlv_ptp_adj {
336 u_char adjacency_state;
337 u_char extd_local_circuit_id[4];
338 u_char neighbor_sysid[SYSTEM_ID_LEN];
339 u_char neighbor_extd_local_circuit_id[4];
340 };
341
342 static int osi_cksum(const u_char *, u_int);
343 static void esis_print(const u_char *, u_int);
344 static int isis_print(const u_char *, u_int);
345
346 struct isis_metric_block {
347 u_char metric_default;
348 u_char metric_delay;
349 u_char metric_expense;
350 u_char metric_error;
351 };
352
353 struct isis_tlv_is_reach {
354 struct isis_metric_block isis_metric_block;
355 u_char neighbor_nodeid[NODE_ID_LEN];
356 };
357
358 struct isis_tlv_es_reach {
359 struct isis_metric_block isis_metric_block;
360 u_char neighbor_sysid[SYSTEM_ID_LEN];
361 };
362
363 struct isis_tlv_ip_reach {
364 struct isis_metric_block isis_metric_block;
365 u_char prefix[4];
366 u_char mask[4];
367 };
368
369 static struct tok isis_is_reach_virtual_values[] = {
370 { 0, "IsNotVirtual"},
371 { 1, "IsVirtual"},
372 { 0, NULL }
373 };
374
375 struct isis_common_header {
376 u_char nlpid;
377 u_char fixed_len;
378 u_char version; /* Protocol version? */
379 u_char id_length;
380 u_char pdu_type; /* 3 MSbs are reserved */
381 u_char pdu_version; /* Packet format version? */
382 u_char reserved;
383 u_char max_area;
384 };
385
386 struct isis_iih_lan_header {
387 u_char circuit_type;
388 u_char source_id[SYSTEM_ID_LEN];
389 u_char holding_time[2];
390 u_char pdu_len[2];
391 u_char priority;
392 u_char lan_id[NODE_ID_LEN];
393 };
394
395 struct isis_iih_ptp_header {
396 u_char circuit_type;
397 u_char source_id[SYSTEM_ID_LEN];
398 u_char holding_time[2];
399 u_char pdu_len[2];
400 u_char circuit_id;
401 };
402
403 struct isis_lsp_header {
404 u_char pdu_len[2];
405 u_char remaining_lifetime[2];
406 u_char lsp_id[LSP_ID_LEN];
407 u_char sequence_number[4];
408 u_char checksum[2];
409 u_char typeblock;
410 };
411
412 struct isis_csnp_header {
413 u_char pdu_len[2];
414 u_char source_id[NODE_ID_LEN];
415 u_char start_lsp_id[LSP_ID_LEN];
416 u_char end_lsp_id[LSP_ID_LEN];
417 };
418
419 struct isis_psnp_header {
420 u_char pdu_len[2];
421 u_char source_id[NODE_ID_LEN];
422 };
423
424 struct isis_tlv_lsp {
425 u_char remaining_lifetime[2];
426 u_char lsp_id[LSP_ID_LEN];
427 u_char sequence_number[4];
428 u_char checksum[2];
429 };
430
431
432 /* allocate space for the following string
433 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
434 * 32 bytes plus one termination byte */
435 static char *
436 print_nsap(register const u_char *cp, register int length)
437 {
438 int i;
439 static char nsap[33];
440 char *pos = nsap;
441
442 if (length==0) {
443 *(pos) = '0';
444 *(pos+1) = '\0';
445 return (nsap);
446 }
447
448 for (i = 0; i < length; i++) {
449 if (!TTEST2(*cp, 1))
450 return (0);
451 pos+=sprintf(pos, "%02x", *cp++);
452 if (((i & 1) == 0) && (i + 1 < length)) {
453 pos+=sprintf(pos, ".");
454 }
455 }
456 *(pos) = '\0';
457 return (nsap);
458 }
459
460 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
461 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
462 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
463 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
464 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
465 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
466
467 void isoclns_print(const u_char *p, u_int length, u_int caplen,
468 const u_char *esrc, const u_char *edst)
469 {
470 u_char pdu_type;
471 const struct isis_common_header *header;
472
473 header = (const struct isis_common_header *)p;
474 pdu_type = header->pdu_type & PDU_TYPE_MASK;
475
476 if (caplen < 1) {
477 printf("[|iso-clns] ");
478 if (!eflag && esrc != NULL && edst != NULL)
479 printf("%s > %s",
480 etheraddr_string(esrc),
481 etheraddr_string(edst));
482 return;
483 }
484
485 switch (*p) {
486
487 case NLPID_CLNS:
488 (void)printf("CLNS(%d)", length);
489 if (!eflag && esrc != NULL && edst != NULL)
490 (void)printf(", %s > %s",
491 etheraddr_string(esrc),
492 etheraddr_string(edst));
493 break;
494
495 case NLPID_ESIS:
496 (void)printf("ESIS(%u)", length);
497 if (!eflag && esrc != NULL && edst != NULL)
498 (void)printf(", %s > %s",
499 etheraddr_string(esrc),
500 etheraddr_string(edst));
501 esis_print(p, length);
502 return;
503
504 case NLPID_ISIS:
505 (void)printf("ISIS(%u)", length);
506 if (!eflag && esrc != NULL && edst != NULL)
507 (void)printf(", %s > %s",
508 etheraddr_string(esrc),
509 etheraddr_string(edst));
510 if (!isis_print(p, length))
511 default_print_unaligned(p, caplen);
512 break;
513
514 case NLPID_NULLNS:
515 (void)printf("ISO NULLNS(%d)", length);
516 if (!eflag && esrc != NULL && edst != NULL)
517 (void)printf(", %s > %s",
518 etheraddr_string(esrc),
519 etheraddr_string(edst));
520 break;
521
522 default:
523 (void)printf("CLNS %02x(%d)", p[0], length);
524 if (!eflag && esrc != NULL && edst != NULL)
525 (void)printf(", %s > %s",
526 etheraddr_string(esrc),
527 etheraddr_string(edst));
528 if (caplen > 1)
529 default_print_unaligned(p, caplen);
530 break;
531 }
532 }
533
534 #define ESIS_REDIRECT 6
535 #define ESIS_ESH 2
536 #define ESIS_ISH 4
537
538 struct esis_hdr {
539 u_char version;
540 u_char reserved;
541 u_char type;
542 u_char tmo[2];
543 u_char cksum[2];
544 };
545
546 static void
547 esis_print(const u_char *p, u_int length)
548 {
549 const u_char *ep;
550 u_int li;
551 const struct esis_hdr *eh;
552
553 if (length <= 2) {
554 if (qflag)
555 printf(" bad pkt!");
556 else
557 printf(" no header at all!");
558 return;
559 }
560 li = p[1];
561 eh = (const struct esis_hdr *) &p[2];
562 ep = p + li;
563 if (li > length) {
564 if (qflag)
565 printf(" bad pkt!");
566 else
567 printf(" LI(%d) > PDU size (%d)!", li, length);
568 return;
569 }
570 if (li < sizeof(struct esis_hdr) + 2) {
571 if (qflag)
572 printf(" bad pkt!");
573 else {
574 printf(" too short for esis header %d:", li);
575 while (--length != 0)
576 printf("%02X", *p++);
577 }
578 return;
579 }
580 switch (eh->type & 0x1f) {
581
582 case ESIS_REDIRECT:
583 printf(" redirect");
584 break;
585
586 case ESIS_ESH:
587 printf(" ESH");
588 break;
589
590 case ESIS_ISH:
591 printf(" ISH");
592 break;
593
594 default:
595 printf(" type %d", eh->type & 0x1f);
596 break;
597 }
598 if (vflag && osi_cksum(p, li)) {
599 printf(" bad cksum (got 0x%02x%02x)",
600 eh->cksum[1], eh->cksum[0]);
601 default_print(p, length);
602 return;
603 }
604 if (eh->version != 1) {
605 printf(" unsupported version %d", eh->version);
606 return;
607 }
608 p += sizeof(*eh) + 2;
609 li -= sizeof(*eh) + 2; /* protoid * li */
610
611 switch (eh->type & 0x1f) {
612 case ESIS_REDIRECT: {
613 const u_char *dst, *snpa, *is;
614
615 dst = p; p += *p + 1;
616 if (p > snapend)
617 return;
618 printf("\n\t\t %s", isonsap_string(dst));
619 snpa = p; p += *p + 1;
620 is = p; p += *p + 1;
621 if (p > snapend)
622 return;
623 if (p > ep) {
624 printf(" [bad li]");
625 return;
626 }
627 if (is[0] == 0)
628 printf(" > %s", etheraddr_string(&snpa[1]));
629 else
630 printf(" > %s", isonsap_string(is));
631 li = ep - p;
632 break;
633 }
634 #if 0
635 case ESIS_ESH:
636 printf(" ESH");
637 break;
638 #endif
639 case ESIS_ISH: {
640 const u_char *is;
641
642 is = p; p += *p + 1;
643 if (p > ep) {
644 printf(" [bad li]");
645 return;
646 }
647 if (p > snapend)
648 return;
649 if (!qflag)
650 printf("\n\tNET: %s", print_nsap(is+1,*is));
651 li = ep - p;
652 break;
653 }
654
655 default:
656 (void)printf(" len=%d", length);
657 if (length && p < snapend) {
658 length = snapend - p;
659 default_print(p, length);
660 }
661 return;
662 }
663 if (vflag)
664 while (p < ep && li) {
665 u_int op, opli;
666 const u_char *q;
667
668 if (snapend - p < 2)
669 return;
670 if (li < 2) {
671 printf(" bad opts/li");
672 return;
673 }
674 op = *p++;
675 opli = *p++;
676 li -= 2;
677 if (opli > li) {
678 printf(" opt (%d) too long", op);
679 return;
680 }
681 li -= opli;
682 q = p;
683 p += opli;
684 if (snapend < p)
685 return;
686 if (op == 198 && opli == 2) {
687 printf(" tmo=%d", q[0] * 256 + q[1]);
688 continue;
689 }
690 printf (" %d:<", op);
691 while (opli-- > 0)
692 printf("%02x", *q++);
693 printf (">");
694 }
695 }
696
697 /* allocate space for the following string
698 * xxxx.xxxx.xxxx
699 * 14 bytes plus one termination byte */
700 static char *
701 isis_print_sysid(const u_char *cp, int sysid_len)
702 {
703 int i;
704 static char sysid[15];
705 char *pos = sysid;
706
707 for (i = 1; i <= sysid_len; i++) {
708 if (!TTEST2(*cp, 1))
709 return (0);
710 pos+=sprintf(pos, "%02x", *cp++);
711 if ((i==2)^(i==4)) {
712 pos+=sprintf(pos, ".");
713 }
714 }
715 *(pos) = '\0';
716 return (sysid);
717 }
718
719
720 /* allocate space for the following string
721 * xxxx.xxxx.xxxx.yy
722 * 17 bytes plus one termination byte */
723 static char *
724 isis_print_nodeid(const u_char *cp)
725 {
726 int i;
727 static char nodeid[18];
728 char *pos = nodeid;
729
730 for (i = 1; i <= 7; i++) {
731 if (!TTEST2(*cp, 1))
732 return (0);
733 pos+=sprintf(pos, "%02x", *cp++);
734 if ((i & 1) == 0) {
735 pos+=sprintf(pos, ".");
736 }
737 }
738 *(pos) = '\0';
739 return (nodeid);
740 }
741
742 /* allocate space for the following string
743 * xxxx.xxxx.xxxx.yy-zz
744 * 20 bytes plus one termination byte */
745 static char *
746 isis_print_lspid(const u_char *cp)
747 {
748 int i;
749 static char lspid[21];
750 char *pos = lspid;
751
752 for (i = 1; i <= 7; i++) {
753 pos+=sprintf(pos, "%02x", *cp++);
754 if ((i & 1) == 0)
755 pos+=sprintf(pos, ".");
756 }
757 pos+=sprintf(pos, "-%02x", *cp);
758 return (lspid);
759 }
760
761 /* print the 4-byte metric block which is common found in the old-style TLVs */
762
763 static int
764 isis_print_metric_block (const struct isis_metric_block *isis_metric_block)
765 {
766 printf(", Default Metric: %d, %s",
767 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default),
768 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal");
769 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay))
770 printf("\n\t\t Delay Metric: %d, %s",
771 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay),
772 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal");
773 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense))
774 printf("\n\t\t Expense Metric: %d, %s",
775 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense),
776 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal");
777 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error))
778 printf("\n\t\t Error Metric: %d, %s",
779 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error),
780 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal");
781
782 return(1); /* everything is ok */
783 }
784
785 static int
786 isis_print_tlv_ip_reach (const u_char *cp, int length)
787 {
788 u_int bitmasks[33] = {
789 0x00000000,
790 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
791 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
792 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
793 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
794 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
795 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
796 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
797 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
798 };
799 u_int mask;
800 int prefix_len;
801 const struct isis_tlv_ip_reach *tlv_ip_reach;
802
803 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
804
805 while (length > 0) {
806 if (length < sizeof(*tlv_ip_reach)) {
807 printf("short IPv4 reachability (%d vs %lu)", length,
808 (unsigned long)sizeof(*tlv_ip_reach));
809 return (0);
810 }
811
812 if (!TTEST(*tlv_ip_reach))
813 return (0);
814
815 mask = EXTRACT_32BITS(tlv_ip_reach->mask);
816 prefix_len = 0;
817
818 /* lets see if we can transform the mask into a prefixlen */
819 while (prefix_len <= 33) {
820 if (bitmasks[prefix_len++] == mask) {
821 prefix_len--;
822 break;
823 }
824 }
825
826 /*
827 * 34 indicates no match -> must be a discontiguous netmask
828 * lets dump the mask, otherwise print the prefix_len
829 */
830 if (prefix_len == 34)
831 printf("\n\t\tIPv4 prefix: %s mask %s",
832 ipaddr_string((tlv_ip_reach->prefix)),
833 ipaddr_string((tlv_ip_reach->mask)));
834 else
835 printf("\n\t\tIPv4 prefix: %s/%u",
836 ipaddr_string((tlv_ip_reach->prefix)),
837 prefix_len);
838
839 printf("\n\t\t Default Metric: %02d, %s, Distribution: %s",
840 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default),
841 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal",
842 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up");
843
844 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay))
845 printf("\n\t\t Delay Metric: %02d, %s",
846 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay),
847 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal");
848
849 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense))
850 printf("\n\t\t Expense Metric: %02d, %s",
851 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense),
852 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal");
853
854 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error))
855 printf("\n\t\t Error Metric: %02d, %s",
856 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error),
857 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal");
858
859 length -= sizeof(struct isis_tlv_ip_reach);
860 tlv_ip_reach++;
861 }
862 return (1);
863 }
864
865 /*
866 * this is the common IP-REACH subTLV decoder it is called
867 * from various EXTD-IP REACH TLVs (135,235,236,237)
868 */
869
870 static int
871 isis_print_ip_reach_subtlv (const u_char *tptr,int subt,int subl,const char *lf) {
872
873 switch(subt) {
874 case SUBTLV_IP_REACH_ADMIN_TAG32:
875 if (!TTEST2(*tptr,4))
876 goto trunctlv;
877 printf("%s32-Bit Administrative tag: 0x%08x",
878 lf,
879 EXTRACT_32BITS(tptr));
880 break;
881 case SUBTLV_IP_REACH_ADMIN_TAG64:
882 if (!TTEST2(*tptr,8))
883 goto trunctlv;
884 printf("%s64-Bit Administrative tag: 0x%08x%08x",
885 lf,
886 EXTRACT_32BITS(tptr),
887 EXTRACT_32BITS(tptr+4));
888 break;
889 default:
890 printf("%sunknown subTLV, type %d, length %d",
891 lf,
892 subt,
893 subl);
894 if(!print_unknown_data(tptr,"\n\t\t ",
895 subl))
896 return(0);
897 break;
898 }
899 return(1);
900
901 trunctlv:
902 printf("%spacket exceeded snapshot",lf);
903 return(0);
904 }
905
906 /*
907 * this is the common IS-REACH subTLV decoder it is called
908 * from various EXTD-IS REACH TLVs (22,24,222)
909 */
910
911 static int
912 isis_print_is_reach_subtlv (const u_char *tptr,int subt,int subl,const char *lf) {
913
914 int i,j;
915 float bw; /* copy buffer for several subTLVs */
916
917 switch(subt) {
918 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
919 if (!TTEST2(*tptr,4))
920 goto trunctlv;
921 printf("%sAdministrative groups: 0x%08x",
922 lf,
923 EXTRACT_32BITS(tptr));
924 break;
925 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID:
926 if (!TTEST2(*tptr,4))
927 goto trunctlv;
928 printf("%sLink Local Identifier: 0x%08x",
929 lf,
930 EXTRACT_32BITS(tptr));
931 break;
932 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
933 if (!TTEST2(*tptr,4))
934 goto trunctlv;
935 printf("%sLink Remote Identifier: 0x%08x",
936 lf,
937 EXTRACT_32BITS(tptr));
938 break;
939 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
940 if (!TTEST2(*tptr,4))
941 goto trunctlv;
942 j = EXTRACT_32BITS(tptr);
943 memcpy (&bw, &j, 4);
944 printf("%sMaximum link bandwidth : %.3f Mbps",
945 lf,
946 bw*8/1000000 );
947 break;
948 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW :
949 if (!TTEST2(*tptr,4))
950 goto trunctlv;
951 j = EXTRACT_32BITS(tptr);
952 memcpy (&bw, &j, 4);
953 printf("%sReservable link bandwidth: %.3f Mbps",
954 lf,
955 bw*8/1000000 );
956 break;
957 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
958 printf("%sUnreserved bandwidth:",lf);
959 for (i = 0; i < 8; i++) {
960 if (!TTEST2(*(tptr+i*4),4))
961 goto trunctlv;
962 j = EXTRACT_32BITS(tptr);
963 memcpy (&bw, &j, 4);
964 printf("%s priority level %d: %.3f Mbps",
965 lf,
966 i,
967 bw*8/1000000 );
968 }
969 break;
970 case SUBTLV_EXT_IS_REACH_TE_METRIC:
971 if (!TTEST2(*tptr,3))
972 goto trunctlv;
973 printf("%sTraffic Engineering Metric: %d",
974 lf,
975 EXTRACT_24BITS(tptr));
976 break;
977 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
978 if (!TTEST2(*tptr,4))
979 goto trunctlv;
980 printf("%sIPv4 interface address: %s",
981 lf,
982 ipaddr_string(tptr));
983 break;
984 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
985 if (!TTEST2(*tptr,4))
986 goto trunctlv;
987 printf("%sIPv4 neighbor address: %s",
988 lf,
989 ipaddr_string(tptr));
990 break;
991 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
992 if (!TTEST2(*tptr,2))
993 goto trunctlv;
994 i = 0;
995 j = (ISIS_8BIT_MASK(*tptr)); /* fetch the typecode and make sure
996 that no high-order LSBs are set */
997 printf("%sLink Protection Type: %s",
998 lf,
999 (j) ? "" : "none" );
1000 /* scan through the bits until the typecode is zero */
1001 while(!j) {
1002 printf("%s", isis_gmpls_link_prot_values[i]);
1003 j=j>>1;
1004 if (j) /*any other bit set ?*/
1005 printf(", ");
1006 i++;
1007 }
1008 printf(", Priority %u", *(tptr+1));
1009 break;
1010 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
1011 printf("%sInterface Switching Capability",lf);
1012
1013 if (!TTEST2(*tptr,1))
1014 goto trunctlv;
1015 printf("%s Interface Switching Capability:%s",
1016 lf,
1017 tok2str(isis_gmpls_sw_cap_values, "Unknown", *(tptr)));
1018
1019 if (!TTEST2(*(tptr+1),1))
1020 goto trunctlv;
1021 printf(", LSP Encoding: %s",
1022 tok2str(isis_gmpls_lsp_enc_values, "Unknown", *(tptr+1)));
1023
1024 if (!TTEST2(*(tptr+2),2)) /* skip 2 res. bytes */
1025 goto trunctlv;
1026
1027 printf("%s Max LSP Bandwidth:",lf);
1028 for (i = 0; i < 8; i++) {
1029 if (!TTEST2(*(tptr+(i*4)+4),4))
1030 goto trunctlv;
1031 j = EXTRACT_32BITS(tptr);
1032 memcpy (&bw, &j, 4);
1033 printf("%s priority level %d: %.3f Mbps",
1034 lf,
1035 i,
1036 bw*8/1000000 );
1037 }
1038 subl-=36;
1039 /* there is some optional stuff left to decode but this is as of yet
1040 not specified so just lets hexdump what is left */
1041 if(subl>0){
1042 if(!print_unknown_data(tptr,"\n\t\t ",
1043 subl-36))
1044 return(0);
1045 }
1046 break;
1047 case 250:
1048 case 251:
1049 case 252:
1050 case 253:
1051 case 254:
1052 printf("%sReserved for cisco specific extensions, type %d, length %d",
1053 lf,
1054 subt,
1055 subl);
1056 break;
1057 case 255:
1058 printf("%sReserved for future expansion, type %d, length %d",
1059 lf,
1060 subt,
1061 subl);
1062 break;
1063 default:
1064 printf("%sunknown subTLV, type %d, length %d",
1065 lf,
1066 subt,
1067 subl);
1068 if(!print_unknown_data(tptr,"\n\t\t ",
1069 subl))
1070 return(0);
1071 break;
1072 }
1073 return(1);
1074
1075 trunctlv:
1076 printf("%spacket exceeded snapshot",lf);
1077 return(0);
1078 }
1079
1080
1081 /*
1082 * isis_print
1083 * Decode IS-IS packets. Return 0 on error.
1084 */
1085
1086 static int isis_print (const u_char *p, u_int length)
1087 {
1088 const struct isis_common_header *header;
1089
1090 const struct isis_iih_lan_header *header_iih_lan;
1091 const struct isis_iih_ptp_header *header_iih_ptp;
1092 const struct isis_lsp_header *header_lsp;
1093 const struct isis_csnp_header *header_csnp;
1094 const struct isis_psnp_header *header_psnp;
1095
1096 const struct isis_tlv_lsp *tlv_lsp;
1097 const struct isis_tlv_ptp_adj *tlv_ptp_adj;
1098 const struct isis_tlv_is_reach *tlv_is_reach;
1099 const struct isis_tlv_es_reach *tlv_es_reach;
1100
1101 u_char pdu_type, max_area, id_length, type, len, tmp, alen, lan_alen, prefix_len, subl, subt, tslen;
1102 const u_char *optr, *pptr, *tptr;
1103 u_short packet_len,pdu_len,time_remain;
1104 u_int i,j,bit_length,byte_length,metric,ra,rr;
1105 u_char prefix[4]; /* copy buffer for ipv4 prefixes */
1106 #ifdef INET6
1107 u_char prefix6[16]; /* copy buffer for ipv6 prefixes */
1108 #endif
1109 packet_len=length;
1110 optr = p; /* initialize the _o_riginal pointer to the packet start -
1111 need it for parsing the checksum TLV */
1112 header = (const struct isis_common_header *)p;
1113 TCHECK(*header);
1114 pptr = p+(ISIS_COMMON_HEADER_SIZE);
1115 header_iih_lan = (const struct isis_iih_lan_header *)pptr;
1116 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
1117 header_lsp = (const struct isis_lsp_header *)pptr;
1118 header_csnp = (const struct isis_csnp_header *)pptr;
1119 header_psnp = (const struct isis_psnp_header *)pptr;
1120
1121 /*
1122 * Sanity checking of the header.
1123 */
1124 if (header->nlpid != NLPID_ISIS) {
1125 printf(", coding error!");
1126 return (0);
1127 }
1128
1129 if (header->version != ISIS_VERSION) {
1130 printf(", version %d packet not supported", header->version);
1131 return (0);
1132 }
1133
1134 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
1135 printf(", system ID length of %d is not supported",
1136 header->id_length);
1137 return (0);
1138 }
1139
1140 if (header->pdu_version != ISIS_VERSION) {
1141 printf(", version %d packet not supported", header->pdu_version);
1142 return (0);
1143 }
1144
1145 max_area = header->max_area;
1146 switch(max_area) {
1147 case 0:
1148 max_area = 3; /* silly shit */
1149 break;
1150 case 255:
1151 printf(", bad packet -- 255 areas");
1152 return (0);
1153 default:
1154 break;
1155 }
1156
1157 id_length = header->id_length;
1158 switch(id_length) {
1159 case 0:
1160 id_length = 6; /* silly shit again */
1161 break;
1162 case 1: /* 1-8 are valid sys-ID lenghts */
1163 case 2:
1164 case 3:
1165 case 4:
1166 case 5:
1167 case 6:
1168 case 7:
1169 case 8:
1170 break;
1171 case 255:
1172 id_length = 0; /* entirely useless */
1173 break;
1174 default:
1175 printf(", bad packet -- illegal sys-ID length (%u)", id_length);
1176 return (0);
1177 break;
1178 }
1179
1180 printf("\n\thlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1181 header->fixed_len,
1182 header->version,
1183 header->pdu_version,
1184 id_length,
1185 header->id_length,
1186 max_area,
1187 header->max_area);
1188
1189 pdu_type=header->pdu_type;
1190
1191 /* first lets see if we know the PDU name*/
1192 printf(", pdu-type: %s",
1193 tok2str(isis_pdu_values,
1194 "unknown, type %d",
1195 pdu_type));
1196
1197 switch (pdu_type) {
1198
1199 case L1_LAN_IIH:
1200 case L2_LAN_IIH:
1201 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
1202 printf(", bogus fixed header length %u should be %lu",
1203 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE);
1204 return (0);
1205 }
1206
1207 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
1208 if (packet_len>pdu_len) {
1209 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1210 length=pdu_len;
1211 }
1212
1213 TCHECK(*header_iih_lan);
1214 printf("\n\t source-id: %s, holding time: %u, %s",
1215 isis_print_sysid(header_iih_lan->source_id,SYSTEM_ID_LEN),
1216 EXTRACT_16BITS(header_iih_lan->holding_time),
1217 tok2str(isis_iih_circuit_type_values,
1218 "unknown circuit type 0x%02x",
1219 header_iih_lan->circuit_type));
1220
1221 printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
1222 isis_print_nodeid(header_iih_lan->lan_id),
1223 (header_iih_lan->priority) & PRIORITY_MASK,
1224 pdu_len);
1225
1226 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
1227 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
1228 break;
1229
1230 case PTP_IIH:
1231 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
1232 printf(", bogus fixed header length %u should be %lu",
1233 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE);
1234 return (0);
1235 }
1236
1237 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
1238 if (packet_len>pdu_len) {
1239 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1240 length=pdu_len;
1241 }
1242
1243 TCHECK(*header_iih_ptp);
1244 printf("\n\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1245 isis_print_sysid(header_iih_ptp->source_id,SYSTEM_ID_LEN),
1246 EXTRACT_16BITS(header_iih_ptp->holding_time),
1247 header_iih_ptp->circuit_id,
1248 tok2str(isis_iih_circuit_type_values,
1249 "unknown circuit type 0x%02x",
1250 header_iih_ptp->circuit_type),
1251 pdu_len);
1252
1253 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
1254 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
1255 break;
1256
1257 case L1_LSP:
1258 case L2_LSP:
1259 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
1260 printf(", bogus fixed header length %u should be %lu",
1261 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE);
1262 return (0);
1263 }
1264
1265 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
1266 if (packet_len>pdu_len) {
1267 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1268 length=pdu_len;
1269 }
1270
1271 TCHECK(*header_lsp);
1272 printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1273 isis_print_lspid(header_lsp->lsp_id),
1274 EXTRACT_32BITS(header_lsp->sequence_number),
1275 EXTRACT_16BITS(header_lsp->remaining_lifetime));
1276 /* verify the checksum -
1277 * checking starts at the lsp-id field
1278 * which is 12 bytes after the packet start*/
1279 printf("\n\t chksum: 0x%04x (%s), PDU length: %u",
1280 EXTRACT_16BITS(header_lsp->checksum),
1281 (osi_cksum(optr+12, length-12)) ? "incorrect" : "correct",
1282 pdu_len);
1283
1284 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
1285
1286 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
1287 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
1288 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
1289 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
1290 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
1291 printf("ATT bit set, ");
1292 }
1293 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
1294 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
1295
1296 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
1297 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
1298 break;
1299
1300 case L1_CSNP:
1301 case L2_CSNP:
1302 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
1303 printf(", bogus fixed header length %u should be %lu",
1304 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE);
1305 return (0);
1306 }
1307
1308 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
1309 if (packet_len>pdu_len) {
1310 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1311 length=pdu_len;
1312 }
1313
1314 TCHECK(*header_csnp);
1315 printf("\n\t source-id: %s, PDU length: %u",
1316 isis_print_nodeid(header_csnp->source_id),
1317 pdu_len);
1318 printf("\n\t start lsp-id: %s",
1319 isis_print_lspid(header_csnp->start_lsp_id));
1320 printf("\n\t end lsp-id: %s",
1321 isis_print_lspid(header_csnp->end_lsp_id));
1322
1323 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
1324 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
1325 break;
1326
1327 case L1_PSNP:
1328 case L2_PSNP:
1329 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
1330 printf("- bogus fixed header length %u should be %lu",
1331 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE);
1332 return (0);
1333 }
1334
1335 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
1336 if (packet_len>pdu_len) {
1337 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1338 length=pdu_len;
1339 }
1340
1341 TCHECK(*header_psnp);
1342 printf("\n\t source-id: %s",
1343 isis_print_nodeid(header_psnp->source_id));
1344
1345 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
1346 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
1347 break;
1348
1349 default:
1350 if(!print_unknown_data(pptr,"\n\t ",length))
1351 return(0);
1352 return (0);
1353 }
1354
1355 /*
1356 * Now print the TLV's.
1357 */
1358
1359 while (packet_len >= 2) {
1360 if (pptr == snapend) {
1361 return (1);
1362 }
1363
1364 if (!TTEST2(*pptr, 2)) {
1365 printf("\n\t\t packet exceeded snapshot (%ld) bytes",
1366 (long)(pptr-snapend));
1367 return (1);
1368 }
1369 type = *pptr++;
1370 len = *pptr++;
1371 tmp =len; /* copy temporary len & pointer to packet data */
1372 tptr = pptr;
1373 packet_len -= 2;
1374 if (len > packet_len) {
1375 break;
1376 }
1377
1378 /* first lets see if we know the TLVs name*/
1379 printf("\n\t %s TLV #%u, length: %u",
1380 tok2str(isis_tlv_values,
1381 "unknown",
1382 type),
1383 type,
1384 len);
1385
1386 /* now check if we have a decoder otherwise do a hexdump at the end*/
1387 switch (type) {
1388 case TLV_AREA_ADDR:
1389 if (!TTEST2(*tptr, 1))
1390 goto trunctlv;
1391 alen = *tptr++;
1392 while (tmp && alen < tmp) {
1393 printf("\n\t\tArea address (%u): %s",
1394 alen,
1395 print_nsap(tptr, alen));
1396 tptr += alen;
1397 tmp -= alen + 1;
1398 if (tmp==0) /* if this is the last area address do not attemt a boundary check */
1399 break;
1400 if (!TTEST2(*tptr, 1))
1401 goto trunctlv;
1402 alen = *tptr++;
1403 }
1404 break;
1405 case TLV_ISNEIGH:
1406 while (tmp >= ETHER_ADDR_LEN) {
1407 if (!TTEST2(*tptr, ETHER_ADDR_LEN))
1408 goto trunctlv;
1409 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr,ETHER_ADDR_LEN));
1410 tmp -= ETHER_ADDR_LEN;
1411 tptr += ETHER_ADDR_LEN;
1412 }
1413 break;
1414
1415 case TLV_ISNEIGH_VARLEN:
1416 if (!TTEST2(*tptr, 1))
1417 goto trunctlv;
1418 lan_alen = *tptr++; /* LAN adress length */
1419 tmp --;
1420 printf("\n\t\tLAN address length %u bytes ",lan_alen);
1421 while (tmp >= lan_alen) {
1422 if (!TTEST2(*tptr, lan_alen))
1423 goto trunctlv;
1424 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr,lan_alen));
1425 tmp -= lan_alen;
1426 tptr +=lan_alen;
1427 }
1428 break;
1429
1430 case TLV_PADDING:
1431 break;
1432
1433 case TLV_MT_IS_REACH:
1434 while (tmp>0) {
1435 if (!TTEST2(*tptr, 2))
1436 goto trunctlv;
1437 printf("\n\t\t%s",
1438 tok2str(isis_mt_values,
1439 "Reserved for IETF Consensus",
1440 ISIS_MASK_MTID(EXTRACT_16BITS(tptr))));
1441
1442 printf(" Topology (0x%03x)",
1443 ISIS_MASK_MTID(EXTRACT_16BITS(tptr)));
1444 tptr+=2;
1445 if (!TTEST2(*tptr, NODE_ID_LEN))
1446 goto trunctlv;
1447 printf("\n\t\t IS Neighbor: %s", isis_print_nodeid(tptr));
1448 tptr+=(NODE_ID_LEN);
1449 if (!TTEST2(*tptr, 3))
1450 goto trunctlv;
1451 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1452 tptr+=3;
1453 if (!TTEST2(*tptr, 1))
1454 goto trunctlv;
1455 tslen=*(tptr++);
1456 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1457 if (tslen) {
1458 printf(" (%u)",tslen);
1459 while (tslen>0) {
1460 if (!TTEST2(*tptr,2))
1461 goto trunctlv;
1462 subt=*(tptr++);
1463 subl=*(tptr++);
1464 if(!isis_print_is_reach_subtlv(tptr,subt,subl,"\n\t\t "))
1465 return(0);
1466 tptr+=subl;
1467 tslen-=(subl+2);
1468 tmp-=(subl+2);
1469 }
1470 }
1471 tmp-=(SYSTEM_ID_LEN+7);
1472 }
1473 break;
1474
1475 case TLV_EXT_IS_REACH:
1476 while (tmp>0) {
1477 if (!TTEST2(*tptr, NODE_ID_LEN))
1478 goto trunctlv;
1479 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr));
1480 tptr+=(NODE_ID_LEN);
1481
1482 if (!TTEST2(*tptr, 3))
1483 goto trunctlv;
1484 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1485 tptr+=3;
1486
1487 if (!TTEST2(*tptr, 1))
1488 goto trunctlv;
1489 tslen=*(tptr++); /* read out subTLV length */
1490 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1491 if (tslen) {
1492 printf(" (%u)",tslen);
1493 while (tslen>0) {
1494 if (!TTEST2(*tptr,2))
1495 goto trunctlv;
1496 subt=*(tptr++);
1497 subl=*(tptr++);
1498 if(!isis_print_is_reach_subtlv(tptr,subt,subl,"\n\t\t "))
1499 return(0);
1500 tptr+=subl;
1501 tslen-=(subl+2);
1502 tmp-=(subl+2);
1503 }
1504 }
1505 tmp-=(SYSTEM_ID_LEN+5);
1506 }
1507 break;
1508 case TLV_IS_REACH:
1509 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
1510 goto trunctlv;
1511 printf("\n\t\t%s",
1512 tok2str(isis_is_reach_virtual_values,
1513 "bogus virtual flag 0x%02x",
1514 *tptr++));
1515 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
1516 while (tmp >= sizeof(struct isis_tlv_is_reach)) {
1517 if (!TTEST(*tlv_is_reach))
1518 goto trunctlv;
1519 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach->neighbor_nodeid));
1520 isis_print_metric_block(&tlv_is_reach->isis_metric_block);
1521 tmp -= sizeof(struct isis_tlv_is_reach);
1522 tlv_is_reach++;
1523 }
1524 break;
1525
1526 case TLV_ESNEIGH:
1527 tlv_es_reach = (const struct isis_tlv_es_reach *)tptr;
1528 while (tmp >= sizeof(struct isis_tlv_es_reach)) {
1529 if (!TTEST(*tlv_es_reach))
1530 goto trunctlv;
1531 printf("\n\t\tES Neighbor: %s",
1532 isis_print_sysid(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN));
1533 isis_print_metric_block(&tlv_es_reach->isis_metric_block);
1534 tmp -= sizeof(struct isis_tlv_es_reach);
1535 tlv_es_reach++;
1536 }
1537 break;
1538
1539 /* those two TLVs share the same format */
1540 case TLV_IP_REACH:
1541 case TLV_IP_REACH_EXT:
1542 if (!isis_print_tlv_ip_reach(pptr, len))
1543 return (1);
1544 break;
1545
1546 case TLV_MT_IP_REACH:
1547 while (tmp>0) {
1548 if (!TTEST2(*tptr, 2))
1549 goto trunctlv;
1550
1551 printf("\n\t\t%s",
1552 tok2str(isis_mt_values,
1553 "Reserved for IETF Consensus",
1554 ISIS_MASK_MTID(EXTRACT_16BITS(tptr))));
1555
1556 printf(" Topology (0x%03x)",
1557 ISIS_MASK_MTID(EXTRACT_16BITS(tptr)));
1558 tptr+=2;
1559
1560 memset (prefix, 0, 4);
1561 if (!TTEST2(*tptr, 4))
1562 return (1);
1563 metric = EXTRACT_32BITS(tptr);
1564 tptr+=4;
1565
1566 if (!TTEST2(*tptr, 1)) /* fetch status byte */
1567 return (1);
1568 j=*(tptr);
1569 bit_length = (*(tptr)++&0x3f);
1570 byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
1571
1572 if (!TTEST2(*tptr, byte_length))
1573 return (1);
1574 memcpy(prefix,tptr,byte_length);
1575 tptr+=byte_length;
1576 printf("\n\t\tIPv4 prefix: %s/%d",
1577 ipaddr_string(prefix),
1578 bit_length);
1579
1580 printf("\n\t\t Metric: %u, Distribution: %s",
1581 metric,
1582 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up");
1583
1584 printf(", %ssub-TLVs present",
1585 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
1586
1587 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
1588 /* assume that one prefix can hold more
1589 than one subTLV - therefore the first byte must reflect
1590 the aggregate bytecount of the subTLVs for this prefix
1591 */
1592 if (!TTEST2(*tptr, 1))
1593 return (1);
1594 tslen=*(tptr++);
1595 tmp--;
1596 printf(" (%u)",tslen); /* print out subTLV length */
1597
1598 while (tslen>0) {
1599 if (!TTEST2(*tptr,2))
1600 goto trunctlv;
1601 subt=*(tptr++);
1602 subl=*(tptr++);
1603 if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t "))
1604 return(0);
1605 tptr+=subl;
1606 tslen-=(subl+2);
1607 tmp-=(subl+2);
1608 }
1609 }
1610 tmp-=(7+byte_length);
1611 }
1612 break;
1613
1614 case TLV_EXT_IP_REACH:
1615 while (tmp>0) {
1616 memset (prefix, 0, 4);
1617 if (!TTEST2(*tptr, 4))
1618 return (1);
1619 metric = EXTRACT_32BITS(tptr);
1620 tptr+=4;
1621
1622 if (!TTEST2(*tptr, 1)) /* fetch status byte */
1623 return (1);
1624 j=*(tptr);
1625 bit_length = (*(tptr)++&0x3f);
1626 byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
1627
1628 if (!TTEST2(*tptr, byte_length))
1629 return (1);
1630 memcpy(prefix,tptr,byte_length);
1631 tptr+=byte_length;
1632 printf("\n\t\tIPv4 prefix: %s/%d",
1633 ipaddr_string(prefix),
1634 bit_length);
1635
1636 printf("\n\t\t Metric: %u, Distribution: %s",
1637 metric,
1638 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up");
1639
1640 printf(", %ssub-TLVs present",
1641 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no ");
1642
1643 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) {
1644 /* assume that one prefix can hold more
1645 than one subTLV - therefore the first byte must reflect
1646 the aggregate bytecount of the subTLVs for this prefix
1647 */
1648 if (!TTEST2(*tptr, 1))
1649 return (1);
1650 tslen=*(tptr++);
1651 tmp--;
1652 printf(" (%u)",tslen); /* print out subTLV length */
1653
1654 while (tslen>0) {
1655 if (!TTEST2(*tptr,2))
1656 goto trunctlv;
1657 subt=*(tptr++);
1658 subl=*(tptr++);
1659 if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t "))
1660 return(0);
1661 tptr+=subl;
1662 tslen-=(subl+2);
1663 tmp-=(subl+2);
1664 }
1665 }
1666 tmp-=(5+byte_length);
1667 }
1668 break;
1669
1670 #ifdef INET6
1671
1672 case TLV_IP6_REACH:
1673 while (tmp>0) {
1674 if (!TTEST2(*tptr, 4))
1675 return (1);
1676 metric = EXTRACT_32BITS(tptr);
1677 tptr+=4;
1678
1679 if (!TTEST2(*tptr, 2))
1680 return (1);
1681 j=*(tptr++);
1682 bit_length = (*(tptr)++);
1683 byte_length = (bit_length + 7) / 8;
1684 if (!TTEST2(*tptr, byte_length))
1685 return (1);
1686
1687 memset(prefix6, 0, 16);
1688 memcpy(prefix6,tptr,byte_length);
1689 tptr+=byte_length;
1690 printf("\n\t\tIPv6 prefix: %s/%u",
1691 ip6addr_string(prefix6),
1692 bit_length);
1693
1694 printf("\n\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present",
1695 metric,
1696 ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal",
1697 ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up",
1698 ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no ");
1699
1700 if (ISIS_MASK_TLV_IP6_SUBTLV(j)) {
1701 /* assume that one prefix can hold more
1702 than one subTLV - therefore the first byte must reflect
1703 the aggregate bytecount of the subTLVs for this prefix
1704 */
1705 if (!TTEST2(*tptr, 1))
1706 return (1);
1707 tslen=*(tptr++);
1708 tmp--;
1709 printf(" (%u)",tslen); /* print out subTLV length */
1710
1711 while (tslen>0) {
1712 if (!TTEST2(*tptr,2))
1713 goto trunctlv;
1714 subt=*(tptr++);
1715 subl=*(tptr++);
1716 if(!isis_print_ip_reach_subtlv(tptr,subt,subl,"\n\t\t "))
1717 return(0);
1718 tptr+=subl;
1719 tslen-=(subl+2);
1720 tmp-=(subl+2);
1721 }
1722 }
1723 tmp-=(6+byte_length);
1724 }
1725
1726 break;
1727 #endif
1728
1729 #ifdef INET6
1730 case TLV_IP6ADDR:
1731 while (tmp>0) {
1732 if (!TTEST2(*tptr, 16))
1733 goto trunctlv;
1734
1735 printf("\n\t\tIPv6 interface address: %s",
1736 ip6addr_string(tptr));
1737
1738 tptr += 16;
1739 tmp -= 16;
1740 }
1741 break;
1742 #endif
1743 case TLV_AUTH:
1744 if (!TTEST2(*tptr, 1))
1745 goto trunctlv;
1746
1747 printf("\n\t\t%s: ",
1748 tok2str(isis_subtlv_auth_values,
1749 "unknown Authentication type 0x%02x",
1750 *tptr));
1751
1752 switch (*tptr) {
1753 case SUBTLV_AUTH_SIMPLE:
1754 for(i=1;i<len;i++) {
1755 if (!TTEST2(*(tptr+i), 1))
1756 goto trunctlv;
1757 printf("%c",*(tptr+i));
1758 }
1759 break;
1760 case SUBTLV_AUTH_MD5:
1761 for(i=1;i<len;i++) {
1762 if (!TTEST2(*(tptr+i), 1))
1763 goto trunctlv;
1764 printf("%02x",*(tptr+i));
1765 }
1766 if (len != SUBTLV_AUTH_MD5_LEN+1)
1767 printf(", (malformed subTLV) ");
1768 break;
1769 case SUBTLV_AUTH_PRIVATE:
1770 default:
1771 if(!print_unknown_data(tptr+1,"\n\t\t ",len-1))
1772 return(0);
1773 break;
1774 }
1775 break;
1776
1777 case TLV_PTP_ADJ:
1778 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
1779 if(tmp>=1) {
1780 if (!TTEST2(*tptr, 1))
1781 goto trunctlv;
1782 printf("\n\t\tAdjacency State: %s",
1783 tok2str(isis_ptp_adjancey_values, "0x%02x", *tptr));
1784 tmp--;
1785 }
1786 if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
1787 if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id,
1788 sizeof(tlv_ptp_adj->extd_local_circuit_id)))
1789 goto trunctlv;
1790 printf("\n\t\tExtended Local circuit ID: 0x%08x",
1791 EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id));
1792 tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
1793 }
1794 if(tmp>=SYSTEM_ID_LEN) {
1795 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN))
1796 goto trunctlv;
1797 printf("\n\t\tNeighbor SystemID: %s",
1798 isis_print_sysid(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN));
1799 tmp-=SYSTEM_ID_LEN;
1800 }
1801 if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
1802 if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id,
1803 sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)))
1804 goto trunctlv;
1805 printf("\n\t\tNeighbor Extended Local circuit ID: 0x%08x",
1806 EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id));
1807 }
1808 break;
1809
1810 case TLV_PROTOCOLS:
1811 printf("\n\t\tNLPID(s): ");
1812 while (tmp>0) {
1813 if (!TTEST2(*(tptr), 1))
1814 goto trunctlv;
1815 printf("%s",
1816 tok2str(isis_nlpid_values,
1817 "Unknown 0x%02x",
1818 *tptr++));
1819 if (tmp>1) /* further NPLIDs ? - put comma */
1820 printf(", ");
1821 tmp--;
1822 }
1823 break;
1824
1825 case TLV_TE_ROUTER_ID:
1826 if (!TTEST2(*pptr, 4))
1827 goto trunctlv;
1828 printf("\n\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr));
1829 break;
1830
1831 case TLV_IPADDR:
1832 while (tmp>0) {
1833 if (!TTEST2(*tptr, 4))
1834 goto trunctlv;
1835 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1836 tptr += 4;
1837 tmp -= 4;
1838 }
1839 break;
1840
1841 case TLV_HOSTNAME:
1842 printf("\n\t\tHostname: ");
1843 while (tmp>0) {
1844 if (!TTEST2(*tptr, 1))
1845 goto trunctlv;
1846 printf("%c",*tptr++);
1847 tmp--;
1848 }
1849 break;
1850
1851 case TLV_SHARED_RISK_GROUP:
1852 if (!TTEST2(*tptr, NODE_ID_LEN))
1853 goto trunctlv;
1854 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr));
1855 tptr+=(NODE_ID_LEN);
1856 len-=(NODE_ID_LEN);
1857
1858 if (!TTEST2(*tptr, 1))
1859 goto trunctlv;
1860 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered");
1861 len--;
1862
1863 if (!TTEST2(*tptr,4))
1864 goto trunctlv;
1865 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1866 tptr+=4;
1867 len-=4;
1868
1869 if (!TTEST2(*tptr,4))
1870 goto trunctlv;
1871 printf("\n\t\tIPv4 neighbor address: %s", ipaddr_string(tptr));
1872 tptr+=4;
1873 len-=4;
1874
1875 while (tmp>0) {
1876 if (!TTEST2(*tptr, 4))
1877 goto trunctlv;
1878 printf("\n\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr));
1879 tptr+=4;
1880 len-=4;
1881 }
1882 break;
1883
1884 case TLV_LSP:
1885 tlv_lsp = (const struct isis_tlv_lsp *)tptr;
1886 while(tmp>0) {
1887 printf("\n\t\tlsp-id: %s",
1888 isis_print_nodeid(tlv_lsp->lsp_id));
1889 if (!TTEST((tlv_lsp->lsp_id)[NODE_ID_LEN]))
1890 goto trunctlv;
1891 printf("-%02x",(tlv_lsp->lsp_id)[NODE_ID_LEN]);
1892 if (!TTEST2(tlv_lsp->sequence_number, 4))
1893 goto trunctlv;
1894 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number));
1895 if (!TTEST2(tlv_lsp->remaining_lifetime, 2))
1896 goto trunctlv;
1897 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime));
1898 if (!TTEST2(tlv_lsp->checksum, 2))
1899 goto trunctlv;
1900 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum));
1901 tmp-=sizeof(struct isis_tlv_lsp);
1902 tlv_lsp++;
1903 }
1904 break;
1905
1906 case TLV_CHECKSUM:
1907 if (!TTEST2(*tptr, 2))
1908 goto trunctlv;
1909 printf("\n\t\tchecksum: 0x%04x (%s)",
1910 EXTRACT_16BITS(tptr),
1911 (osi_cksum(optr, length)) ? "incorrect" : "correct");
1912 break;
1913
1914 case TLV_MT_SUPPORTED:
1915 while (tmp>1) {
1916 /* length can only be a multiple of 2, otherwise there is
1917 something broken -> so decode down until length is 1 */
1918 if (tmp!=1) {
1919 if (!TTEST2(*tptr, 2))
1920 goto trunctlv;
1921 printf("\n\t\t%s",
1922 tok2str(isis_mt_values,
1923 "Reserved for IETF Consensus",
1924 ISIS_MASK_MTID(EXTRACT_16BITS(tptr))));
1925
1926 printf(" Topology (0x%03x)%s%s",
1927 ISIS_MASK_MTID(EXTRACT_16BITS(tptr)),
1928 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr)) ? "" : ", no sub-TLVs present",
1929 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr)) ? ", ATT bit set" : "" );
1930 } else {
1931 printf("\n\t\tmalformed MT-ID");
1932 break;
1933 }
1934 tmp-=2;
1935 tptr+=2;
1936 }
1937 break;
1938
1939 case TLV_RESTART_SIGNALING:
1940 if (!TTEST2(*tptr, 3))
1941 goto trunctlv;
1942 rr = ISIS_MASK_TLV_RESTART_RR(*tptr);
1943 ra = ISIS_MASK_TLV_RESTART_RA(*tptr);
1944 tptr++;
1945 time_remain = EXTRACT_16BITS(tptr);
1946 printf("\n\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\tRemaining holding time: %us",
1947 rr ? "set" : "clear", ra ? "set" : "clear", time_remain);
1948 break;
1949
1950 case TLV_IDRP_INFO:
1951 if (!TTEST2(*tptr, 1))
1952 goto trunctlv;
1953 printf("\n\t\tInter-Domain Information Type: %s",
1954 tok2str(isis_subtlv_idrp_values,
1955 "Unknown (0x%02x)",
1956 *tptr));
1957 switch (*tptr++) {
1958 case SUBTLV_IDRP_ASN:
1959 if (!TTEST2(*tptr, 2)) /* fetch AS number */
1960 goto trunctlv;
1961 printf("AS Number: %u",EXTRACT_16BITS(tptr));
1962 break;
1963 case SUBTLV_IDRP_LOCAL:
1964 case SUBTLV_IDRP_RES:
1965 default:
1966 if(!print_unknown_data(tptr,"\n\t\t",len-1))
1967 return(0);
1968 break;
1969 }
1970 break;
1971
1972 case TLV_LSP_BUFFERSIZE:
1973 if (!TTEST2(*tptr, 2))
1974 goto trunctlv;
1975 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr));
1976 break;
1977
1978 case TLV_PART_DIS:
1979 while (tmp >= SYSTEM_ID_LEN) {
1980 if (!TTEST2(*tptr, SYSTEM_ID_LEN))
1981 goto trunctlv;
1982 printf("%s",isis_print_sysid(tptr,SYSTEM_ID_LEN));
1983 tptr+=SYSTEM_ID_LEN;
1984 tmp-=SYSTEM_ID_LEN;
1985 }
1986 break;
1987
1988 case TLV_PREFIX_NEIGH:
1989 if (!TTEST2(*tptr, sizeof(struct isis_metric_block)))
1990 goto trunctlv;
1991 printf("Metric Block");
1992 isis_print_metric_block((const struct isis_metric_block *)tptr);
1993 tptr+=sizeof(struct isis_metric_block);
1994 tmp-=sizeof(struct isis_metric_block);
1995
1996 while(tmp>0) {
1997 if (!TTEST2(*tptr, 1))
1998 goto trunctlv;
1999 prefix_len=*tptr++; /* read out prefix length in semioctets*/
2000 tmp--;
2001 if (!TTEST2(*tptr, prefix_len/2))
2002 goto trunctlv;
2003 printf("\n\t\tAddress: %s/%u",
2004 print_nsap(tptr,prefix_len/2),
2005 prefix_len*4);
2006 tptr+=prefix_len/2;
2007 tmp-=prefix_len/2;
2008 }
2009 break;
2010
2011 /*
2012 * FIXME those are the defined TLVs that lack a decoder
2013 * you are welcome to contribute code ;-)
2014 */
2015
2016 case TLV_IS_ALIAS_ID:
2017 case TLV_DECNET_PHASE4:
2018 case TLV_LUCENT_PRIVATE:
2019 case TLV_IPAUTH:
2020 case TLV_NORTEL_PRIVATE1:
2021 case TLV_NORTEL_PRIVATE2:
2022 case TLV_MT_IP6_REACH:
2023
2024 default:
2025 if(!print_unknown_data(pptr,"\n\t\t",len))
2026 return(0);
2027 break;
2028 }
2029
2030 pptr += len;
2031 packet_len -= len;
2032 }
2033
2034 if (packet_len != 0) {
2035 printf("\n\t\t %d straggler bytes", packet_len);
2036 }
2037 return (1);
2038
2039 trunc:
2040 fputs("[|isis]", stdout);
2041 return (1);
2042
2043 trunctlv:
2044 printf("\n\t\t packet exceeded snapshot");
2045 return(1);
2046 }
2047
2048 /*
2049 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2050 */
2051
2052 static int
2053 osi_cksum(const u_char *tptr, u_int len)
2054 {
2055 int32_t c0 = 0, c1 = 0;
2056
2057 while ((int)--len >= 0) {
2058 c0 += *tptr++;
2059 c0 %= 255;
2060 c1 += c0;
2061 c1 %= 255;
2062 }
2063 return (c0 | c1);
2064 }