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 * $FreeBSD$ 27 */ 28 29 #ifndef lint 30 static const char rcsid[] = 31 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.36 2002/01/10 09:33:23 guy Exp $ (LBL)"; 32 #endif 33 34 #ifdef HAVE_CONFIG_H 35 #include "config.h" 36 #endif 37 38 #include <sys/types.h> 39 #include <sys/time.h> 40 #include <sys/socket.h> 41 42 #include <netinet/in.h> 43 44 #include <stdio.h> 45 #include <string.h> 46 47 #include "interface.h" 48 #include "addrtoname.h" 49 #include "ethertype.h" 50 #include "ether.h" 51 #include "extract.h" 52 53 #define NLPID_CLNS 129 /* 0x81 */ 54 #define NLPID_ESIS 130 /* 0x82 */ 55 #define NLPID_ISIS 131 /* 0x83 */ 56 #define NLPID_IP6 0x8e 57 #define NLPID_IP 0xcc 58 #define NLPID_NULLNS 0 59 60 /* 61 * IS-IS is defined in ISO 10589. Look there for protocol definitions. 62 */ 63 64 #define SYSTEM_ID_LEN ETHER_ADDR_LEN 65 #define ISIS_VERSION 1 66 #define PDU_TYPE_MASK 0x1F 67 #define PRIORITY_MASK 0x7F 68 69 #define L1_LAN_IIH 15 70 #define L2_LAN_IIH 16 71 #define PTP_IIH 17 72 #define L1_LSP 18 73 #define L2_LSP 20 74 #define L1_CSNP 24 75 #define L2_CSNP 25 76 #define L1_PSNP 26 77 #define L2_PSNP 27 78 79 80 /* 81 * A TLV is a tuple of a type, length and a value and is normally used for 82 * encoding information in all sorts of places. This is an enumeration of 83 * the well known types. 84 */ 85 86 #define TLV_AREA_ADDR 1 87 #define TLV_IS_REACH 2 88 #define TLV_ES_REACH 3 89 #define TLV_SUMMARY 5 90 #define TLV_ISNEIGH 6 91 #define TLV_PADDING 8 92 #define TLV_LSP 9 93 #define TLV_AUTH 10 94 #define TLV_CHECKSUM 12 95 #define TLV_EXT_IS_REACH 22 96 #define TLV_IP_REACH 128 97 #define TLV_PROTOCOLS 129 98 #define TLV_IP_REACH_EXT 130 99 #define TLV_IDRP_INFO 131 100 #define TLV_IPADDR 132 101 #define TLV_IPAUTH 133 102 #define TLV_TE_ROUTER_ID 134 103 #define TLV_EXT_IP_REACH 135 104 #define TLV_HOSTNAME 137 105 #define TLV_RESTART_SIGNALING 211 106 #define TLV_MT_IS_REACH 222 107 #define TLV_MT_SUPPORTED 229 108 #define TLV_IP6ADDR 232 109 #define TLV_MT_REACH 235 110 #define TLV_IP6_REACH 236 111 #define TLV_PTP_ADJ 240 112 113 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 114 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 115 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 116 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 117 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 118 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 119 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18 120 121 #define SUBTLV_AUTH_SIMPLE 1 122 #define SUBTLV_AUTH_MD5 54 123 124 #define ISIS_MASK_LEVEL_BITS(x) ((x)&0x1) 125 126 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) 127 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) 128 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) 129 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) 130 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) 131 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) 132 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) 133 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) 134 135 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80) 136 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40) 137 138 #define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80) 139 #define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40) 140 #define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20) 141 142 #define ISIS_MASK_RESTART_RR(x) ((x)&0x1) 143 #define ISIS_MASK_RESTART_RA(x) ((x)&0x2) 144 145 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) 146 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) 147 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) 148 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) 149 150 #define ISIS_LSP_TYPE_UNUSED0 0 151 #define ISIS_LSP_TYPE_LEVEL_1 1 152 #define ISIS_LSP_TYPE_UNUSED2 2 153 #define ISIS_LSP_TYPE_LEVEL_2 3 154 155 static struct tok isis_lsp_istype_values[] = { 156 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, 157 { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, 158 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, 159 { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"}, 160 { 0, NULL } 161 }; 162 163 static struct tok isis_nlpid_values[] = { 164 { NLPID_CLNS, "CLNS"}, 165 { NLPID_IP, "IPv4"}, 166 { NLPID_IP6, "IPv6"}, 167 { 0, "unknown" } 168 }; 169 170 /* 171 * Katz's point to point adjacency TLV uses codes to tell us the state of 172 * the remote adjacency. Enumerate them. 173 */ 174 175 #define ISIS_PTP_ADJ_UP 0 176 #define ISIS_PTP_ADJ_INIT 1 177 #define ISIS_PTP_ADJ_DOWN 2 178 179 static int osi_cksum(const u_char *, u_int, u_char *); 180 static void esis_print(const u_char *, u_int); 181 static int isis_print(const u_char *, u_int); 182 183 184 static struct tok isis_ptp_adjancey_values[] = { 185 { ISIS_PTP_ADJ_UP, "Up" }, 186 { ISIS_PTP_ADJ_INIT, "Initializing" }, 187 { ISIS_PTP_ADJ_DOWN, "Down" } 188 }; 189 190 struct isis_tlv_ptp_adj { 191 u_char adjacency_state; 192 u_char ext_local_circuit_id[4]; 193 u_char neighbor_sysid[SYSTEM_ID_LEN]; 194 u_char neighbor_ext_local_circuit_id[4]; 195 }; 196 197 struct isis_tlv_ip_reach { 198 u_char metric_default; 199 u_char metric_delay; 200 u_char metric_expense; 201 u_char metric_error; 202 u_char prefix[4]; 203 u_char mask[4]; 204 }; 205 206 struct isis_tlv_is_reach { 207 u_char metric_default; 208 u_char metric_delay; 209 u_char metric_expense; 210 u_char metric_error; 211 u_char neighbor_nodeid[SYSTEM_ID_LEN+1]; 212 }; 213 214 215 struct isis_common_header { 216 u_char nlpid; 217 u_char fixed_len; 218 u_char version; /* Protocol version? */ 219 u_char id_length; 220 u_char pdu_type; /* 3 MSbs are reserved */ 221 u_char pkt_version; /* Packet format version? */ 222 u_char reserved; 223 u_char max_area; 224 }; 225 226 struct isis_iih_lan_header { 227 u_char circuit_type; 228 u_char source_id[SYSTEM_ID_LEN]; 229 u_char holding_time[2]; 230 u_char pdu_len[2]; 231 u_char priority; 232 u_char lan_id[SYSTEM_ID_LEN+1]; 233 }; 234 235 struct isis_iih_ptp_header { 236 u_char circuit_type; 237 u_char source_id[SYSTEM_ID_LEN]; 238 u_char holding_time[2]; 239 u_char pdu_len[2]; 240 u_char circuit_id; 241 }; 242 243 struct isis_lsp_header { 244 u_char pdu_len[2]; 245 u_char remaining_lifetime[2]; 246 u_char lsp_id[SYSTEM_ID_LEN+2]; 247 u_char sequence_number[4]; 248 u_char checksum[2]; 249 u_char typeblock; 250 }; 251 252 struct isis_csnp_header { 253 u_char pdu_len[2]; 254 u_char source_id[SYSTEM_ID_LEN+1]; 255 u_char start_lsp_id[SYSTEM_ID_LEN+2]; 256 u_char end_lsp_id[SYSTEM_ID_LEN+2]; 257 }; 258 259 struct isis_psnp_header { 260 u_char pdu_len[2]; 261 u_char source_id[SYSTEM_ID_LEN+1]; 262 }; 263 264 struct isis_tlv_lsp { 265 u_char remaining_lifetime[2]; 266 u_char lsp_id[SYSTEM_ID_LEN+2]; 267 u_char sequence_number[4]; 268 u_char checksum[2]; 269 }; 270 271 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) 272 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) 273 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) 274 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) 275 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) 276 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) 277 278 void isoclns_print(const u_char *p, u_int length, u_int caplen, 279 const u_char *esrc, const u_char *edst) 280 { 281 u_char pdu_type; 282 const struct isis_common_header *header; 283 284 header = (const struct isis_common_header *)p; 285 pdu_type = header->pdu_type & PDU_TYPE_MASK; 286 287 if (caplen < 1) { 288 printf("[|iso-clns] "); 289 if (!eflag && esrc != NULL && edst != NULL) 290 printf("%s > %s", 291 etheraddr_string(esrc), 292 etheraddr_string(edst)); 293 return; 294 } 295 296 switch (*p) { 297 298 case NLPID_CLNS: 299 (void)printf("CLNS(%d)", length); 300 if (!eflag && esrc != NULL && edst != NULL) 301 (void)printf(", %s > %s", 302 etheraddr_string(esrc), 303 etheraddr_string(edst)); 304 break; 305 306 case NLPID_ESIS: 307 (void)printf("ESIS"); 308 if (!eflag && esrc != NULL && edst != NULL) 309 (void)printf(", %s > %s", 310 etheraddr_string(esrc), 311 etheraddr_string(edst)); 312 esis_print(p, length); 313 return; 314 315 case NLPID_ISIS: 316 (void)printf("ISIS(%d)", length); 317 if (!eflag && esrc != NULL && edst != NULL) 318 (void)printf(", %s > %s", 319 etheraddr_string(esrc), 320 etheraddr_string(edst)); 321 if (!isis_print(p, length)) 322 default_print_unaligned(p, caplen); 323 break; 324 325 case NLPID_NULLNS: 326 (void)printf("ISO NULLNS(%d)", length); 327 if (!eflag && esrc != NULL && edst != NULL) 328 (void)printf(", %s > %s", 329 etheraddr_string(esrc), 330 etheraddr_string(edst)); 331 break; 332 333 default: 334 (void)printf("CLNS %02x(%d)", p[0], length); 335 if (!eflag && esrc != NULL && edst != NULL) 336 (void)printf(", %s > %s", 337 etheraddr_string(esrc), 338 etheraddr_string(edst)); 339 if (caplen > 1) 340 default_print_unaligned(p, caplen); 341 break; 342 } 343 } 344 345 #define ESIS_REDIRECT 6 346 #define ESIS_ESH 2 347 #define ESIS_ISH 4 348 349 struct esis_hdr { 350 u_char version; 351 u_char reserved; 352 u_char type; 353 u_char tmo[2]; 354 u_char cksum[2]; 355 }; 356 357 static void 358 esis_print(const u_char *p, u_int length) 359 { 360 const u_char *ep; 361 u_int li; 362 const struct esis_hdr *eh; 363 u_char off[2]; 364 365 if (length <= 2) { 366 if (qflag) 367 printf(" bad pkt!"); 368 else 369 printf(" no header at all!"); 370 return; 371 } 372 li = p[1]; 373 eh = (const struct esis_hdr *) &p[2]; 374 ep = p + li; 375 if (li > length) { 376 if (qflag) 377 printf(" bad pkt!"); 378 else 379 printf(" LI(%d) > PDU size (%d)!", li, length); 380 return; 381 } 382 if (li < sizeof(struct esis_hdr) + 2) { 383 if (qflag) 384 printf(" bad pkt!"); 385 else { 386 printf(" too short for esis header %d:", li); 387 while (--length != 0) 388 printf("%02X", *p++); 389 } 390 return; 391 } 392 switch (eh->type & 0x1f) { 393 394 case ESIS_REDIRECT: 395 printf(" redirect"); 396 break; 397 398 case ESIS_ESH: 399 printf(" esh"); 400 break; 401 402 case ESIS_ISH: 403 printf(" ish"); 404 break; 405 406 default: 407 printf(" type %d", eh->type & 0x1f); 408 break; 409 } 410 off[0] = eh->cksum[0]; 411 off[1] = eh->cksum[1]; 412 if (vflag && osi_cksum(p, li, off)) { 413 printf(" bad cksum (got %02x%02x)", 414 eh->cksum[1], eh->cksum[0]); 415 default_print(p, length); 416 return; 417 } 418 if (eh->version != 1) { 419 printf(" unsupported version %d", eh->version); 420 return; 421 } 422 p += sizeof(*eh) + 2; 423 li -= sizeof(*eh) + 2; /* protoid * li */ 424 425 switch (eh->type & 0x1f) { 426 case ESIS_REDIRECT: { 427 const u_char *dst, *snpa, *is; 428 429 dst = p; p += *p + 1; 430 if (p > snapend) 431 return; 432 printf("\n\t\t\t %s", isonsap_string(dst)); 433 snpa = p; p += *p + 1; 434 is = p; p += *p + 1; 435 if (p > snapend) 436 return; 437 if (p > ep) { 438 printf(" [bad li]"); 439 return; 440 } 441 if (is[0] == 0) 442 printf(" > %s", etheraddr_string(&snpa[1])); 443 else 444 printf(" > %s", isonsap_string(is)); 445 li = ep - p; 446 break; 447 } 448 #if 0 449 case ESIS_ESH: 450 printf(" esh"); 451 break; 452 #endif 453 case ESIS_ISH: { 454 const u_char *is; 455 456 is = p; p += *p + 1; 457 if (p > ep) { 458 printf(" [bad li]"); 459 return; 460 } 461 if (p > snapend) 462 return; 463 if (!qflag) 464 printf("\n\t\t\t %s", isonsap_string(is)); 465 li = ep - p; 466 break; 467 } 468 469 default: 470 (void)printf(" len=%d", length); 471 if (length && p < snapend) { 472 length = snapend - p; 473 default_print(p, length); 474 } 475 return; 476 } 477 if (vflag) 478 while (p < ep && li) { 479 u_int op, opli; 480 const u_char *q; 481 482 if (snapend - p < 2) 483 return; 484 if (li < 2) { 485 printf(" bad opts/li"); 486 return; 487 } 488 op = *p++; 489 opli = *p++; 490 li -= 2; 491 if (opli > li) { 492 printf(" opt (%d) too long", op); 493 return; 494 } 495 li -= opli; 496 q = p; 497 p += opli; 498 if (snapend < p) 499 return; 500 if (op == 198 && opli == 2) { 501 printf(" tmo=%d", q[0] * 256 + q[1]); 502 continue; 503 } 504 printf (" %d:<", op); 505 while (opli-- > 0) 506 printf("%02x", *q++); 507 printf (">"); 508 } 509 } 510 511 /* 512 * print_nsap 513 * Print out an NSAP. 514 */ 515 static int 516 print_nsap(register const u_char *cp, register int length) 517 { 518 int i; 519 520 for (i = 0; i < length; i++) { 521 if (!TTEST2(*cp, 1)) 522 return (0); 523 printf("%02x", *cp++); 524 if (((i & 1) == 0) && (i + 1 < length)) { 525 printf("."); 526 } 527 } 528 return (1); 529 } 530 531 static int 532 isis_print_sysid(const u_char *cp) 533 { 534 int i; 535 536 for (i = 1; i <= 6; i++) { 537 if (!TTEST2(*cp, 1)) 538 return (0); 539 printf("%02x", *cp++); 540 if ((i==2)^(i==4)) { 541 printf("."); 542 } 543 } 544 return (1); 545 } 546 547 static int 548 isis_print_nodeid(const u_char *cp) 549 { 550 int i; 551 552 for (i = 1; i <= 7; i++) { 553 if (!TTEST2(*cp, 1)) 554 return (0); 555 printf("%02x", *cp++); 556 if ((i & 1) == 0) { 557 printf("."); 558 } 559 } 560 return (1); 561 } 562 563 static void 564 isis_print_lspid(const u_char *cp) 565 { 566 int i; 567 568 for (i = 1; i <= 7; i++) { 569 printf("%02x", *cp++); 570 if ((i & 1) == 0) 571 printf("."); 572 } 573 printf("-%02x", *cp); 574 } 575 576 static int 577 isis_print_tlv_ip_reach (const u_char *cp, int length) 578 { 579 int bitmasks[33] = { 580 0x00000000, 581 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 582 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 583 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 584 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 585 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 586 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 587 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 588 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff 589 }; 590 int mask, prefix_len; 591 const struct isis_tlv_ip_reach *tlv_ip_reach; 592 593 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; 594 595 while (length > 0) { 596 if (length < sizeof(*tlv_ip_reach)) { 597 printf("short IP reachability (%d vs %lu)", length, 598 (unsigned long)sizeof(*tlv_ip_reach)); 599 return (0); 600 } 601 602 if (!TTEST(*tlv_ip_reach)) 603 return (0); 604 605 mask = EXTRACT_32BITS(tlv_ip_reach->mask); 606 prefix_len = 0; 607 608 while (prefix_len <= 33) { 609 if (bitmasks[prefix_len++] == mask) { 610 prefix_len--; 611 break; 612 } 613 } 614 615 /* 616 * 34 indicates no match -> must be a discontiguous netmask 617 * lets dump the mask, otherwise print the prefix_len 618 */ 619 if (prefix_len == 34) 620 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u", 621 (tlv_ip_reach->prefix)[0], 622 (tlv_ip_reach->prefix)[1], 623 (tlv_ip_reach->prefix)[2], 624 (tlv_ip_reach->prefix)[3], 625 (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1], 626 (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]); 627 else 628 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u", 629 (tlv_ip_reach->prefix)[0], 630 (tlv_ip_reach->prefix)[1], 631 (tlv_ip_reach->prefix)[2], 632 (tlv_ip_reach->prefix)[3], prefix_len); 633 634 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s", 635 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default), 636 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_default) ? "External" : "Internal", 637 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->metric_default) ? "down" : "up"); 638 639 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_delay)) 640 printf("\n\t\t\t Delay Metric: %02d, %s", 641 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_delay), 642 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_delay) ? "External" : "Internal"); 643 644 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_expense)) 645 printf("\n\t\t\t Expense Metric: %02d, %s", 646 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_expense), 647 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_expense) ? "External" : "Internal"); 648 649 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_error)) 650 printf("\n\t\t\t Error Metric: %02d, %s", 651 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_error), 652 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_error) ? "External" : "Internal"); 653 654 length -= sizeof(struct isis_tlv_ip_reach); 655 tlv_ip_reach++; 656 } 657 return (1); 658 } 659 660 /* 661 * isis_print 662 * Decode IS-IS packets. Return 0 on error. 663 */ 664 665 static int isis_print (const u_char *p, u_int length) 666 { 667 const struct isis_common_header *header; 668 669 const struct isis_iih_lan_header *header_iih_lan; 670 const struct isis_iih_ptp_header *header_iih_ptp; 671 const struct isis_lsp_header *header_lsp; 672 const struct isis_csnp_header *header_csnp; 673 const struct isis_psnp_header *header_psnp; 674 675 const struct isis_tlv_lsp *tlv_lsp; 676 const struct isis_tlv_ptp_adj *tlv_ptp_adj; 677 const struct isis_tlv_is_reach *tlv_is_reach; 678 679 u_char pdu_type, max_area, type, len, tmp, alen, subl, subt, tslen, ttslen; 680 const u_char *optr, *pptr, *tptr; 681 u_short packet_len,pdu_len; 682 u_int i,j,bit_length,byte_length,metric; 683 u_char prefix[4]; /* copy buffer for ipv4 prefixes */ 684 #ifdef INET6 685 u_char prefix6[16]; /* copy buffer for ipv6 prefixes */ 686 #endif 687 u_char off[2]; 688 float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV */ 689 690 packet_len=length; 691 optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */ 692 header = (const struct isis_common_header *)p; 693 TCHECK(*header); 694 pptr = p+(ISIS_COMMON_HEADER_SIZE); 695 header_iih_lan = (const struct isis_iih_lan_header *)pptr; 696 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; 697 header_lsp = (const struct isis_lsp_header *)pptr; 698 header_csnp = (const struct isis_csnp_header *)pptr; 699 header_psnp = (const struct isis_psnp_header *)pptr; 700 701 /* 702 * Sanity checking of the header. 703 */ 704 if (header->nlpid != NLPID_ISIS) { 705 printf(", coding error!"); 706 return (0); 707 } 708 709 if (header->version != ISIS_VERSION) { 710 printf(", version %d packet not supported", header->version); 711 return (0); 712 } 713 714 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) { 715 printf(", system ID length of %d is not supported", 716 header->id_length); 717 return (0); 718 } 719 720 if (header->pkt_version != ISIS_VERSION) { 721 printf(", version %d packet not supported", header->pkt_version); 722 return (0); 723 } 724 725 max_area = header->max_area; 726 switch(max_area) { 727 case 0: 728 max_area = 3; /* silly shit */ 729 break; 730 case 255: 731 printf(", bad packet -- 255 areas"); 732 return (0); 733 default: 734 break; 735 } 736 737 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)", 738 header->fixed_len, 739 header->pkt_version, 740 max_area, 741 header->max_area); 742 743 pdu_type=header->pdu_type; 744 745 switch (pdu_type) { 746 747 case L1_LAN_IIH: 748 case L2_LAN_IIH: 749 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { 750 printf(", bogus fixed header length %u should be %lu", 751 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); 752 return (0); 753 } 754 755 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); 756 if (packet_len>pdu_len) { 757 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 758 length=pdu_len; 759 } 760 761 printf(", L%s Lan IIH (%u)", 762 ISIS_MASK_LEVEL_BITS(pdu_type) ? "1" : "2", 763 pdu_len); 764 765 TCHECK(*header_iih_lan); 766 printf("\n\t\t source-id: "); 767 isis_print_sysid(header_iih_lan->source_id); 768 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan->holding_time)); 769 switch(header_iih_lan->circuit_type) { 770 771 case 1: 772 printf(", Level 1 only"); 773 break; 774 775 case 2: 776 printf(", Level 2 only"); 777 break; 778 779 case 3: 780 printf(", Level 1, Level 2"); 781 break; 782 783 default: 784 printf(", unknown 0x%02x", header_iih_lan->circuit_type); 785 break; 786 } 787 printf("\n\t\t lan-id: "); 788 isis_print_nodeid(header_iih_lan->lan_id); 789 printf(", Priority: %u",(header_iih_lan->priority) & PRIORITY_MASK); 790 791 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 792 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 793 break; 794 795 case PTP_IIH: 796 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { 797 printf(", bogus fixed header length %u should be %lu", 798 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); 799 return (0); 800 } 801 802 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); 803 if (packet_len>pdu_len) { 804 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 805 length=pdu_len; 806 } 807 808 printf(", PTP IIH (%u)",pdu_len); 809 TCHECK(*header_iih_ptp); 810 printf("\n\t\t source-id: "); 811 isis_print_sysid(header_iih_ptp->source_id); 812 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp->holding_time)); 813 printf(", circuit-id: 0x%02x", header_iih_ptp->circuit_id); 814 switch(header_iih_ptp->circuit_type) { 815 816 case 1: 817 printf(", Level 1 only"); 818 break; 819 820 case 2: 821 printf(", Level 2 only"); 822 break; 823 824 case 3: 825 printf(", Level 1, Level 2"); 826 break; 827 828 default: 829 printf(", unknown 0x%02x", header_iih_ptp->circuit_type); 830 break; 831 } 832 833 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 834 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 835 break; 836 837 case L1_LSP: 838 case L2_LSP: 839 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { 840 printf(", bogus fixed header length %u should be %lu", 841 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); 842 return (0); 843 } 844 845 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); 846 if (packet_len>pdu_len) { 847 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 848 length=pdu_len; 849 } 850 851 if (pdu_type == L1_LSP) 852 printf(", L1 LSP (%u)",pdu_len); 853 else if (pdu_type == L2_LSP) 854 printf(", L2 LSP (%u)",pdu_len); 855 856 TCHECK(*header_lsp); 857 printf("\n\t\t lsp-id: "); 858 isis_print_lspid(header_lsp->lsp_id); 859 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number)); 860 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime)); 861 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum)); 862 863 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); 864 865 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { 866 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); 867 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); 868 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); 869 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); 870 printf("ATT bit set, "); 871 } 872 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); 873 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); 874 875 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 876 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 877 break; 878 879 case L1_CSNP: 880 case L2_CSNP: 881 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { 882 printf(", bogus fixed header length %u should be %lu", 883 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); 884 return (0); 885 } 886 887 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); 888 if (packet_len>pdu_len) { 889 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 890 length=pdu_len; 891 } 892 893 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); 894 TCHECK(*header_csnp); 895 printf("\n\t\t source-id: "); 896 isis_print_nodeid(header_csnp->source_id); 897 printf("\n\t\t start lsp-id: "); 898 isis_print_lspid(header_csnp->start_lsp_id); 899 printf("\n\t\t end lsp-id: "); 900 isis_print_lspid(header_csnp->end_lsp_id); 901 902 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 903 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 904 break; 905 906 case L1_PSNP: 907 case L2_PSNP: 908 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { 909 printf("- bogus fixed header length %u should be %lu", 910 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); 911 return (0); 912 } 913 914 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); 915 if (packet_len>pdu_len) { 916 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 917 length=pdu_len; 918 } 919 920 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); 921 TCHECK(*header_psnp); 922 printf("\n\t\t source-id: "); 923 isis_print_nodeid(header_psnp->source_id); 924 925 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 926 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 927 break; 928 929 default: 930 printf(", PDU type (0x%02x) not supported", pdu_type); 931 return (1); 932 } 933 934 /* 935 * Now print the TLV's. 936 */ 937 938 while (packet_len >= 2) { 939 if (pptr == snapend) { 940 return (1); 941 } 942 943 if (!TTEST2(*pptr, 2)) { 944 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes", 945 (long)(pptr-snapend)); 946 return (1); 947 } 948 type = *pptr++; 949 len = *pptr++; 950 packet_len -= 2; 951 if (len > packet_len) { 952 break; 953 } 954 printf("\n\t\t "); 955 956 switch (type) { 957 case TLV_AREA_ADDR: 958 printf("Area address(es) (%u)",len); 959 tmp = len; 960 tptr = pptr; 961 if (!TTEST2(*tptr, 1)) 962 goto trunctlv; 963 alen = *tptr++; 964 while (tmp && alen < tmp) { 965 printf("\n\t\t\tArea address (%u): ",alen); 966 if (!print_nsap(tptr, alen)) 967 return (1); 968 tptr += alen; 969 tmp -= alen + 1; 970 if (tmp==0) /* if this is the last area address do not attemt a boundary check */ 971 break; 972 if (!TTEST2(*tptr, 1)) 973 goto trunctlv; 974 alen = *tptr++; 975 } 976 break; 977 case TLV_ISNEIGH: 978 printf("IS Neighbor(s) (%u)",len); 979 tmp = len; 980 tptr = pptr; 981 while (tmp >= ETHER_ADDR_LEN) { 982 printf("\n\t\t\tIS Neighbor: "); 983 if (!isis_print_sysid(tptr)) 984 return (1); 985 tmp -= ETHER_ADDR_LEN; 986 tptr += ETHER_ADDR_LEN; 987 } 988 break; 989 990 case TLV_PADDING: 991 printf("Padding (%u)", len); 992 break; 993 994 case TLV_MT_IS_REACH: 995 printf("Multi Topology IS Reachability (%u)",len); 996 tptr=pptr; 997 tmp=len; 998 while (tmp>0) { 999 printf("\n\t\t\t"); 1000 if (!TTEST2(*tptr, 2)) 1001 goto trunctlv; 1002 switch(EXTRACT_16BITS(tptr)&0x0fff) { 1003 1004 case 0: 1005 printf("IPv4 unicast"); 1006 break; 1007 1008 case 1: 1009 printf("In-Band Management"); 1010 break; 1011 1012 case 2: 1013 printf("IPv6 unicast"); 1014 break; 1015 1016 case 3: 1017 printf("Multicast"); 1018 break; 1019 1020 case 4095: 1021 printf("Development, Experimental or Proprietary"); 1022 break; 1023 1024 default: 1025 printf("Reserved for IETF Consensus"); 1026 break; 1027 } 1028 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff); 1029 tptr+=2; 1030 printf("\n\t\t\t IS Neighbor: "); 1031 if (!isis_print_nodeid(tptr)) 1032 return (1); 1033 tptr+=(SYSTEM_ID_LEN+1); 1034 if (!TTEST2(*tptr, 3)) 1035 goto trunctlv; 1036 printf(", Metric: %d",EXTRACT_24BITS(tptr)); 1037 tptr+=3; 1038 if (!TTEST2(*tptr, 1)) 1039 goto trunctlv; 1040 tslen=*(tptr++); 1041 printf(", %ssub-TLVs present",tslen ? "" : "no "); 1042 1043 tptr+=tslen; 1044 tmp-=(13+tslen); 1045 } 1046 break; 1047 1048 case TLV_EXT_IS_REACH: 1049 printf("Extended IS Reachability (%u)",len); 1050 tptr=pptr; 1051 tmp=len; 1052 while (tmp>0) { 1053 printf("\n\t\t\tIS Neighbor: "); 1054 if (!isis_print_nodeid(tptr)) 1055 return (1); 1056 tptr+=(SYSTEM_ID_LEN+1); 1057 if (!TTEST2(*tptr, 3)) 1058 goto trunctlv; 1059 printf(", Metric: %d",EXTRACT_24BITS(tptr)); 1060 tptr+=3; 1061 if (!TTEST2(*tptr, 1)) 1062 goto trunctlv; 1063 tslen=*(tptr++); 1064 printf(", %ssub-TLVs present",tslen ? "" : "no "); 1065 if (tslen) { 1066 printf(" (%u)",tslen); 1067 ttslen=tslen; 1068 while (ttslen>0) { 1069 if (!TTEST2(*tptr,2)) 1070 goto trunctlv; 1071 printf("\n\t\t\t "); 1072 subt=*(tptr++); 1073 subl=*(tptr++); 1074 switch(subt) { 1075 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP: 1076 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr)); 1077 break; 1078 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW : 1079 if (!TTEST2(*tptr,4)) 1080 goto trunctlv; 1081 j = EXTRACT_32BITS(tptr); 1082 memcpy (&bw, &j, 4); 1083 printf("Maximum link bandwidth : %.3f Mbps", 1084 bw*8/1000000 ); 1085 break; 1086 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW : 1087 if (!TTEST2(*tptr,4)) 1088 goto trunctlv; 1089 j = EXTRACT_32BITS(tptr); 1090 memcpy (&bw, &j, 4); 1091 printf("Reservable link bandwidth: %.3f Mbps", 1092 bw*8/1000000 ); 1093 break; 1094 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW : 1095 printf("Unreserved bandwidth:"); 1096 for (i = 0; i < 8; i++) { 1097 if (!TTEST2(*tptr,4)) 1098 goto trunctlv; 1099 j = EXTRACT_32BITS(tptr); 1100 memcpy (&bw, &j, 4); 1101 printf("\n\t\t\t priority level %d: %.3f Mbps", 1102 i, bw*8/1000000 ); 1103 tptr+=4; 1104 } 1105 tptr-=32; 1106 break; 1107 case SUBTLV_EXT_IS_REACH_TE_METRIC: 1108 if (!TTEST2(*tptr,3)) 1109 goto trunctlv; 1110 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr)); 1111 break; 1112 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: 1113 if (!TTEST2(*tptr,4)) 1114 goto trunctlv; 1115 printf("IPv4 interface address: %s", ipaddr_string(tptr)); 1116 break; 1117 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: 1118 if (!TTEST2(*tptr,4)) 1119 goto trunctlv; 1120 printf("IPv4 neighbor address: %s", ipaddr_string(tptr)); 1121 break; 1122 case 250: 1123 case 251: 1124 case 252: 1125 case 253: 1126 case 254: 1127 printf("Reserved for cisco specific extensions, type %d, length %d", subt, subl); 1128 break; 1129 case 255: 1130 printf("Reserved for future expansion, type %d, length %d", subt, subl); 1131 break; 1132 default: 1133 printf("unknown subTLV, type %d, length %d", subt, subl); 1134 } 1135 tptr+=subl; 1136 ttslen-=(subl+2); 1137 } 1138 } 1139 tptr+=tslen; 1140 tmp-=(11+tslen); 1141 } 1142 break; 1143 case TLV_IS_REACH: 1144 printf("IS Reachability (%u)",len); 1145 1146 tptr=pptr; 1147 1148 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ 1149 goto trunctlv; 1150 1151 switch (*tptr) { 1152 case 0: 1153 printf("\n\t\t\tIsNotVirtual"); 1154 break; 1155 case 1: 1156 printf("\n\t\t\tIsVirtual"); 1157 break; 1158 default: 1159 printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr)); 1160 break; 1161 } 1162 1163 tptr++; 1164 1165 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; 1166 1167 tmp = len; 1168 while (tmp >= sizeof(struct isis_tlv_is_reach)) { 1169 if (!TTEST(*tlv_is_reach)) 1170 goto trunctlv; 1171 1172 printf("\n\t\t\tIS Neighbor: "); 1173 isis_print_nodeid(tlv_is_reach->neighbor_nodeid); 1174 1175 printf(", Default Metric: %d, %s", 1176 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_default), 1177 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_default) ? "External" : "Internal"); 1178 1179 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_delay)) 1180 printf("\n\t\t\t Delay Metric: %d, %s", 1181 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_delay), 1182 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_delay) ? "External" : "Internal"); 1183 1184 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_expense)) 1185 printf("\n\t\t\t Expense Metric: %d, %s", 1186 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_expense), 1187 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_expense) ? "External" : "Internal"); 1188 1189 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_error)) 1190 printf("\n\t\t\t Error Metric: %d, %s", 1191 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_error), 1192 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_error) ? "External" : "Internal"); 1193 1194 tmp -= sizeof(struct isis_tlv_is_reach); 1195 tlv_is_reach++; 1196 } 1197 break; 1198 1199 case TLV_IP_REACH: 1200 printf("IP Internal reachability (%u)",len); 1201 if (!isis_print_tlv_ip_reach(pptr, len)) 1202 return (1); 1203 break; 1204 1205 case TLV_IP_REACH_EXT: 1206 printf("IP External reachability (%u)",len); 1207 if (!isis_print_tlv_ip_reach(pptr, len)) 1208 return (1); 1209 break; 1210 1211 case TLV_EXT_IP_REACH: 1212 printf("Extended IP reachability (%u)",len); 1213 i=len; 1214 tptr=pptr; 1215 1216 while (i>0) { 1217 memset (prefix, 0, 4); 1218 if (!TTEST2(*tptr, 4)) 1219 return (1); 1220 metric = EXTRACT_32BITS(tptr); 1221 tptr+=4; 1222 1223 if (!TTEST2(*tptr, 1)) 1224 return (1); 1225 j=*(tptr); 1226 bit_length = (*(tptr)++&0x3f); 1227 byte_length = (bit_length + 7) / 8; 1228 if (!TTEST2(*tptr, byte_length)) 1229 return (1); 1230 1231 memcpy(prefix,tptr,byte_length); 1232 1233 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d", 1234 prefix[0], 1235 prefix[1], 1236 prefix[2], 1237 prefix[3], 1238 bit_length); 1239 1240 printf("\n\t\t\t Metric: %u, Distribution: %s", 1241 metric, 1242 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up"); 1243 1244 printf(", %ssub-TLVs present", 1245 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no "); 1246 1247 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) { 1248 if (!TTEST2(*tptr, 1)) 1249 return (1); 1250 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */ 1251 i-=*tptr; 1252 tptr+=*tptr++; 1253 } 1254 1255 i-=(5+byte_length); 1256 tptr+=byte_length; 1257 } 1258 break; 1259 1260 #ifdef INET6 1261 1262 case TLV_IP6_REACH: 1263 printf("IP6 reachability (%u)",len); 1264 i=len; 1265 tptr=pptr; 1266 1267 while (i>0) { 1268 if (!TTEST2(*tptr, 4)) 1269 return (1); 1270 metric = EXTRACT_32BITS(tptr); 1271 tptr+=4; 1272 1273 if (!TTEST2(*tptr, 2)) 1274 return (1); 1275 j=*(tptr++); 1276 bit_length = (*(tptr)++); 1277 byte_length = (bit_length + 7) / 8; 1278 if (!TTEST2(*tptr, byte_length)) 1279 return (1); 1280 1281 memset(prefix6, 0, 16); 1282 memcpy(prefix6,tptr,byte_length); 1283 1284 printf("\n\t\t\tIPv6 prefix: %s/%u", 1285 ip6addr_string(prefix6), 1286 bit_length); 1287 1288 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present", 1289 metric, 1290 ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal", 1291 ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up", 1292 ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no "); 1293 1294 if (ISIS_MASK_TLV_IP6_SUBTLV(j)) { 1295 if (!TTEST2(*tptr, 1)) 1296 return (1); 1297 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */ 1298 i-=*tptr; 1299 tptr+=*tptr++; 1300 } 1301 1302 i-=(6+byte_length); 1303 tptr+=byte_length; 1304 } 1305 1306 break; 1307 #endif 1308 1309 #ifdef INET6 1310 case TLV_IP6ADDR: 1311 printf("IPv6 Interface address(es) (%u)",len); 1312 i=len; 1313 tptr=pptr; 1314 while (i>0) { 1315 if (!TTEST2(*tptr, 16)) 1316 goto trunctlv; 1317 1318 printf("\n\t\t\tIPv6 interface address: %s", 1319 ip6addr_string(tptr)); 1320 1321 tptr += 16; 1322 i -= 16; 1323 } 1324 break; 1325 #endif 1326 case TLV_AUTH: 1327 if (!TTEST2(*pptr, 1)) 1328 goto trunctlv; 1329 printf("Authentication (%u)",len); 1330 if (*pptr==SUBTLV_AUTH_SIMPLE) { 1331 printf("\n\t\t\tsimple text password: "); 1332 for(i=1;i<len;i++) { 1333 if (!TTEST2(*(pptr+i), 1)) 1334 goto trunctlv; 1335 printf("%c",*(pptr+i)); 1336 } 1337 } 1338 if (!TTEST2(*pptr, 1)) 1339 goto trunctlv; 1340 if (*pptr==SUBTLV_AUTH_MD5) { 1341 printf("\n\t\t\tMD5 password: "); 1342 for(i=1;i<len;i++) { 1343 if (!TTEST2(*(pptr+i), 1)) 1344 goto trunctlv; 1345 printf("%02x",*(pptr+i)); 1346 } 1347 } 1348 break; 1349 1350 case TLV_PTP_ADJ: 1351 printf("Point-to-point Adjacency State (%u)",len); 1352 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)pptr; 1353 i=len; 1354 if(i>=1) { 1355 if (!TTEST2(*pptr, 1)) 1356 goto trunctlv; 1357 printf("\n\t\t\tAdjacency State: %s", 1358 tok2str(isis_ptp_adjancey_values, "#0x%x", *pptr)); 1359 i--; 1360 } 1361 if(i>=4) { 1362 if (!TTEST2(tlv_ptp_adj->ext_local_circuit_id, 4)) 1363 goto trunctlv; 1364 printf("\n\t\t\tExtended Local circuit ID: 0x%08x", 1365 EXTRACT_32BITS(tlv_ptp_adj->ext_local_circuit_id)); 1366 i-=4; 1367 } 1368 if(i>=6) { 1369 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, 6)) 1370 goto trunctlv; 1371 printf("\n\t\t\tNeighbor SystemID: "); 1372 isis_print_sysid(tlv_ptp_adj->neighbor_sysid); 1373 i-=6; 1374 } 1375 if(i>=4) { 1376 if (!TTEST2(tlv_ptp_adj->neighbor_ext_local_circuit_id, 4)) 1377 goto trunctlv; 1378 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x", 1379 EXTRACT_32BITS(tlv_ptp_adj->neighbor_ext_local_circuit_id)); 1380 } 1381 break; 1382 1383 case TLV_PROTOCOLS: 1384 printf("Protocols supported (%u)", len); 1385 printf("\n\t\t\tNLPID(s): "); 1386 for (i = 0; i < len; i++) { 1387 if (!TTEST2(*(pptr+i), 1)) 1388 goto trunctlv; 1389 printf("%s (0x%02x)",tok2str(isis_nlpid_values, "Unknown", *(pptr+i)),*(pptr+i)); 1390 if (i<len-1) 1391 printf(", "); 1392 } 1393 break; 1394 1395 case TLV_TE_ROUTER_ID: 1396 printf("Traffic Engineering Router ID (%u)",len); 1397 if (!TTEST2(*pptr, 4)) 1398 goto trunctlv; 1399 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr)); 1400 break; 1401 1402 case TLV_IPADDR: 1403 printf("IPv4 Interface address(es) (%u)",len); 1404 i=len; 1405 tptr=pptr; 1406 while (i>0) { 1407 if (!TTEST2(*tptr, 4)) 1408 goto trunctlv; 1409 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr)); 1410 tptr += 4; 1411 i -= 4; 1412 } 1413 break; 1414 1415 case TLV_HOSTNAME: 1416 printf("Hostname (%u)", len); 1417 printf("\n\t\t\tHostname: "); 1418 for(i = 0; i < len; i++) { 1419 if (!TTEST2(*(pptr+i), 1)) 1420 goto trunctlv; 1421 printf("%c",*(pptr+i)); 1422 } 1423 break; 1424 1425 case TLV_LSP: 1426 tlv_lsp = (const struct isis_tlv_lsp *)pptr; 1427 printf("LSP entries (%u)", len); 1428 i=0; 1429 while(i<len) { 1430 printf("\n\t\t\tlsp-id: "); 1431 if (!isis_print_nodeid(tlv_lsp->lsp_id)) 1432 return (1); 1433 if (!TTEST((tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1])) 1434 goto trunctlv; 1435 printf("-%02x",(tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]); 1436 if (!TTEST2(tlv_lsp->sequence_number, 4)) 1437 goto trunctlv; 1438 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); 1439 if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) 1440 goto trunctlv; 1441 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); 1442 if (!TTEST2(tlv_lsp->checksum, 2)) 1443 goto trunctlv; 1444 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); 1445 i+=sizeof(struct isis_tlv_lsp); 1446 tlv_lsp++; 1447 } 1448 break; 1449 1450 case TLV_CHECKSUM: 1451 if (!TTEST2(*pptr, 2)) 1452 goto trunctlv; 1453 printf("Checksum (%u)", len); 1454 printf("\n\t\t\tchecksum: 0x%04x", 1455 EXTRACT_16BITS(pptr)); 1456 1457 if (osi_cksum(optr, length, off)) 1458 printf(" (incorrect)"); 1459 else 1460 printf(" (correct)"); 1461 break; 1462 1463 case TLV_MT_SUPPORTED: 1464 printf("Multi Topology (%u)",len); 1465 i=len; 1466 tptr=pptr; 1467 while (i>1) { 1468 /* length can only be a multiple of 2, otherwise there is 1469 something broken -> so decode down until length is 1 */ 1470 if (i!=1) { 1471 if (!TTEST2(*tptr, 2)) 1472 goto trunctlv; 1473 printf("\n\t\t\t"); 1474 switch(EXTRACT_16BITS(tptr)&0x0fff) { 1475 1476 case 0: 1477 printf("IPv4 unicast"); 1478 break; 1479 1480 case 1: 1481 printf("In-Band Management"); 1482 break; 1483 1484 case 2: 1485 printf("IPv6 unicast"); 1486 break; 1487 1488 case 3: 1489 printf("Multicast"); 1490 break; 1491 1492 case 4095: 1493 printf("Development, Experimental or Proprietary"); 1494 break; 1495 1496 default: 1497 printf("Reserved for IETF Consensus"); 1498 break; 1499 } 1500 printf(" Topology (0x%03x)%s%s", 1501 EXTRACT_16BITS(tptr)&0xfff, 1502 (EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs present", 1503 (EXTRACT_16BITS(tptr)&0x4000) ? ", ATT bit set" : "" ); 1504 } else { 1505 printf("\n\t\t\tmalformed MT-ID"); 1506 break; 1507 } 1508 i-=2; 1509 tptr+=2; 1510 } 1511 break; 1512 1513 case TLV_RESTART_SIGNALING: 1514 tptr=pptr; 1515 printf("Restart Signaling (%u)",len); 1516 if (!TTEST2(*tptr, 3)) 1517 goto trunctlv; 1518 1519 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us", 1520 ISIS_MASK_RESTART_RR(*tptr) ? "set" : "clear", 1521 ISIS_MASK_RESTART_RA(*tptr++) ? "set" : "clear", 1522 EXTRACT_16BITS(tptr)); 1523 1524 break; 1525 1526 default: 1527 printf("unknown TLV, type %d, length %d\n\t\t\t", type, len); 1528 tptr=pptr; 1529 1530 for(i=0;i<len;i++) { 1531 if (!TTEST2(*(tptr+i), 1)) 1532 goto trunctlv; 1533 printf("%02x",*(tptr+i)); /* formatted hex output of unknown TLV data */ 1534 if (i%2) 1535 printf(" "); 1536 if (i/16!=(i+1)/16) { 1537 if (i<(len-1)) 1538 printf("\n\t\t\t"); 1539 } 1540 } 1541 break; 1542 } 1543 1544 pptr += len; 1545 packet_len -= len; 1546 } 1547 1548 if (packet_len != 0) { 1549 printf("\n\t\t\t %d straggler bytes", packet_len); 1550 } 1551 return (1); 1552 1553 trunc: 1554 fputs("[|isis]", stdout); 1555 return (1); 1556 1557 trunctlv: 1558 printf("\n\t\t\t packet exceeded snapshot"); 1559 return(1); 1560 } 1561 1562 /* 1563 * Verify the checksum. See 8473-1, Appendix C, section C.4. 1564 */ 1565 1566 static int 1567 osi_cksum(register const u_char *p, register u_int len, u_char *off) 1568 { 1569 int32_t c0 = 0, c1 = 0; 1570 1571 if ((off[0] == 0) && (off[1] == 0)) 1572 return 0; 1573 1574 off[0] = off[1] = 0; 1575 while ((int)--len >= 0) { 1576 c0 += *p++; 1577 c0 %= 255; 1578 c1 += c0; 1579 c1 %= 255; 1580 } 1581 return (c0 | c1); 1582 } 1583 1584