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