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.2.2 2002/06/29 04:28:44 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 u_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 u_int mask; 591 int prefix_len; 592 const struct isis_tlv_ip_reach *tlv_ip_reach; 593 594 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; 595 596 while (length > 0) { 597 if (length < sizeof(*tlv_ip_reach)) { 598 printf("short IP reachability (%d vs %lu)", length, 599 (unsigned long)sizeof(*tlv_ip_reach)); 600 return (0); 601 } 602 603 if (!TTEST(*tlv_ip_reach)) 604 return (0); 605 606 mask = EXTRACT_32BITS(tlv_ip_reach->mask); 607 prefix_len = 0; 608 609 while (prefix_len <= 33) { 610 if (bitmasks[prefix_len++] == mask) { 611 prefix_len--; 612 break; 613 } 614 } 615 616 /* 617 * 34 indicates no match -> must be a discontiguous netmask 618 * lets dump the mask, otherwise print the prefix_len 619 */ 620 if (prefix_len == 34) 621 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u", 622 (tlv_ip_reach->prefix)[0], 623 (tlv_ip_reach->prefix)[1], 624 (tlv_ip_reach->prefix)[2], 625 (tlv_ip_reach->prefix)[3], 626 (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1], 627 (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]); 628 else 629 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u", 630 (tlv_ip_reach->prefix)[0], 631 (tlv_ip_reach->prefix)[1], 632 (tlv_ip_reach->prefix)[2], 633 (tlv_ip_reach->prefix)[3], prefix_len); 634 635 printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s", 636 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default), 637 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_default) ? "External" : "Internal", 638 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->metric_default) ? "down" : "up"); 639 640 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_delay)) 641 printf("\n\t\t\t Delay Metric: %02d, %s", 642 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_delay), 643 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_delay) ? "External" : "Internal"); 644 645 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_expense)) 646 printf("\n\t\t\t Expense Metric: %02d, %s", 647 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_expense), 648 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_expense) ? "External" : "Internal"); 649 650 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_error)) 651 printf("\n\t\t\t Error Metric: %02d, %s", 652 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_error), 653 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_error) ? "External" : "Internal"); 654 655 length -= sizeof(struct isis_tlv_ip_reach); 656 tlv_ip_reach++; 657 } 658 return (1); 659 } 660 661 /* 662 * isis_print 663 * Decode IS-IS packets. Return 0 on error. 664 */ 665 666 static int isis_print (const u_char *p, u_int length) 667 { 668 const struct isis_common_header *header; 669 670 const struct isis_iih_lan_header *header_iih_lan; 671 const struct isis_iih_ptp_header *header_iih_ptp; 672 const struct isis_lsp_header *header_lsp; 673 const struct isis_csnp_header *header_csnp; 674 const struct isis_psnp_header *header_psnp; 675 676 const struct isis_tlv_lsp *tlv_lsp; 677 const struct isis_tlv_ptp_adj *tlv_ptp_adj; 678 const struct isis_tlv_is_reach *tlv_is_reach; 679 680 u_char pdu_type, max_area, type, len, tmp, alen, subl, subt, tslen, ttslen; 681 const u_char *optr, *pptr, *tptr; 682 u_char subtlv_len; 683 u_short packet_len,pdu_len; 684 u_int i,j,bit_length,byte_length,metric; 685 u_char prefix[4]; /* copy buffer for ipv4 prefixes */ 686 #ifdef INET6 687 u_char prefix6[16]; /* copy buffer for ipv6 prefixes */ 688 #endif 689 u_char off[2]; 690 float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV */ 691 692 packet_len=length; 693 optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */ 694 header = (const struct isis_common_header *)p; 695 TCHECK(*header); 696 pptr = p+(ISIS_COMMON_HEADER_SIZE); 697 header_iih_lan = (const struct isis_iih_lan_header *)pptr; 698 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; 699 header_lsp = (const struct isis_lsp_header *)pptr; 700 header_csnp = (const struct isis_csnp_header *)pptr; 701 header_psnp = (const struct isis_psnp_header *)pptr; 702 703 /* 704 * Sanity checking of the header. 705 */ 706 if (header->nlpid != NLPID_ISIS) { 707 printf(", coding error!"); 708 return (0); 709 } 710 711 if (header->version != ISIS_VERSION) { 712 printf(", version %d packet not supported", header->version); 713 return (0); 714 } 715 716 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) { 717 printf(", system ID length of %d is not supported", 718 header->id_length); 719 return (0); 720 } 721 722 if (header->pkt_version != ISIS_VERSION) { 723 printf(", version %d packet not supported", header->pkt_version); 724 return (0); 725 } 726 727 max_area = header->max_area; 728 switch(max_area) { 729 case 0: 730 max_area = 3; /* silly shit */ 731 break; 732 case 255: 733 printf(", bad packet -- 255 areas"); 734 return (0); 735 default: 736 break; 737 } 738 739 printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)", 740 header->fixed_len, 741 header->pkt_version, 742 max_area, 743 header->max_area); 744 745 pdu_type=header->pdu_type; 746 747 switch (pdu_type) { 748 749 case L1_LAN_IIH: 750 case L2_LAN_IIH: 751 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { 752 printf(", bogus fixed header length %u should be %lu", 753 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); 754 return (0); 755 } 756 757 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); 758 if (packet_len>pdu_len) { 759 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 760 length=pdu_len; 761 } 762 763 printf(", L%s Lan IIH (%u)", 764 ISIS_MASK_LEVEL_BITS(pdu_type) ? "1" : "2", 765 pdu_len); 766 767 TCHECK(*header_iih_lan); 768 printf("\n\t\t source-id: "); 769 isis_print_sysid(header_iih_lan->source_id); 770 printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan->holding_time)); 771 switch(header_iih_lan->circuit_type) { 772 773 case 1: 774 printf(", Level 1 only"); 775 break; 776 777 case 2: 778 printf(", Level 2 only"); 779 break; 780 781 case 3: 782 printf(", Level 1, Level 2"); 783 break; 784 785 default: 786 printf(", unknown 0x%02x", header_iih_lan->circuit_type); 787 break; 788 } 789 printf("\n\t\t lan-id: "); 790 isis_print_nodeid(header_iih_lan->lan_id); 791 printf(", Priority: %u",(header_iih_lan->priority) & PRIORITY_MASK); 792 793 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 794 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 795 break; 796 797 case PTP_IIH: 798 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { 799 printf(", bogus fixed header length %u should be %lu", 800 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); 801 return (0); 802 } 803 804 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); 805 if (packet_len>pdu_len) { 806 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 807 length=pdu_len; 808 } 809 810 printf(", PTP IIH (%u)",pdu_len); 811 TCHECK(*header_iih_ptp); 812 printf("\n\t\t source-id: "); 813 isis_print_sysid(header_iih_ptp->source_id); 814 printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp->holding_time)); 815 printf(", circuit-id: 0x%02x", header_iih_ptp->circuit_id); 816 switch(header_iih_ptp->circuit_type) { 817 818 case 1: 819 printf(", Level 1 only"); 820 break; 821 822 case 2: 823 printf(", Level 2 only"); 824 break; 825 826 case 3: 827 printf(", Level 1, Level 2"); 828 break; 829 830 default: 831 printf(", unknown 0x%02x", header_iih_ptp->circuit_type); 832 break; 833 } 834 835 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 836 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 837 break; 838 839 case L1_LSP: 840 case L2_LSP: 841 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { 842 printf(", bogus fixed header length %u should be %lu", 843 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); 844 return (0); 845 } 846 847 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); 848 if (packet_len>pdu_len) { 849 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 850 length=pdu_len; 851 } 852 853 if (pdu_type == L1_LSP) 854 printf(", L1 LSP (%u)",pdu_len); 855 else if (pdu_type == L2_LSP) 856 printf(", L2 LSP (%u)",pdu_len); 857 858 TCHECK(*header_lsp); 859 printf("\n\t\t lsp-id: "); 860 isis_print_lspid(header_lsp->lsp_id); 861 printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number)); 862 printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime)); 863 printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum)); 864 865 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); 866 867 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { 868 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); 869 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); 870 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); 871 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); 872 printf("ATT bit set, "); 873 } 874 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); 875 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); 876 877 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 878 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 879 break; 880 881 case L1_CSNP: 882 case L2_CSNP: 883 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { 884 printf(", bogus fixed header length %u should be %lu", 885 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); 886 return (0); 887 } 888 889 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); 890 if (packet_len>pdu_len) { 891 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 892 length=pdu_len; 893 } 894 895 printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); 896 TCHECK(*header_csnp); 897 printf("\n\t\t source-id: "); 898 isis_print_nodeid(header_csnp->source_id); 899 printf("\n\t\t start lsp-id: "); 900 isis_print_lspid(header_csnp->start_lsp_id); 901 printf("\n\t\t end lsp-id: "); 902 isis_print_lspid(header_csnp->end_lsp_id); 903 904 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 905 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 906 break; 907 908 case L1_PSNP: 909 case L2_PSNP: 910 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { 911 printf("- bogus fixed header length %u should be %lu", 912 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); 913 return (0); 914 } 915 916 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); 917 if (packet_len>pdu_len) { 918 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 919 length=pdu_len; 920 } 921 922 printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); 923 TCHECK(*header_psnp); 924 printf("\n\t\t source-id: "); 925 isis_print_nodeid(header_psnp->source_id); 926 927 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 928 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 929 break; 930 931 default: 932 printf(", PDU type (0x%02x) not supported", pdu_type); 933 return (1); 934 } 935 936 /* 937 * Now print the TLV's. 938 */ 939 940 while (packet_len >= 2) { 941 if (pptr == snapend) { 942 return (1); 943 } 944 945 if (!TTEST2(*pptr, 2)) { 946 printf("\n\t\t\t packet exceeded snapshot (%ld) bytes", 947 (long)(pptr-snapend)); 948 return (1); 949 } 950 type = *pptr++; 951 len = *pptr++; 952 packet_len -= 2; 953 if (len > packet_len) { 954 break; 955 } 956 printf("\n\t\t "); 957 958 switch (type) { 959 case TLV_AREA_ADDR: 960 printf("Area address(es) (%u)",len); 961 tmp = len; 962 tptr = pptr; 963 if (!TTEST2(*tptr, 1)) 964 goto trunctlv; 965 alen = *tptr++; 966 while (tmp && alen < tmp) { 967 printf("\n\t\t\tArea address (%u): ",alen); 968 if (!print_nsap(tptr, alen)) 969 return (1); 970 tptr += alen; 971 tmp -= alen + 1; 972 if (tmp==0) /* if this is the last area address do not attemt a boundary check */ 973 break; 974 if (!TTEST2(*tptr, 1)) 975 goto trunctlv; 976 alen = *tptr++; 977 } 978 break; 979 case TLV_ISNEIGH: 980 printf("IS Neighbor(s) (%u)",len); 981 tmp = len; 982 tptr = pptr; 983 while (tmp >= ETHER_ADDR_LEN) { 984 printf("\n\t\t\tIS Neighbor: "); 985 if (!isis_print_sysid(tptr)) 986 return (1); 987 tmp -= ETHER_ADDR_LEN; 988 tptr += ETHER_ADDR_LEN; 989 } 990 break; 991 992 case TLV_PADDING: 993 printf("Padding (%u)", len); 994 break; 995 996 case TLV_MT_IS_REACH: 997 printf("Multi Topology IS Reachability (%u)",len); 998 tptr=pptr; 999 tmp=len; 1000 while (tmp>0) { 1001 printf("\n\t\t\t"); 1002 if (!TTEST2(*tptr, 2)) 1003 goto trunctlv; 1004 switch(EXTRACT_16BITS(tptr)&0x0fff) { 1005 1006 case 0: 1007 printf("IPv4 unicast"); 1008 break; 1009 1010 case 1: 1011 printf("In-Band Management"); 1012 break; 1013 1014 case 2: 1015 printf("IPv6 unicast"); 1016 break; 1017 1018 case 3: 1019 printf("Multicast"); 1020 break; 1021 1022 case 4095: 1023 printf("Development, Experimental or Proprietary"); 1024 break; 1025 1026 default: 1027 printf("Reserved for IETF Consensus"); 1028 break; 1029 } 1030 printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff); 1031 tptr+=2; 1032 printf("\n\t\t\t IS Neighbor: "); 1033 if (!isis_print_nodeid(tptr)) 1034 return (1); 1035 tptr+=(SYSTEM_ID_LEN+1); 1036 if (!TTEST2(*tptr, 3)) 1037 goto trunctlv; 1038 printf(", Metric: %d",EXTRACT_24BITS(tptr)); 1039 tptr+=3; 1040 if (!TTEST2(*tptr, 1)) 1041 goto trunctlv; 1042 tslen=*(tptr++); 1043 printf(", %ssub-TLVs present",tslen ? "" : "no "); 1044 1045 tptr+=tslen; 1046 tmp-=(13+tslen); 1047 } 1048 break; 1049 1050 case TLV_EXT_IS_REACH: 1051 printf("Extended IS Reachability (%u)",len); 1052 tptr=pptr; 1053 tmp=len; 1054 while (tmp>0) { 1055 printf("\n\t\t\tIS Neighbor: "); 1056 if (!isis_print_nodeid(tptr)) 1057 return (1); 1058 tptr+=(SYSTEM_ID_LEN+1); 1059 if (!TTEST2(*tptr, 3)) 1060 goto trunctlv; 1061 printf(", Metric: %d",EXTRACT_24BITS(tptr)); 1062 tptr+=3; 1063 if (!TTEST2(*tptr, 1)) 1064 goto trunctlv; 1065 tslen=*(tptr++); 1066 printf(", %ssub-TLVs present",tslen ? "" : "no "); 1067 if (tslen) { 1068 printf(" (%u)",tslen); 1069 ttslen=tslen; 1070 while (ttslen>0) { 1071 if (!TTEST2(*tptr,2)) 1072 goto trunctlv; 1073 printf("\n\t\t\t "); 1074 subt=*(tptr++); 1075 subl=*(tptr++); 1076 switch(subt) { 1077 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP: 1078 printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr)); 1079 break; 1080 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW : 1081 if (!TTEST2(*tptr,4)) 1082 goto trunctlv; 1083 j = EXTRACT_32BITS(tptr); 1084 memcpy (&bw, &j, 4); 1085 printf("Maximum link bandwidth : %.3f Mbps", 1086 bw*8/1000000 ); 1087 break; 1088 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW : 1089 if (!TTEST2(*tptr,4)) 1090 goto trunctlv; 1091 j = EXTRACT_32BITS(tptr); 1092 memcpy (&bw, &j, 4); 1093 printf("Reservable link bandwidth: %.3f Mbps", 1094 bw*8/1000000 ); 1095 break; 1096 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW : 1097 printf("Unreserved bandwidth:"); 1098 for (i = 0; i < 8; i++) { 1099 if (!TTEST2(*tptr,4)) 1100 goto trunctlv; 1101 j = EXTRACT_32BITS(tptr); 1102 memcpy (&bw, &j, 4); 1103 printf("\n\t\t\t priority level %d: %.3f Mbps", 1104 i, bw*8/1000000 ); 1105 tptr+=4; 1106 } 1107 tptr-=32; 1108 break; 1109 case SUBTLV_EXT_IS_REACH_TE_METRIC: 1110 if (!TTEST2(*tptr,3)) 1111 goto trunctlv; 1112 printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr)); 1113 break; 1114 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: 1115 if (!TTEST2(*tptr,4)) 1116 goto trunctlv; 1117 printf("IPv4 interface address: %s", ipaddr_string(tptr)); 1118 break; 1119 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: 1120 if (!TTEST2(*tptr,4)) 1121 goto trunctlv; 1122 printf("IPv4 neighbor address: %s", ipaddr_string(tptr)); 1123 break; 1124 case 250: 1125 case 251: 1126 case 252: 1127 case 253: 1128 case 254: 1129 printf("Reserved for cisco specific extensions, type %d, length %d", subt, subl); 1130 break; 1131 case 255: 1132 printf("Reserved for future expansion, type %d, length %d", subt, subl); 1133 break; 1134 default: 1135 printf("unknown subTLV, type %d, length %d", subt, subl); 1136 } 1137 tptr+=subl; 1138 ttslen-=(subl+2); 1139 } 1140 } 1141 tptr+=tslen; 1142 tmp-=(11+tslen); 1143 } 1144 break; 1145 case TLV_IS_REACH: 1146 printf("IS Reachability (%u)",len); 1147 1148 tptr=pptr; 1149 1150 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ 1151 goto trunctlv; 1152 1153 switch (*tptr) { 1154 case 0: 1155 printf("\n\t\t\tIsNotVirtual"); 1156 break; 1157 case 1: 1158 printf("\n\t\t\tIsVirtual"); 1159 break; 1160 default: 1161 printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr)); 1162 break; 1163 } 1164 1165 tptr++; 1166 1167 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; 1168 1169 tmp = len; 1170 while (tmp >= sizeof(struct isis_tlv_is_reach)) { 1171 if (!TTEST(*tlv_is_reach)) 1172 goto trunctlv; 1173 1174 printf("\n\t\t\tIS Neighbor: "); 1175 isis_print_nodeid(tlv_is_reach->neighbor_nodeid); 1176 1177 printf(", Default Metric: %d, %s", 1178 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_default), 1179 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_default) ? "External" : "Internal"); 1180 1181 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_delay)) 1182 printf("\n\t\t\t Delay Metric: %d, %s", 1183 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_delay), 1184 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_delay) ? "External" : "Internal"); 1185 1186 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_expense)) 1187 printf("\n\t\t\t Expense Metric: %d, %s", 1188 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_expense), 1189 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_expense) ? "External" : "Internal"); 1190 1191 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_error)) 1192 printf("\n\t\t\t Error Metric: %d, %s", 1193 ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_error), 1194 ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_error) ? "External" : "Internal"); 1195 1196 tmp -= sizeof(struct isis_tlv_is_reach); 1197 tlv_is_reach++; 1198 } 1199 break; 1200 1201 case TLV_IP_REACH: 1202 printf("IP Internal reachability (%u)",len); 1203 if (!isis_print_tlv_ip_reach(pptr, len)) 1204 return (1); 1205 break; 1206 1207 case TLV_IP_REACH_EXT: 1208 printf("IP External reachability (%u)",len); 1209 if (!isis_print_tlv_ip_reach(pptr, len)) 1210 return (1); 1211 break; 1212 1213 case TLV_EXT_IP_REACH: 1214 printf("Extended IP reachability (%u)",len); 1215 i=len; 1216 tptr=pptr; 1217 1218 while (i>0) { 1219 memset (prefix, 0, 4); 1220 if (!TTEST2(*tptr, 4)) 1221 return (1); 1222 metric = EXTRACT_32BITS(tptr); 1223 tptr+=4; 1224 1225 if (!TTEST2(*tptr, 1)) 1226 return (1); 1227 j=*(tptr); 1228 bit_length = (*(tptr)++&0x3f); 1229 byte_length = (bit_length + 7) / 8; 1230 if (!TTEST2(*tptr, byte_length)) 1231 return (1); 1232 1233 memcpy(prefix,tptr,byte_length); 1234 1235 printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d", 1236 prefix[0], 1237 prefix[1], 1238 prefix[2], 1239 prefix[3], 1240 bit_length); 1241 1242 printf("\n\t\t\t Metric: %u, Distribution: %s", 1243 metric, 1244 ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up"); 1245 1246 printf(", %ssub-TLVs present", 1247 ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no "); 1248 1249 if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) { 1250 if (!TTEST2(*tptr, 1)) 1251 return (1); 1252 subtlv_len = *tptr; 1253 printf(" (%u)",subtlv_len); /* no subTLV decoder supported - just print out subTLV length */ 1254 i -= subtlv_len; 1255 tptr += subtlv_len + 1; 1256 } 1257 1258 i-=(5+byte_length); 1259 tptr+=byte_length; 1260 } 1261 break; 1262 1263 #ifdef INET6 1264 1265 case TLV_IP6_REACH: 1266 printf("IP6 reachability (%u)",len); 1267 i=len; 1268 tptr=pptr; 1269 1270 while (i>0) { 1271 if (!TTEST2(*tptr, 4)) 1272 return (1); 1273 metric = EXTRACT_32BITS(tptr); 1274 tptr+=4; 1275 1276 if (!TTEST2(*tptr, 2)) 1277 return (1); 1278 j=*(tptr++); 1279 bit_length = (*(tptr)++); 1280 byte_length = (bit_length + 7) / 8; 1281 if (!TTEST2(*tptr, byte_length)) 1282 return (1); 1283 1284 memset(prefix6, 0, 16); 1285 memcpy(prefix6,tptr,byte_length); 1286 1287 printf("\n\t\t\tIPv6 prefix: %s/%u", 1288 ip6addr_string(prefix6), 1289 bit_length); 1290 1291 printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present", 1292 metric, 1293 ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal", 1294 ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up", 1295 ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no "); 1296 1297 if (ISIS_MASK_TLV_IP6_SUBTLV(j)) { 1298 if (!TTEST2(*tptr, 1)) 1299 return (1); 1300 printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */ 1301 i-=*tptr; 1302 tptr+=*tptr++; 1303 } 1304 1305 i-=(6+byte_length); 1306 tptr+=byte_length; 1307 } 1308 1309 break; 1310 #endif 1311 1312 #ifdef INET6 1313 case TLV_IP6ADDR: 1314 printf("IPv6 Interface address(es) (%u)",len); 1315 i=len; 1316 tptr=pptr; 1317 while (i>0) { 1318 if (!TTEST2(*tptr, 16)) 1319 goto trunctlv; 1320 1321 printf("\n\t\t\tIPv6 interface address: %s", 1322 ip6addr_string(tptr)); 1323 1324 tptr += 16; 1325 i -= 16; 1326 } 1327 break; 1328 #endif 1329 case TLV_AUTH: 1330 if (!TTEST2(*pptr, 1)) 1331 goto trunctlv; 1332 printf("Authentication (%u)",len); 1333 if (*pptr==SUBTLV_AUTH_SIMPLE) { 1334 printf("\n\t\t\tsimple text password: "); 1335 for(i=1;i<len;i++) { 1336 if (!TTEST2(*(pptr+i), 1)) 1337 goto trunctlv; 1338 printf("%c",*(pptr+i)); 1339 } 1340 } 1341 if (!TTEST2(*pptr, 1)) 1342 goto trunctlv; 1343 if (*pptr==SUBTLV_AUTH_MD5) { 1344 printf("\n\t\t\tMD5 password: "); 1345 for(i=1;i<len;i++) { 1346 if (!TTEST2(*(pptr+i), 1)) 1347 goto trunctlv; 1348 printf("%02x",*(pptr+i)); 1349 } 1350 } 1351 break; 1352 1353 case TLV_PTP_ADJ: 1354 printf("Point-to-point Adjacency State (%u)",len); 1355 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)pptr; 1356 i=len; 1357 if(i>=1) { 1358 if (!TTEST2(*pptr, 1)) 1359 goto trunctlv; 1360 printf("\n\t\t\tAdjacency State: %s", 1361 tok2str(isis_ptp_adjancey_values, "#0x%x", *pptr)); 1362 i--; 1363 } 1364 if(i>=4) { 1365 if (!TTEST2(tlv_ptp_adj->ext_local_circuit_id, 4)) 1366 goto trunctlv; 1367 printf("\n\t\t\tExtended Local circuit ID: 0x%08x", 1368 EXTRACT_32BITS(tlv_ptp_adj->ext_local_circuit_id)); 1369 i-=4; 1370 } 1371 if(i>=6) { 1372 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, 6)) 1373 goto trunctlv; 1374 printf("\n\t\t\tNeighbor SystemID: "); 1375 isis_print_sysid(tlv_ptp_adj->neighbor_sysid); 1376 i-=6; 1377 } 1378 if(i>=4) { 1379 if (!TTEST2(tlv_ptp_adj->neighbor_ext_local_circuit_id, 4)) 1380 goto trunctlv; 1381 printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x", 1382 EXTRACT_32BITS(tlv_ptp_adj->neighbor_ext_local_circuit_id)); 1383 } 1384 break; 1385 1386 case TLV_PROTOCOLS: 1387 printf("Protocols supported (%u)", len); 1388 printf("\n\t\t\tNLPID(s): "); 1389 for (i = 0; i < len; i++) { 1390 if (!TTEST2(*(pptr+i), 1)) 1391 goto trunctlv; 1392 printf("%s (0x%02x)",tok2str(isis_nlpid_values, "Unknown", *(pptr+i)),*(pptr+i)); 1393 if (i<len-1) 1394 printf(", "); 1395 } 1396 break; 1397 1398 case TLV_TE_ROUTER_ID: 1399 printf("Traffic Engineering Router ID (%u)",len); 1400 if (!TTEST2(*pptr, 4)) 1401 goto trunctlv; 1402 printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr)); 1403 break; 1404 1405 case TLV_IPADDR: 1406 printf("IPv4 Interface address(es) (%u)",len); 1407 i=len; 1408 tptr=pptr; 1409 while (i>0) { 1410 if (!TTEST2(*tptr, 4)) 1411 goto trunctlv; 1412 printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr)); 1413 tptr += 4; 1414 i -= 4; 1415 } 1416 break; 1417 1418 case TLV_HOSTNAME: 1419 printf("Hostname (%u)", len); 1420 printf("\n\t\t\tHostname: "); 1421 for(i = 0; i < len; i++) { 1422 if (!TTEST2(*(pptr+i), 1)) 1423 goto trunctlv; 1424 printf("%c",*(pptr+i)); 1425 } 1426 break; 1427 1428 case TLV_LSP: 1429 tlv_lsp = (const struct isis_tlv_lsp *)pptr; 1430 printf("LSP entries (%u)", len); 1431 i=0; 1432 while(i<len) { 1433 printf("\n\t\t\tlsp-id: "); 1434 if (!isis_print_nodeid(tlv_lsp->lsp_id)) 1435 return (1); 1436 if (!TTEST((tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1])) 1437 goto trunctlv; 1438 printf("-%02x",(tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]); 1439 if (!TTEST2(tlv_lsp->sequence_number, 4)) 1440 goto trunctlv; 1441 printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); 1442 if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) 1443 goto trunctlv; 1444 printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); 1445 if (!TTEST2(tlv_lsp->checksum, 2)) 1446 goto trunctlv; 1447 printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); 1448 i+=sizeof(struct isis_tlv_lsp); 1449 tlv_lsp++; 1450 } 1451 break; 1452 1453 case TLV_CHECKSUM: 1454 if (!TTEST2(*pptr, 2)) 1455 goto trunctlv; 1456 printf("Checksum (%u)", len); 1457 printf("\n\t\t\tchecksum: 0x%04x", 1458 EXTRACT_16BITS(pptr)); 1459 1460 if (osi_cksum(optr, length, off)) 1461 printf(" (incorrect)"); 1462 else 1463 printf(" (correct)"); 1464 break; 1465 1466 case TLV_MT_SUPPORTED: 1467 printf("Multi Topology (%u)",len); 1468 i=len; 1469 tptr=pptr; 1470 while (i>1) { 1471 /* length can only be a multiple of 2, otherwise there is 1472 something broken -> so decode down until length is 1 */ 1473 if (i!=1) { 1474 if (!TTEST2(*tptr, 2)) 1475 goto trunctlv; 1476 printf("\n\t\t\t"); 1477 switch(EXTRACT_16BITS(tptr)&0x0fff) { 1478 1479 case 0: 1480 printf("IPv4 unicast"); 1481 break; 1482 1483 case 1: 1484 printf("In-Band Management"); 1485 break; 1486 1487 case 2: 1488 printf("IPv6 unicast"); 1489 break; 1490 1491 case 3: 1492 printf("Multicast"); 1493 break; 1494 1495 case 4095: 1496 printf("Development, Experimental or Proprietary"); 1497 break; 1498 1499 default: 1500 printf("Reserved for IETF Consensus"); 1501 break; 1502 } 1503 printf(" Topology (0x%03x)%s%s", 1504 EXTRACT_16BITS(tptr)&0xfff, 1505 (EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs present", 1506 (EXTRACT_16BITS(tptr)&0x4000) ? ", ATT bit set" : "" ); 1507 } else { 1508 printf("\n\t\t\tmalformed MT-ID"); 1509 break; 1510 } 1511 i-=2; 1512 tptr+=2; 1513 } 1514 break; 1515 1516 case TLV_RESTART_SIGNALING: 1517 tptr=pptr; 1518 printf("Restart Signaling (%u)",len); 1519 if (!TTEST2(*tptr, 3)) 1520 goto trunctlv; 1521 1522 printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us", 1523 ISIS_MASK_RESTART_RR(*tptr) ? "set" : "clear", 1524 ISIS_MASK_RESTART_RA(*tptr) ? "set" : "clear", 1525 EXTRACT_16BITS(tptr+1)); 1526 tptr += 3; 1527 1528 break; 1529 1530 default: 1531 printf("unknown TLV, type %d, length %d\n\t\t\t", type, len); 1532 tptr=pptr; 1533 1534 for(i=0;i<len;i++) { 1535 if (!TTEST2(*(tptr+i), 1)) 1536 goto trunctlv; 1537 printf("%02x",*(tptr+i)); /* formatted hex output of unknown TLV data */ 1538 if (i%2) 1539 printf(" "); 1540 if (i/16!=(i+1)/16) { 1541 if (i<(len-1)) 1542 printf("\n\t\t\t"); 1543 } 1544 } 1545 break; 1546 } 1547 1548 pptr += len; 1549 packet_len -= len; 1550 } 1551 1552 if (packet_len != 0) { 1553 printf("\n\t\t\t %d straggler bytes", packet_len); 1554 } 1555 return (1); 1556 1557 trunc: 1558 fputs("[|isis]", stdout); 1559 return (1); 1560 1561 trunctlv: 1562 printf("\n\t\t\t packet exceeded snapshot"); 1563 return(1); 1564 } 1565 1566 /* 1567 * Verify the checksum. See 8473-1, Appendix C, section C.4. 1568 */ 1569 1570 static int 1571 osi_cksum(register const u_char *p, register u_int len, u_char *off) 1572 { 1573 int32_t c0 = 0, c1 = 0; 1574 1575 if ((off[0] == 0) && (off[1] == 0)) 1576 return 0; 1577 1578 off[0] = off[1] = 0; 1579 while ((int)--len >= 0) { 1580 c0 += *p++; 1581 c0 %= 255; 1582 c1 += c0; 1583 c1 %= 255; 1584 } 1585 return (c0 | c1); 1586 } 1587 1588