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