print-isoclns.c revision 172686
117680Spst/* 217680Spst * Copyright (c) 1992, 1993, 1994, 1995, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2026183Sfenner * 2117680Spst * Original code by Matt Thomas, Digital Equipment Corporation 2256896Sfenner * 2398527Sfenner * Extensively modified by Hannes Gredler (hannes@juniper.net) for more 24146778Ssam * complete IS-IS & CLNP support. 2598527Sfenner * 2656896Sfenner * $FreeBSD: head/contrib/tcpdump/print-isoclns.c 172686 2007-10-16 02:31:48Z mlaier $ 2717680Spst */ 2817680Spst 2917680Spst#ifndef lint 30127675Sbmsstatic const char rcsid[] _U_ = 31172686Smlaier "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.133.2.25 2007/03/02 09:20:27 hannes Exp $ (LBL)"; 3217680Spst#endif 3317680Spst 3456896Sfenner#ifdef HAVE_CONFIG_H 3556896Sfenner#include "config.h" 3656896Sfenner#endif 3756896Sfenner 38127675Sbms#include <tcpdump-stdinc.h> 3917680Spst 4017680Spst#include <stdio.h> 4198527Sfenner#include <string.h> 4217680Spst 4317680Spst#include "interface.h" 4417680Spst#include "addrtoname.h" 4517680Spst#include "ethertype.h" 4675118Sfenner#include "ether.h" 47146778Ssam#include "nlpid.h" 4817688Spst#include "extract.h" 49127675Sbms#include "gmpls.h" 50146778Ssam#include "oui.h" 5117680Spst 52127675Sbms#define IPV4 1 /* AFI value */ 53127675Sbms#define IPV6 2 /* AFI value */ 54127675Sbms 5532149Spst/* 5632149Spst * IS-IS is defined in ISO 10589. Look there for protocol definitions. 5732149Spst */ 5832149Spst 5975118Sfenner#define SYSTEM_ID_LEN ETHER_ADDR_LEN 60127675Sbms#define NODE_ID_LEN SYSTEM_ID_LEN+1 61127675Sbms#define LSP_ID_LEN SYSTEM_ID_LEN+2 62127675Sbms 6332149Spst#define ISIS_VERSION 1 64146778Ssam#define ESIS_VERSION 1 65146778Ssam#define CLNP_VERSION 1 6632149Spst 67146778Ssam#define ISIS_PDU_TYPE_MASK 0x1F 68146778Ssam#define ESIS_PDU_TYPE_MASK 0x1F 69146778Ssam#define CLNP_PDU_TYPE_MASK 0x1F 70146778Ssam#define CLNP_FLAG_MASK 0xE0 71146778Ssam#define ISIS_LAN_PRIORITY_MASK 0x7F 7232149Spst 73146778Ssam#define ISIS_PDU_L1_LAN_IIH 15 74146778Ssam#define ISIS_PDU_L2_LAN_IIH 16 75146778Ssam#define ISIS_PDU_PTP_IIH 17 76146778Ssam#define ISIS_PDU_L1_LSP 18 77146778Ssam#define ISIS_PDU_L2_LSP 20 78146778Ssam#define ISIS_PDU_L1_CSNP 24 79146778Ssam#define ISIS_PDU_L2_CSNP 25 80146778Ssam#define ISIS_PDU_L1_PSNP 26 81146778Ssam#define ISIS_PDU_L2_PSNP 27 82146778Ssam 83127675Sbmsstatic struct tok isis_pdu_values[] = { 84146778Ssam { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"}, 85146778Ssam { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"}, 86146778Ssam { ISIS_PDU_PTP_IIH, "p2p IIH"}, 87146778Ssam { ISIS_PDU_L1_LSP, "L1 LSP"}, 88146778Ssam { ISIS_PDU_L2_LSP, "L2 LSP"}, 89146778Ssam { ISIS_PDU_L1_CSNP, "L1 CSNP"}, 90146778Ssam { ISIS_PDU_L2_CSNP, "L2 CSNP"}, 91146778Ssam { ISIS_PDU_L1_PSNP, "L1 PSNP"}, 92146778Ssam { ISIS_PDU_L2_PSNP, "L2 PSNP"}, 93127675Sbms { 0, NULL} 94127675Sbms}; 9598527Sfenner 9632149Spst/* 9732149Spst * A TLV is a tuple of a type, length and a value and is normally used for 9832149Spst * encoding information in all sorts of places. This is an enumeration of 9932149Spst * the well known types. 100127675Sbms * 101127675Sbms * list taken from rfc3359 plus some memory from veterans ;-) 10232149Spst */ 10332149Spst 104146778Ssam#define ISIS_TLV_AREA_ADDR 1 /* iso10589 */ 105146778Ssam#define ISIS_TLV_IS_REACH 2 /* iso10589 */ 106146778Ssam#define ISIS_TLV_ESNEIGH 3 /* iso10589 */ 107146778Ssam#define ISIS_TLV_PART_DIS 4 /* iso10589 */ 108146778Ssam#define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ 109146778Ssam#define ISIS_TLV_ISNEIGH 6 /* iso10589 */ 110146778Ssam#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */ 111146778Ssam#define ISIS_TLV_PADDING 8 /* iso10589 */ 112146778Ssam#define ISIS_TLV_LSP 9 /* iso10589 */ 113146778Ssam#define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ 114146778Ssam#define ISIS_TLV_CHECKSUM 12 /* rfc3358 */ 115162021Ssam#define ISIS_TLV_CHECKSUM_MINLEN 2 116146778Ssam#define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ 117162021Ssam#define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2 118146778Ssam#define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ 119146778Ssam#define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ 120146778Ssam#define ISIS_TLV_DECNET_PHASE4 42 121146778Ssam#define ISIS_TLV_LUCENT_PRIVATE 66 122146778Ssam#define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ 123146778Ssam#define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */ 124146778Ssam#define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ 125146778Ssam#define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */ 126162021Ssam#define ISIS_TLV_IDRP_INFO_MINLEN 1 127146778Ssam#define ISIS_TLV_IPADDR 132 /* rfc1195 */ 128146778Ssam#define ISIS_TLV_IPAUTH 133 /* rfc1195 */ 129146778Ssam#define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ 130146778Ssam#define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ 131146778Ssam#define ISIS_TLV_HOSTNAME 137 /* rfc2763 */ 132146778Ssam#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ 133146778Ssam#define ISIS_TLV_NORTEL_PRIVATE1 176 134146778Ssam#define ISIS_TLV_NORTEL_PRIVATE2 177 135147904Ssam#define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */ 136162021Ssam#define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1 137162021Ssam#define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2 138146778Ssam#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ 139146778Ssam#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ 140162021Ssam#define ISIS_TLV_MT_SUPPORTED_MINLEN 2 141146778Ssam#define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ 142146778Ssam#define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ 143146778Ssam#define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ 144146778Ssam#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ 145146778Ssam#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ 146146778Ssam#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ 147162021Ssam#define ISIS_TLV_IIH_SEQNR_MINLEN 4 148146778Ssam#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ 149162021Ssam#define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 15032149Spst 151127675Sbmsstatic struct tok isis_tlv_values[] = { 152146778Ssam { ISIS_TLV_AREA_ADDR, "Area address(es)"}, 153146778Ssam { ISIS_TLV_IS_REACH, "IS Reachability"}, 154146778Ssam { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"}, 155146778Ssam { ISIS_TLV_PART_DIS, "Partition DIS"}, 156146778Ssam { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, 157146778Ssam { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, 158146778Ssam { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, 159146778Ssam { ISIS_TLV_PADDING, "Padding"}, 160146778Ssam { ISIS_TLV_LSP, "LSP entries"}, 161146778Ssam { ISIS_TLV_AUTH, "Authentication"}, 162146778Ssam { ISIS_TLV_CHECKSUM, "Checksum"}, 163146778Ssam { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, 164146778Ssam { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"}, 165146778Ssam { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"}, 166146778Ssam { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"}, 167146778Ssam { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, 168146778Ssam { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, 169146778Ssam { ISIS_TLV_PROTOCOLS, "Protocols supported"}, 170146778Ssam { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"}, 171146778Ssam { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"}, 172146778Ssam { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"}, 173146778Ssam { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"}, 174146778Ssam { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, 175146778Ssam { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, 176146778Ssam { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, 177146778Ssam { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, 178146778Ssam { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, 179146778Ssam { ISIS_TLV_HOSTNAME, "Hostname"}, 180146778Ssam { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"}, 181146778Ssam { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, 182146778Ssam { ISIS_TLV_MT_SUPPORTED, "Multi Topology"}, 183146778Ssam { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"}, 184146778Ssam { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, 185146778Ssam { ISIS_TLV_IP6_REACH, "IPv6 reachability"}, 186146778Ssam { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, 187146778Ssam { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, 188146778Ssam { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, 189146778Ssam { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, 190127675Sbms { 0, NULL } 191127675Sbms}; 19298527Sfenner 193146778Ssam#define ESIS_OPTION_PROTOCOLS 129 194146778Ssam#define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */ 195146778Ssam#define ESIS_OPTION_SECURITY 197 /* iso9542 */ 196146778Ssam#define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */ 197146778Ssam#define ESIS_OPTION_PRIORITY 205 /* iso9542 */ 198146778Ssam#define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */ 199146778Ssam#define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */ 20098527Sfenner 201146778Ssamstatic struct tok esis_option_values[] = { 202146778Ssam { ESIS_OPTION_PROTOCOLS, "Protocols supported"}, 203146778Ssam { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" }, 204146778Ssam { ESIS_OPTION_SECURITY, "Security" }, 205146778Ssam { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" }, 206146778Ssam { ESIS_OPTION_PRIORITY, "Priority" }, 207146778Ssam { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" }, 208146778Ssam { ESIS_OPTION_SNPA_MASK, "SNPA Mask" }, 209146778Ssam { 0, NULL } 210146778Ssam}; 211146778Ssam 212146778Ssam#define CLNP_OPTION_DISCARD_REASON 193 213146778Ssam#define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */ 214147904Ssam#define CLNP_OPTION_SECURITY 197 /* iso8473 */ 215147904Ssam#define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */ 216147904Ssam#define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */ 217147904Ssam#define CLNP_OPTION_PADDING 204 /* iso8473 */ 218146778Ssam#define CLNP_OPTION_PRIORITY 205 /* iso8473 */ 219146778Ssam 220146778Ssamstatic struct tok clnp_option_values[] = { 221146778Ssam { CLNP_OPTION_DISCARD_REASON, "Discard Reason"}, 222146778Ssam { CLNP_OPTION_PRIORITY, "Priority"}, 223146778Ssam { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"}, 224147904Ssam { CLNP_OPTION_SECURITY, "Security"}, 225147904Ssam { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"}, 226147904Ssam { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"}, 227147904Ssam { CLNP_OPTION_PADDING, "Padding"}, 228146778Ssam { 0, NULL } 229146778Ssam}; 230146778Ssam 231146778Ssamstatic struct tok clnp_option_rfd_class_values[] = { 232146778Ssam { 0x0, "General"}, 233146778Ssam { 0x8, "Address"}, 234146778Ssam { 0x9, "Source Routeing"}, 235146778Ssam { 0xa, "Lifetime"}, 236146778Ssam { 0xb, "PDU Discarded"}, 237146778Ssam { 0xc, "Reassembly"}, 238146778Ssam { 0, NULL } 239146778Ssam}; 240146778Ssam 241146778Ssamstatic struct tok clnp_option_rfd_general_values[] = { 242146778Ssam { 0x0, "Reason not specified"}, 243146778Ssam { 0x1, "Protocol procedure error"}, 244146778Ssam { 0x2, "Incorrect checksum"}, 245146778Ssam { 0x3, "PDU discarded due to congestion"}, 246146778Ssam { 0x4, "Header syntax error (cannot be parsed)"}, 247146778Ssam { 0x5, "Segmentation needed but not permitted"}, 248146778Ssam { 0x6, "Incomplete PDU received"}, 249146778Ssam { 0x7, "Duplicate option"}, 250146778Ssam { 0, NULL } 251146778Ssam}; 252146778Ssam 253146778Ssamstatic struct tok clnp_option_rfd_address_values[] = { 254146778Ssam { 0x0, "Destination address unreachable"}, 255146778Ssam { 0x1, "Destination address unknown"}, 256146778Ssam { 0, NULL } 257146778Ssam}; 258146778Ssam 259146778Ssamstatic struct tok clnp_option_rfd_source_routeing_values[] = { 260146778Ssam { 0x0, "Unspecified source routeing error"}, 261146778Ssam { 0x1, "Syntax error in source routeing field"}, 262146778Ssam { 0x2, "Unknown address in source routeing field"}, 263146778Ssam { 0x3, "Path not acceptable"}, 264146778Ssam { 0, NULL } 265146778Ssam}; 266146778Ssam 267146778Ssamstatic struct tok clnp_option_rfd_lifetime_values[] = { 268146778Ssam { 0x0, "Lifetime expired while data unit in transit"}, 269146778Ssam { 0x1, "Lifetime expired during reassembly"}, 270146778Ssam { 0, NULL } 271146778Ssam}; 272146778Ssam 273146778Ssamstatic struct tok clnp_option_rfd_pdu_discard_values[] = { 274146778Ssam { 0x0, "Unsupported option not specified"}, 275146778Ssam { 0x1, "Unsupported protocol version"}, 276146778Ssam { 0x2, "Unsupported security option"}, 277146778Ssam { 0x3, "Unsupported source routeing option"}, 278146778Ssam { 0x4, "Unsupported recording of route option"}, 279146778Ssam { 0, NULL } 280146778Ssam}; 281146778Ssam 282146778Ssamstatic struct tok clnp_option_rfd_reassembly_values[] = { 283146778Ssam { 0x0, "Reassembly interference"}, 284146778Ssam { 0, NULL } 285146778Ssam}; 286146778Ssam 287146778Ssam/* array of 16 error-classes */ 288146778Ssamstatic struct tok *clnp_option_rfd_error_class[] = { 289146778Ssam clnp_option_rfd_general_values, 290146778Ssam NULL, 291146778Ssam NULL, 292146778Ssam NULL, 293146778Ssam NULL, 294146778Ssam NULL, 295146778Ssam NULL, 296146778Ssam NULL, 297146778Ssam clnp_option_rfd_address_values, 298146778Ssam clnp_option_rfd_source_routeing_values, 299146778Ssam clnp_option_rfd_lifetime_values, 300146778Ssam clnp_option_rfd_pdu_discard_values, 301146778Ssam clnp_option_rfd_reassembly_values, 302146778Ssam NULL, 303146778Ssam NULL, 304146778Ssam NULL 305146778Ssam}; 306146778Ssam 307147904Ssam#define CLNP_OPTION_OPTION_QOS_MASK 0x3f 308147904Ssam#define CLNP_OPTION_SCOPE_MASK 0xc0 309147904Ssam#define CLNP_OPTION_SCOPE_SA_SPEC 0x40 310147904Ssam#define CLNP_OPTION_SCOPE_DA_SPEC 0x80 311147904Ssam#define CLNP_OPTION_SCOPE_GLOBAL 0xc0 312146778Ssam 313147904Ssamstatic struct tok clnp_option_scope_values[] = { 314147904Ssam { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"}, 315147904Ssam { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"}, 316147904Ssam { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"}, 317147904Ssam { 0, NULL } 318147904Ssam}; 319147904Ssam 320147904Ssamstatic struct tok clnp_option_sr_rr_values[] = { 321147904Ssam { 0x0, "partial"}, 322147904Ssam { 0x1, "complete"}, 323147904Ssam { 0, NULL } 324147904Ssam}; 325147904Ssam 326147904Ssamstatic struct tok clnp_option_sr_rr_string_values[] = { 327147904Ssam { CLNP_OPTION_SOURCE_ROUTING, "source routing"}, 328147904Ssam { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"}, 329147904Ssam { 0, NULL } 330147904Ssam}; 331147904Ssam 332147904Ssamstatic struct tok clnp_option_qos_global_values[] = { 333147904Ssam { 0x20, "reserved"}, 334147904Ssam { 0x10, "sequencing vs. delay"}, 335147904Ssam { 0x08, "congested"}, 336147904Ssam { 0x04, "delay vs. cost"}, 337147904Ssam { 0x02, "error vs. delay"}, 338147904Ssam { 0x01, "error vs. cost"}, 339147904Ssam { 0, NULL } 340147904Ssam}; 341147904Ssam 342146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ 343146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* draft-ietf-isis-gmpls-extensions */ 344146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ 345146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ 346146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ 347146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ 348146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ 349162021Ssam#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */ 350162021Ssam#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */ 351146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ 352146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* draft-ietf-isis-gmpls-extensions */ 353146778Ssam#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* draft-ietf-isis-gmpls-extensions */ 354162021Ssam#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */ 355146778Ssam 356127675Sbmsstatic struct tok isis_ext_is_reach_subtlv_values[] = { 357146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, 358146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, 359146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, 360146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, 361146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, 362146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, 363146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, 364146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, 365146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, 366146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, 367146778Ssam { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, 368162021Ssam { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" }, 369162021Ssam { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" }, 370146778Ssam { 250, "Reserved for cisco specific extensions" }, 371146778Ssam { 251, "Reserved for cisco specific extensions" }, 372146778Ssam { 252, "Reserved for cisco specific extensions" }, 373146778Ssam { 253, "Reserved for cisco specific extensions" }, 374146778Ssam { 254, "Reserved for cisco specific extensions" }, 375146778Ssam { 255, "Reserved for future expansion" }, 376127675Sbms { 0, NULL } 377127675Sbms}; 37898527Sfenner 379146778Ssam#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ 380146778Ssam#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ 381146778Ssam#define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ 382127675Sbms 383127675Sbmsstatic struct tok isis_ext_ip_reach_subtlv_values[] = { 384146778Ssam { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, 385146778Ssam { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, 386146778Ssam { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, 387127675Sbms { 0, NULL } 388127675Sbms}; 389127675Sbms 390146778Ssam#define ISIS_SUBTLV_AUTH_SIMPLE 1 391146778Ssam#define ISIS_SUBTLV_AUTH_MD5 54 392146778Ssam#define ISIS_SUBTLV_AUTH_MD5_LEN 16 393146778Ssam#define ISIS_SUBTLV_AUTH_PRIVATE 255 394127675Sbms 395127675Sbmsstatic struct tok isis_subtlv_auth_values[] = { 396146778Ssam { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"}, 397146778Ssam { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, 398146778Ssam { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, 399127675Sbms { 0, NULL } 400127675Sbms}; 401127675Sbms 402146778Ssam#define ISIS_SUBTLV_IDRP_RES 0 403146778Ssam#define ISIS_SUBTLV_IDRP_LOCAL 1 404146778Ssam#define ISIS_SUBTLV_IDRP_ASN 2 405127675Sbms 406127675Sbmsstatic struct tok isis_subtlv_idrp_values[] = { 407146778Ssam { ISIS_SUBTLV_IDRP_RES, "Reserved"}, 408146778Ssam { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, 409146778Ssam { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"}, 410127675Sbms { 0, NULL} 411127675Sbms}; 412127675Sbms 413146778Ssam#define CLNP_SEGMENT_PART 0x80 414146778Ssam#define CLNP_MORE_SEGMENTS 0x40 415146778Ssam#define CLNP_REQUEST_ER 0x20 416127675Sbms 417146778Ssamstatic struct tok clnp_flag_values[] = { 418146778Ssam { CLNP_SEGMENT_PART, "Segmentation permitted"}, 419146778Ssam { CLNP_MORE_SEGMENTS, "more Segments"}, 420146778Ssam { CLNP_REQUEST_ER, "request Error Report"}, 421146778Ssam { 0, NULL} 422146778Ssam}; 423146778Ssam 42498527Sfenner#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) 42598527Sfenner#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) 42698527Sfenner#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) 42798527Sfenner#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) 42898527Sfenner#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) 42998527Sfenner#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) 43098527Sfenner#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) 43198527Sfenner#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) 43298527Sfenner 433127675Sbms#define ISIS_MASK_MTID(x) ((x)&0x0fff) 434127675Sbms#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) 43598527Sfenner 436127675Sbmsstatic struct tok isis_mt_flag_values[] = { 437127675Sbms { 0x4000, "sub-TLVs present"}, 438127675Sbms { 0x8000, "ATT bit set"}, 439127675Sbms { 0, NULL} 440127675Sbms}; 44198527Sfenner 442127675Sbms#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) 443127675Sbms#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) 44498527Sfenner 445127675Sbms#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) 446127675Sbms#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) 447127675Sbms 44898527Sfenner#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) 44998527Sfenner#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) 45098527Sfenner#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) 45198527Sfenner#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) 45298527Sfenner 453127675Sbms#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) 454127675Sbms 455127675Sbmsstatic struct tok isis_mt_values[] = { 456127675Sbms { 0, "IPv4 unicast"}, 457127675Sbms { 1, "In-Band Management"}, 458127675Sbms { 2, "IPv6 unicast"}, 459127675Sbms { 3, "Multicast"}, 460127675Sbms { 4095, "Development, Experimental or Proprietary"}, 461127675Sbms { 0, NULL } 462127675Sbms}; 463127675Sbms 464127675Sbmsstatic struct tok isis_iih_circuit_type_values[] = { 465127675Sbms { 1, "Level 1 only"}, 466127675Sbms { 2, "Level 2 only"}, 467127675Sbms { 3, "Level 1, Level 2"}, 468127675Sbms { 0, NULL} 469127675Sbms}; 470127675Sbms 47198527Sfenner#define ISIS_LSP_TYPE_UNUSED0 0 47298527Sfenner#define ISIS_LSP_TYPE_LEVEL_1 1 47398527Sfenner#define ISIS_LSP_TYPE_UNUSED2 2 47498527Sfenner#define ISIS_LSP_TYPE_LEVEL_2 3 47598527Sfenner 47698527Sfennerstatic struct tok isis_lsp_istype_values[] = { 477127675Sbms { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, 478127675Sbms { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, 479127675Sbms { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, 480172686Smlaier { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"}, 481127675Sbms { 0, NULL } 48298527Sfenner}; 48398527Sfenner 48432149Spst/* 48532149Spst * Katz's point to point adjacency TLV uses codes to tell us the state of 48632149Spst * the remote adjacency. Enumerate them. 48732149Spst */ 48832149Spst 48932149Spst#define ISIS_PTP_ADJ_UP 0 49032149Spst#define ISIS_PTP_ADJ_INIT 1 49132149Spst#define ISIS_PTP_ADJ_DOWN 2 49232149Spst 49398527Sfennerstatic struct tok isis_ptp_adjancey_values[] = { 494127675Sbms { ISIS_PTP_ADJ_UP, "Up" }, 495127675Sbms { ISIS_PTP_ADJ_INIT, "Initializing" }, 496127675Sbms { ISIS_PTP_ADJ_DOWN, "Down" }, 497127675Sbms { 0, NULL} 49832149Spst}; 49932149Spst 50098527Sfennerstruct isis_tlv_ptp_adj { 501127675Sbms u_int8_t adjacency_state; 502127675Sbms u_int8_t extd_local_circuit_id[4]; 503127675Sbms u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; 504127675Sbms u_int8_t neighbor_extd_local_circuit_id[4]; 50532149Spst}; 50632149Spst 507127675Sbmsstatic int osi_cksum(const u_int8_t *, u_int); 508146778Ssamstatic int clnp_print(const u_int8_t *, u_int); 509127675Sbmsstatic void esis_print(const u_int8_t *, u_int); 510127675Sbmsstatic int isis_print(const u_int8_t *, u_int); 511127675Sbms 512127675Sbmsstruct isis_metric_block { 513127675Sbms u_int8_t metric_default; 514127675Sbms u_int8_t metric_delay; 515127675Sbms u_int8_t metric_expense; 516127675Sbms u_int8_t metric_error; 51798527Sfenner}; 51898527Sfenner 51998527Sfennerstruct isis_tlv_is_reach { 520127675Sbms struct isis_metric_block isis_metric_block; 521127675Sbms u_int8_t neighbor_nodeid[NODE_ID_LEN]; 52298527Sfenner}; 52398527Sfenner 524127675Sbmsstruct isis_tlv_es_reach { 525127675Sbms struct isis_metric_block isis_metric_block; 526127675Sbms u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; 527127675Sbms}; 52898527Sfenner 529127675Sbmsstruct isis_tlv_ip_reach { 530127675Sbms struct isis_metric_block isis_metric_block; 531127675Sbms u_int8_t prefix[4]; 532127675Sbms u_int8_t mask[4]; 533127675Sbms}; 534127675Sbms 535127675Sbmsstatic struct tok isis_is_reach_virtual_values[] = { 536127675Sbms { 0, "IsNotVirtual"}, 537127675Sbms { 1, "IsVirtual"}, 538127675Sbms { 0, NULL } 539127675Sbms}; 540127675Sbms 541127675Sbmsstatic struct tok isis_restart_flag_values[] = { 542127675Sbms { 0x1, "Restart Request"}, 543127675Sbms { 0x2, "Restart Acknowledgement"}, 544147904Ssam { 0x4, "Suppress adjacency advertisement"}, 545127675Sbms { 0, NULL } 546127675Sbms}; 547127675Sbms 54832149Spststruct isis_common_header { 549127675Sbms u_int8_t nlpid; 550127675Sbms u_int8_t fixed_len; 551127675Sbms u_int8_t version; /* Protocol version */ 552127675Sbms u_int8_t id_length; 553127675Sbms u_int8_t pdu_type; /* 3 MSbits are reserved */ 554127675Sbms u_int8_t pdu_version; /* Packet format version */ 555127675Sbms u_int8_t reserved; 556127675Sbms u_int8_t max_area; 55732149Spst}; 55832149Spst 55998527Sfennerstruct isis_iih_lan_header { 560127675Sbms u_int8_t circuit_type; 561127675Sbms u_int8_t source_id[SYSTEM_ID_LEN]; 562127675Sbms u_int8_t holding_time[2]; 563127675Sbms u_int8_t pdu_len[2]; 564127675Sbms u_int8_t priority; 565127675Sbms u_int8_t lan_id[NODE_ID_LEN]; 56632149Spst}; 56798527Sfenner 56898527Sfennerstruct isis_iih_ptp_header { 569127675Sbms u_int8_t circuit_type; 570127675Sbms u_int8_t source_id[SYSTEM_ID_LEN]; 571127675Sbms u_int8_t holding_time[2]; 572127675Sbms u_int8_t pdu_len[2]; 573127675Sbms u_int8_t circuit_id; 57432149Spst}; 57532149Spst 57698527Sfennerstruct isis_lsp_header { 577127675Sbms u_int8_t pdu_len[2]; 578127675Sbms u_int8_t remaining_lifetime[2]; 579127675Sbms u_int8_t lsp_id[LSP_ID_LEN]; 580127675Sbms u_int8_t sequence_number[4]; 581127675Sbms u_int8_t checksum[2]; 582127675Sbms u_int8_t typeblock; 58332149Spst}; 58432149Spst 58598527Sfennerstruct isis_csnp_header { 586127675Sbms u_int8_t pdu_len[2]; 587127675Sbms u_int8_t source_id[NODE_ID_LEN]; 588127675Sbms u_int8_t start_lsp_id[LSP_ID_LEN]; 589127675Sbms u_int8_t end_lsp_id[LSP_ID_LEN]; 59098527Sfenner}; 59132149Spst 59298527Sfennerstruct isis_psnp_header { 593127675Sbms u_int8_t pdu_len[2]; 594127675Sbms u_int8_t source_id[NODE_ID_LEN]; 59598527Sfenner}; 59632149Spst 59798527Sfennerstruct isis_tlv_lsp { 598127675Sbms u_int8_t remaining_lifetime[2]; 599127675Sbms u_int8_t lsp_id[LSP_ID_LEN]; 600127675Sbms u_int8_t sequence_number[4]; 601127675Sbms u_int8_t checksum[2]; 60298527Sfenner}; 603127675Sbms 60498527Sfenner#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) 60598527Sfenner#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) 60698527Sfenner#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) 60798527Sfenner#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) 60898527Sfenner#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) 60998527Sfenner#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) 61032149Spst 611127675Sbmsvoid isoclns_print(const u_int8_t *p, u_int length, u_int caplen) 61217680Spst{ 61398527Sfenner const struct isis_common_header *header; 614127675Sbms 61598527Sfenner header = (const struct isis_common_header *)p; 61632149Spst 617146778Ssam if (caplen <= 1) { /* enough bytes on the wire ? */ 618146778Ssam printf("|OSI"); 619146778Ssam return; 620146778Ssam } 62117680Spst 622146778Ssam if (eflag) 623146778Ssam printf("OSI NLPID %s (0x%02x): ", 624146778Ssam tok2str(nlpid_values,"Unknown",*p), 625146778Ssam *p); 626146778Ssam 62717680Spst switch (*p) { 62817680Spst 629146778Ssam case NLPID_CLNP: 630146778Ssam if (!clnp_print(p, length)) 631146778Ssam print_unknown_data(p,"\n\t",caplen); 63217680Spst break; 63317680Spst 63417688Spst case NLPID_ESIS: 63517680Spst esis_print(p, length); 63617680Spst return; 63717680Spst 63817688Spst case NLPID_ISIS: 63917751Spst if (!isis_print(p, length)) 640127675Sbms print_unknown_data(p,"\n\t",caplen); 64117680Spst break; 64217680Spst 64317688Spst case NLPID_NULLNS: 644147904Ssam (void)printf("%slength: %u", 645147904Ssam eflag ? "" : ", ", 646147904Ssam length); 64717680Spst break; 64817680Spst 649146778Ssam case NLPID_Q933: 650146778Ssam q933_print(p+1, length-1); 651146778Ssam break; 652146778Ssam 653146778Ssam case NLPID_IP: 654146778Ssam ip_print(gndo, p+1, length-1); 655146778Ssam break; 656146778Ssam 657146778Ssam#ifdef INET6 658146778Ssam case NLPID_IP6: 659146778Ssam ip6_print(p+1, length-1); 660146778Ssam break; 661146778Ssam#endif 662146778Ssam 663146778Ssam case NLPID_PPP: 664146778Ssam ppp_print(p+1, length-1); 665146778Ssam break; 666146778Ssam 66717680Spst default: 668146778Ssam if (!eflag) 669146778Ssam printf("OSI NLPID 0x%02x unknown",*p); 670147904Ssam (void)printf("%slength: %u", 671147904Ssam eflag ? "" : ", ", 672147904Ssam length); 67317680Spst if (caplen > 1) 674127675Sbms print_unknown_data(p,"\n\t",caplen); 67517680Spst break; 67617680Spst } 67717680Spst} 67817680Spst 679146778Ssam#define CLNP_PDU_ER 1 680146778Ssam#define CLNP_PDU_DT 28 681146778Ssam#define CLNP_PDU_MD 29 682146778Ssam#define CLNP_PDU_ERQ 30 683146778Ssam#define CLNP_PDU_ERP 31 68417680Spst 685146778Ssamstatic struct tok clnp_pdu_values[] = { 686146778Ssam { CLNP_PDU_ER, "Error Report"}, 687146778Ssam { CLNP_PDU_MD, "MD"}, 688146778Ssam { CLNP_PDU_DT, "Data"}, 689146778Ssam { CLNP_PDU_ERQ, "Echo Request"}, 690146778Ssam { CLNP_PDU_ERP, "Echo Response"}, 691127675Sbms { 0, NULL } 692127675Sbms}; 693127675Sbms 694146778Ssamstruct clnp_header_t { 695146778Ssam u_int8_t nlpid; 696146778Ssam u_int8_t length_indicator; 697146778Ssam u_int8_t version; 698146778Ssam u_int8_t lifetime; /* units of 500ms */ 699146778Ssam u_int8_t type; 700146778Ssam u_int8_t segment_length[2]; 701146778Ssam u_int8_t cksum[2]; 702146778Ssam}; 703146778Ssam 704146778Ssamstruct clnp_segment_header_t { 705146778Ssam u_int8_t data_unit_id[2]; 706146778Ssam u_int8_t segment_offset[2]; 707146778Ssam u_int8_t total_length[2]; 708146778Ssam}; 709146778Ssam 710146778Ssam/* 711146778Ssam * clnp_print 712146778Ssam * Decode CLNP packets. Return 0 on error. 713146778Ssam */ 714146778Ssam 715146778Ssamstatic int clnp_print (const u_int8_t *pptr, u_int length) 716146778Ssam{ 717146778Ssam const u_int8_t *optr,*source_address,*dest_address; 718147904Ssam u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; 719146778Ssam const struct clnp_header_t *clnp_header; 720146778Ssam const struct clnp_segment_header_t *clnp_segment_header; 721146778Ssam u_int8_t rfd_error_major,rfd_error_minor; 722146778Ssam 723146778Ssam clnp_header = (const struct clnp_header_t *) pptr; 724146778Ssam TCHECK(*clnp_header); 725146778Ssam 726146778Ssam li = clnp_header->length_indicator; 727146778Ssam optr = pptr; 728146778Ssam 729146778Ssam if (!eflag) 730146778Ssam printf("CLNP"); 731146778Ssam 732146778Ssam /* 733146778Ssam * Sanity checking of the header. 734146778Ssam */ 735146778Ssam 736146778Ssam if (clnp_header->version != CLNP_VERSION) { 737146778Ssam printf("version %d packet not supported", clnp_header->version); 738146778Ssam return (0); 739146778Ssam } 740146778Ssam 741146778Ssam /* FIXME further header sanity checking */ 742146778Ssam 743146778Ssam clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK; 744146778Ssam clnp_flags = clnp_header->type & CLNP_FLAG_MASK; 745146778Ssam 746146778Ssam pptr += sizeof(struct clnp_header_t); 747146778Ssam li -= sizeof(struct clnp_header_t); 748146778Ssam dest_address_length = *pptr; 749146778Ssam dest_address = pptr + 1; 750146778Ssam 751146778Ssam pptr += (1 + dest_address_length); 752146778Ssam li -= (1 + dest_address_length); 753146778Ssam source_address_length = *pptr; 754146778Ssam source_address = pptr +1; 755146778Ssam 756146778Ssam pptr += (1 + source_address_length); 757146778Ssam li -= (1 + source_address_length); 758146778Ssam 759146778Ssam if (vflag < 1) { 760146778Ssam printf("%s%s > %s, %s, length %u", 761146778Ssam eflag ? "" : ", ", 762146778Ssam isonsap_string(source_address, source_address_length), 763146778Ssam isonsap_string(dest_address, dest_address_length), 764146778Ssam tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), 765146778Ssam length); 766146778Ssam return (1); 767146778Ssam } 768146778Ssam printf("%slength %u",eflag ? "" : ", ",length); 769146778Ssam 770146778Ssam printf("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x ", 771146778Ssam tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type), 772146778Ssam clnp_header->length_indicator, 773146778Ssam clnp_header->version, 774146778Ssam clnp_header->lifetime/2, 775146778Ssam (clnp_header->lifetime%2)*5, 776146778Ssam EXTRACT_16BITS(clnp_header->segment_length), 777146778Ssam EXTRACT_16BITS(clnp_header->cksum)); 778146778Ssam 779146778Ssam /* do not attempt to verify the checksum if it is zero */ 780146778Ssam if (EXTRACT_16BITS(clnp_header->cksum) == 0) 781146778Ssam printf("(unverified)"); 782146778Ssam else printf("(%s)", osi_cksum(optr, clnp_header->length_indicator) ? "incorrect" : "correct"); 783146778Ssam 784146778Ssam printf("\n\tFlags [%s]", 785146778Ssam bittok2str(clnp_flag_values,"none",clnp_flags)); 786146778Ssam 787146778Ssam printf("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", 788146778Ssam source_address_length, 789146778Ssam isonsap_string(source_address, source_address_length), 790146778Ssam dest_address_length, 791146778Ssam isonsap_string(dest_address,dest_address_length)); 792146778Ssam 793146778Ssam if (clnp_flags & CLNP_SEGMENT_PART) { 794146778Ssam clnp_segment_header = (const struct clnp_segment_header_t *) pptr; 795162021Ssam TCHECK(*clnp_segment_header); 796146778Ssam printf("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", 797146778Ssam EXTRACT_16BITS(clnp_segment_header->data_unit_id), 798146778Ssam EXTRACT_16BITS(clnp_segment_header->segment_offset), 799146778Ssam EXTRACT_16BITS(clnp_segment_header->total_length)); 800146778Ssam pptr+=sizeof(const struct clnp_segment_header_t); 801146778Ssam li-=sizeof(const struct clnp_segment_header_t); 802146778Ssam } 803146778Ssam 804146778Ssam /* now walk the options */ 805146778Ssam while (li >= 2) { 806146778Ssam u_int op, opli; 807146778Ssam const u_int8_t *tptr; 808146778Ssam 809147904Ssam TCHECK2(*pptr, 2); 810146778Ssam if (li < 2) { 811146778Ssam printf(", bad opts/li"); 812146778Ssam return (0); 813146778Ssam } 814146778Ssam op = *pptr++; 815146778Ssam opli = *pptr++; 816146778Ssam li -= 2; 817147904Ssam TCHECK2(*pptr, opli); 818146778Ssam if (opli > li) { 819146778Ssam printf(", opt (%d) too long", op); 820146778Ssam return (0); 821146778Ssam } 822146778Ssam li -= opli; 823146778Ssam tptr = pptr; 824147904Ssam tlen = opli; 825146778Ssam 826146778Ssam printf("\n\t %s Option #%u, length %u, value: ", 827146778Ssam tok2str(clnp_option_values,"Unknown",op), 828146778Ssam op, 829146778Ssam opli); 830146778Ssam 831146778Ssam switch (op) { 832146778Ssam 833147904Ssam 834147904Ssam case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */ 835147904Ssam case CLNP_OPTION_SOURCE_ROUTING: 836147904Ssam printf("%s %s", 837147904Ssam tok2str(clnp_option_sr_rr_values,"Unknown",*tptr), 838147904Ssam tok2str(clnp_option_sr_rr_string_values,"Unknown Option %u",op)); 839147904Ssam nsap_offset=*(tptr+1); 840147904Ssam if (nsap_offset == 0) { 841147904Ssam printf(" Bad NSAP offset (0)"); 842147904Ssam break; 843147904Ssam } 844147904Ssam nsap_offset-=1; /* offset to nsap list */ 845147904Ssam if (nsap_offset > tlen) { 846147904Ssam printf(" Bad NSAP offset (past end of option)"); 847147904Ssam break; 848147904Ssam } 849147904Ssam tptr+=nsap_offset; 850147904Ssam tlen-=nsap_offset; 851147904Ssam while (tlen > 0) { 852147904Ssam source_address_length=*tptr; 853147904Ssam if (tlen < source_address_length+1) { 854147904Ssam printf("\n\t NSAP address goes past end of option"); 855147904Ssam break; 856162021Ssam } 857147904Ssam if (source_address_length > 0) { 858147904Ssam source_address=(tptr+1); 859147904Ssam TCHECK2(*source_address, source_address_length); 860147904Ssam printf("\n\t NSAP address (length %u): %s", 861147904Ssam source_address_length, 862147904Ssam isonsap_string(source_address, source_address_length)); 863147904Ssam } 864147904Ssam tlen-=source_address_length+1; 865147904Ssam } 866147904Ssam break; 867147904Ssam 868146778Ssam case CLNP_OPTION_PRIORITY: 869147904Ssam printf("0x%1x", *tptr&0x0f); 870147904Ssam break; 871146778Ssam 872147904Ssam case CLNP_OPTION_QOS_MAINTENANCE: 873147904Ssam printf("\n\t Format Code: %s", 874147904Ssam tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK)); 875147904Ssam 876147904Ssam if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) 877147904Ssam printf("\n\t QoS Flags [%s]", 878147904Ssam bittok2str(clnp_option_qos_global_values, 879147904Ssam "none", 880147904Ssam *tptr&CLNP_OPTION_OPTION_QOS_MASK)); 881147904Ssam break; 882147904Ssam 883147904Ssam case CLNP_OPTION_SECURITY: 884147904Ssam printf("\n\t Format Code: %s, Security-Level %u", 885147904Ssam tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK), 886147904Ssam *(tptr+1)); 887147904Ssam break; 888147904Ssam 889146778Ssam case CLNP_OPTION_DISCARD_REASON: 890146778Ssam rfd_error_major = (*tptr&0xf0) >> 4; 891146778Ssam rfd_error_minor = *tptr&0x0f; 892146778Ssam printf("\n\t Class: %s Error (0x%01x), %s (0x%01x)", 893146778Ssam tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major), 894146778Ssam rfd_error_major, 895146778Ssam tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor), 896146778Ssam rfd_error_minor); 897146778Ssam break; 898146778Ssam 899147904Ssam case CLNP_OPTION_PADDING: 900147904Ssam printf("padding data"); 901147904Ssam break; 902147904Ssam 903146778Ssam /* 904146778Ssam * FIXME those are the defined Options that lack a decoder 905146778Ssam * you are welcome to contribute code ;-) 906146778Ssam */ 907146778Ssam 908146778Ssam default: 909146778Ssam print_unknown_data(tptr,"\n\t ",opli); 910146778Ssam break; 911146778Ssam } 912146778Ssam if (vflag > 1) 913146778Ssam print_unknown_data(pptr,"\n\t ",opli); 914146778Ssam pptr += opli; 915146778Ssam } 916146778Ssam 917146778Ssam switch (clnp_pdu_type) { 918146778Ssam 919146778Ssam case CLNP_PDU_ER: /* fall through */ 920146778Ssam case CLNP_PDU_ERP: 921147904Ssam TCHECK(*pptr); 922146778Ssam if (*(pptr) == NLPID_CLNP) { 923146778Ssam printf("\n\t-----original packet-----\n\t"); 924146778Ssam /* FIXME recursion protection */ 925146778Ssam clnp_print(pptr, length-clnp_header->length_indicator); 926146778Ssam break; 927146778Ssam } 928146778Ssam 929146778Ssam case CLNP_PDU_DT: 930146778Ssam case CLNP_PDU_MD: 931146778Ssam case CLNP_PDU_ERQ: 932146778Ssam 933146778Ssam default: 934146778Ssam /* dump the PDU specific data */ 935146778Ssam if (length-(pptr-optr) > 0) { 936146778Ssam printf("\n\t undecoded non-header data, length %u",length-clnp_header->length_indicator); 937146778Ssam print_unknown_data(pptr,"\n\t ",length-(pptr-optr)); 938146778Ssam } 939146778Ssam } 940146778Ssam 941146778Ssam return (1); 942146778Ssam 943146778Ssam trunc: 944146778Ssam fputs("[|clnp]", stdout); 945146778Ssam return (1); 946146778Ssam 947146778Ssam} 948146778Ssam 949146778Ssam 950146778Ssam#define ESIS_PDU_REDIRECT 6 951146778Ssam#define ESIS_PDU_ESH 2 952146778Ssam#define ESIS_PDU_ISH 4 953146778Ssam 954146778Ssamstatic struct tok esis_pdu_values[] = { 955146778Ssam { ESIS_PDU_REDIRECT, "redirect"}, 956146778Ssam { ESIS_PDU_ESH, "ESH"}, 957146778Ssam { ESIS_PDU_ISH, "ISH"}, 958146778Ssam { 0, NULL } 959146778Ssam}; 960146778Ssam 961146778Ssamstruct esis_header_t { 962146778Ssam u_int8_t nlpid; 963146778Ssam u_int8_t length_indicator; 964127675Sbms u_int8_t version; 965127675Sbms u_int8_t reserved; 966127675Sbms u_int8_t type; 967146778Ssam u_int8_t holdtime[2]; 968127675Sbms u_int8_t cksum[2]; 96917680Spst}; 97017680Spst 97117680Spststatic void 972146778Ssamesis_print(const u_int8_t *pptr, u_int length) 97317680Spst{ 974146778Ssam const u_int8_t *optr; 975146778Ssam u_int li,esis_pdu_type,source_address_length, source_address_number; 976146778Ssam const struct esis_header_t *esis_header; 97717680Spst 978146778Ssam if (!eflag) 979146778Ssam printf("ES-IS"); 980146778Ssam 98198527Sfenner if (length <= 2) { 98217680Spst if (qflag) 983146778Ssam printf("bad pkt!"); 98417680Spst else 985146778Ssam printf("no header at all!"); 98617680Spst return; 98717680Spst } 988146778Ssam 989146778Ssam esis_header = (const struct esis_header_t *) pptr; 990147904Ssam TCHECK(*esis_header); 991146778Ssam li = esis_header->length_indicator; 992146778Ssam optr = pptr; 993146778Ssam 994146778Ssam /* 995146778Ssam * Sanity checking of the header. 996146778Ssam */ 997146778Ssam 998146778Ssam if (esis_header->nlpid != NLPID_ESIS) { 999146778Ssam printf(" nlpid 0x%02x packet not supported", esis_header->nlpid); 1000146778Ssam return; 1001146778Ssam } 1002146778Ssam 1003146778Ssam if (esis_header->version != ESIS_VERSION) { 1004146778Ssam printf(" version %d packet not supported", esis_header->version); 1005146778Ssam return; 1006146778Ssam } 1007146778Ssam 100817680Spst if (li > length) { 1009146778Ssam printf(" length indicator(%d) > PDU size (%d)!", li, length); 1010146778Ssam return; 101117680Spst } 1012146778Ssam 1013146778Ssam if (li < sizeof(struct esis_header_t) + 2) { 1014146778Ssam printf(" length indicator < min PDU size %d:", li); 1015146778Ssam while (--length != 0) 1016146778Ssam printf("%02X", *pptr++); 1017146778Ssam return; 101817680Spst } 101917680Spst 1020146778Ssam esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK; 102117680Spst 1022146778Ssam if (vflag < 1) { 1023146778Ssam printf("%s%s, length %u", 1024146778Ssam eflag ? "" : ", ", 1025146778Ssam tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type), 1026146778Ssam length); 1027146778Ssam return; 1028146778Ssam } else 1029146778Ssam printf("%slength %u\n\t%s (%u)", 1030146778Ssam eflag ? "" : ", ", 1031146778Ssam length, 1032146778Ssam tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type), 1033146778Ssam esis_pdu_type); 103417680Spst 1035146778Ssam printf(", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ); 1036146778Ssam printf(", checksum: 0x%04x ", EXTRACT_16BITS(esis_header->cksum)); 1037146778Ssam /* do not attempt to verify the checksum if it is zero */ 1038146778Ssam if (EXTRACT_16BITS(esis_header->cksum) == 0) 1039146778Ssam printf("(unverified)"); 1040147904Ssam else 1041147904Ssam printf("(%s)", osi_cksum(pptr, li) ? "incorrect" : "correct"); 104217680Spst 1043146778Ssam printf(", holding time: %us, length indicator: %u",EXTRACT_16BITS(esis_header->holdtime),li); 104417680Spst 1045146778Ssam if (vflag > 1) 1046146778Ssam print_unknown_data(optr,"\n\t",sizeof(struct esis_header_t)); 1047146778Ssam 1048146778Ssam pptr += sizeof(struct esis_header_t); 1049146778Ssam li -= sizeof(struct esis_header_t); 1050146778Ssam 1051146778Ssam switch (esis_pdu_type) { 1052146778Ssam case ESIS_PDU_REDIRECT: { 1053147904Ssam const u_int8_t *dst, *snpa, *neta; 1054147904Ssam u_int dstl, snpal, netal; 1055146778Ssam 1056147904Ssam TCHECK(*pptr); 1057147904Ssam if (li < 1) { 1058147904Ssam printf(", bad redirect/li"); 105917680Spst return; 1060147904Ssam } 1061147904Ssam dstl = *pptr; 1062147904Ssam pptr++; 1063147904Ssam li--; 1064147904Ssam TCHECK2(*pptr, dstl); 1065147904Ssam if (li < dstl) { 1066147904Ssam printf(", bad redirect/li"); 106717680Spst return; 1068147904Ssam } 1069147904Ssam dst = pptr; 1070147904Ssam pptr += dstl; 1071147904Ssam li -= dstl; 1072147904Ssam printf("\n\t %s", isonsap_string(dst,dstl)); 1073146778Ssam 1074147904Ssam TCHECK(*pptr); 1075147904Ssam if (li < 1) { 1076147904Ssam printf(", bad redirect/li"); 1077147904Ssam return; 1078147904Ssam } 1079147904Ssam snpal = *pptr; 1080147904Ssam pptr++; 1081147904Ssam li--; 1082147904Ssam TCHECK2(*pptr, snpal); 1083147904Ssam if (li < snpal) { 1084147904Ssam printf(", bad redirect/li"); 1085147904Ssam return; 1086147904Ssam } 1087147904Ssam snpa = pptr; 1088147904Ssam pptr += snpal; 1089147904Ssam li -= snpal; 1090147904Ssam TCHECK(*pptr); 1091147904Ssam if (li < 1) { 1092147904Ssam printf(", bad redirect/li"); 1093147904Ssam return; 1094147904Ssam } 1095147904Ssam netal = *pptr; 1096147904Ssam pptr++; 1097147904Ssam TCHECK2(*pptr, netal); 1098147904Ssam if (li < netal) { 1099147904Ssam printf(", bad redirect/li"); 1100147904Ssam return; 1101147904Ssam } 1102147904Ssam neta = pptr; 1103147904Ssam pptr += netal; 1104147904Ssam li -= netal; 1105147904Ssam 1106147904Ssam if (netal == 0) 1107147904Ssam printf("\n\t %s", etheraddr_string(snpa)); 110817680Spst else 1109147904Ssam printf("\n\t %s", isonsap_string(neta,netal)); 111017680Spst break; 111117680Spst } 1112127675Sbms 1113146778Ssam case ESIS_PDU_ESH: 1114147904Ssam TCHECK(*pptr); 1115147904Ssam if (li < 1) { 1116147904Ssam printf(", bad esh/li"); 1117147904Ssam return; 1118147904Ssam } 1119146778Ssam source_address_number = *pptr; 1120146778Ssam pptr++; 1121146778Ssam li--; 1122127675Sbms 1123146778Ssam printf("\n\t Number of Source Addresses: %u", source_address_number); 1124146778Ssam 1125146778Ssam while (source_address_number > 0) { 1126147904Ssam TCHECK(*pptr); 1127147904Ssam if (li < 1) { 1128147904Ssam printf(", bad esh/li"); 1129147904Ssam return; 1130147904Ssam } 1131146778Ssam source_address_length = *pptr; 1132147904Ssam pptr++; 1133147904Ssam li--; 1134147904Ssam 1135147904Ssam TCHECK2(*pptr, source_address_length); 1136147904Ssam if (li < source_address_length) { 1137147904Ssam printf(", bad esh/li"); 1138147904Ssam return; 1139147904Ssam } 1140146778Ssam printf("\n\t NET (length: %u): %s", 1141146778Ssam source_address_length, 1142147904Ssam isonsap_string(pptr,source_address_length)); 1143147904Ssam pptr += source_address_length; 1144147904Ssam li -= source_address_length; 1145146778Ssam source_address_number--; 1146146778Ssam } 1147146778Ssam 1148146778Ssam break; 1149146778Ssam 1150146778Ssam case ESIS_PDU_ISH: { 1151147904Ssam TCHECK(*pptr); 1152147904Ssam if (li < 1) { 1153147904Ssam printf(", bad ish/li"); 1154147904Ssam return; 1155147904Ssam } 1156146778Ssam source_address_length = *pptr; 1157147904Ssam pptr++; 1158147904Ssam li--; 1159147904Ssam TCHECK2(*pptr, source_address_length); 1160147904Ssam if (li < source_address_length) { 1161147904Ssam printf(", bad ish/li"); 1162147904Ssam return; 1163147904Ssam } 1164147904Ssam printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length)); 1165147904Ssam pptr += source_address_length; 1166147904Ssam li -= source_address_length; 1167146778Ssam break; 116817680Spst } 116917680Spst 117017680Spst default: 1171127675Sbms if (vflag <= 1) { 1172146778Ssam if (pptr < snapend) 1173146778Ssam print_unknown_data(pptr,"\n\t ",snapend-pptr); 1174127675Sbms } 1175127675Sbms return; 117617680Spst } 1177127675Sbms 1178146778Ssam /* now walk the options */ 1179146778Ssam while (li >= 2) { 1180146778Ssam u_int op, opli; 1181146778Ssam const u_int8_t *tptr; 1182146778Ssam 1183147904Ssam TCHECK2(*pptr, 2); 1184146778Ssam if (li < 2) { 1185146778Ssam printf(", bad opts/li"); 1186146778Ssam return; 1187146778Ssam } 1188146778Ssam op = *pptr++; 1189146778Ssam opli = *pptr++; 1190146778Ssam li -= 2; 1191146778Ssam if (opli > li) { 1192146778Ssam printf(", opt (%d) too long", op); 1193146778Ssam return; 1194146778Ssam } 1195146778Ssam li -= opli; 1196146778Ssam tptr = pptr; 1197146778Ssam 1198146778Ssam printf("\n\t %s Option #%u, length %u, value: ", 1199146778Ssam tok2str(esis_option_values,"Unknown",op), 1200146778Ssam op, 1201146778Ssam opli); 120217680Spst 1203146778Ssam switch (op) { 1204127675Sbms 1205146778Ssam case ESIS_OPTION_ES_CONF_TIME: 1206147904Ssam TCHECK2(*pptr, 2); 1207146778Ssam printf("%us", EXTRACT_16BITS(tptr)); 1208146778Ssam break; 1209127675Sbms 1210146778Ssam case ESIS_OPTION_PROTOCOLS: 1211146778Ssam while (opli>0) { 1212147904Ssam TCHECK(*pptr); 1213146778Ssam printf("%s (0x%02x)", 1214146778Ssam tok2str(nlpid_values, 1215146778Ssam "unknown", 1216146778Ssam *tptr), 1217146778Ssam *tptr); 1218146778Ssam if (opli>1) /* further NPLIDs ? - put comma */ 1219146778Ssam printf(", "); 1220146778Ssam tptr++; 1221146778Ssam opli--; 1222146778Ssam } 1223146778Ssam break; 1224127675Sbms 1225146778Ssam /* 1226146778Ssam * FIXME those are the defined Options that lack a decoder 1227146778Ssam * you are welcome to contribute code ;-) 1228146778Ssam */ 1229127675Sbms 1230146778Ssam case ESIS_OPTION_QOS_MAINTENANCE: 1231146778Ssam case ESIS_OPTION_SECURITY: 1232146778Ssam case ESIS_OPTION_PRIORITY: 1233146778Ssam case ESIS_OPTION_ADDRESS_MASK: 1234146778Ssam case ESIS_OPTION_SNPA_MASK: 123517680Spst 1236146778Ssam default: 1237146778Ssam print_unknown_data(tptr,"\n\t ",opli); 1238146778Ssam break; 1239146778Ssam } 1240146778Ssam if (vflag > 1) 1241146778Ssam print_unknown_data(pptr,"\n\t ",opli); 1242146778Ssam pptr += opli; 1243146778Ssam } 1244147904Ssamtrunc: 1245147904Ssam return; 1246146778Ssam} 1247146778Ssam 1248127675Sbms/* shared routine for printing system, node and lsp-ids */ 1249127675Sbmsstatic char * 1250127675Sbmsisis_print_id(const u_int8_t *cp, int id_len) 125198527Sfenner{ 1252127675Sbms int i; 1253127675Sbms static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; 1254127675Sbms char *pos = id; 125517688Spst 1256127675Sbms for (i = 1; i <= SYSTEM_ID_LEN; i++) { 1257127675Sbms snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); 1258127675Sbms pos += strlen(pos); 1259127675Sbms if (i == 2 || i == 4) 1260127675Sbms *pos++ = '.'; 126198527Sfenner } 1262127675Sbms if (id_len >= NODE_ID_LEN) { 1263127675Sbms snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); 1264127675Sbms pos += strlen(pos); 1265127675Sbms } 1266127675Sbms if (id_len == LSP_ID_LEN) 1267127675Sbms snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); 1268127675Sbms return (id); 126998527Sfenner} 127098527Sfenner 1271127675Sbms/* print the 4-byte metric block which is common found in the old-style TLVs */ 127298527Sfennerstatic int 1273127675Sbmsisis_print_metric_block (const struct isis_metric_block *isis_metric_block) 127498527Sfenner{ 1275127675Sbms printf(", Default Metric: %d, %s", 1276127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), 1277127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); 1278127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) 1279127675Sbms printf("\n\t\t Delay Metric: %d, %s", 1280127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), 1281127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); 1282127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) 1283127675Sbms printf("\n\t\t Expense Metric: %d, %s", 1284127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), 1285127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); 1286127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) 1287127675Sbms printf("\n\t\t Error Metric: %d, %s", 1288127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), 1289127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); 129098527Sfenner 1291127675Sbms return(1); /* everything is ok */ 129298527Sfenner} 129398527Sfenner 129498527Sfennerstatic int 1295127675Sbmsisis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length) 129698527Sfenner{ 1297127675Sbms int prefix_len; 1298127675Sbms const struct isis_tlv_ip_reach *tlv_ip_reach; 129998527Sfenner 1300127675Sbms tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; 1301127675Sbms 1302127675Sbms while (length > 0) { 1303127675Sbms if ((size_t)length < sizeof(*tlv_ip_reach)) { 1304127675Sbms printf("short IPv4 Reachability (%d vs %lu)", 1305127675Sbms length, 1306127675Sbms (unsigned long)sizeof(*tlv_ip_reach)); 130798527Sfenner return (0); 130898527Sfenner } 1309127675Sbms 1310127675Sbms if (!TTEST(*tlv_ip_reach)) 1311127675Sbms return (0); 1312127675Sbms 1313127675Sbms prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); 1314127675Sbms 1315127675Sbms if (prefix_len == -1) 1316127675Sbms printf("%sIPv4 prefix: %s mask %s", 1317127675Sbms ident, 1318127675Sbms ipaddr_string((tlv_ip_reach->prefix)), 1319127675Sbms ipaddr_string((tlv_ip_reach->mask))); 1320127675Sbms else 1321127675Sbms printf("%sIPv4 prefix: %15s/%u", 1322127675Sbms ident, 1323127675Sbms ipaddr_string((tlv_ip_reach->prefix)), 1324127675Sbms prefix_len); 1325127675Sbms 1326127675Sbms printf(", Distribution: %s, Metric: %u, %s", 1327127675Sbms ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", 1328127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), 1329127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); 1330127675Sbms 1331127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) 1332127675Sbms printf("%s Delay Metric: %u, %s", 1333127675Sbms ident, 1334127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), 1335127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); 1336127675Sbms 1337127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) 1338127675Sbms printf("%s Expense Metric: %u, %s", 1339127675Sbms ident, 1340127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), 1341127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); 1342127675Sbms 1343127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) 1344127675Sbms printf("%s Error Metric: %u, %s", 1345127675Sbms ident, 1346127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), 1347127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); 1348127675Sbms 1349127675Sbms length -= sizeof(struct isis_tlv_ip_reach); 1350127675Sbms tlv_ip_reach++; 135198527Sfenner } 135298527Sfenner return (1); 135398527Sfenner} 135498527Sfenner 1355127675Sbms/* 1356127675Sbms * this is the common IP-REACH subTLV decoder it is called 1357127675Sbms * from various EXTD-IP REACH TLVs (135,235,236,237) 1358127675Sbms */ 135998527Sfenner 1360127675Sbmsstatic int 1361127675Sbmsisis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { 1362127675Sbms 1363127675Sbms /* first lets see if we know the subTLVs name*/ 1364127675Sbms printf("%s%s subTLV #%u, length: %u", 1365127675Sbms ident, 1366127675Sbms tok2str(isis_ext_ip_reach_subtlv_values, 1367127675Sbms "unknown", 1368127675Sbms subt), 1369127675Sbms subt, 1370127675Sbms subl); 1371127675Sbms 1372127675Sbms if (!TTEST2(*tptr,subl)) 1373127675Sbms goto trunctlv; 1374127675Sbms 1375127675Sbms switch(subt) { 1376146778Ssam case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ 1377146778Ssam case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: 1378127675Sbms while (subl >= 4) { 1379127675Sbms printf(", 0x%08x (=%u)", 1380127675Sbms EXTRACT_32BITS(tptr), 1381127675Sbms EXTRACT_32BITS(tptr)); 1382127675Sbms tptr+=4; 1383127675Sbms subl-=4; 138417688Spst } 1385127675Sbms break; 1386146778Ssam case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: 1387127675Sbms while (subl >= 8) { 1388127675Sbms printf(", 0x%08x%08x", 1389127675Sbms EXTRACT_32BITS(tptr), 1390127675Sbms EXTRACT_32BITS(tptr+4)); 1391127675Sbms tptr+=8; 1392127675Sbms subl-=8; 1393127675Sbms } 1394127675Sbms break; 1395127675Sbms default: 1396127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 1397127675Sbms subl)) 1398127675Sbms return(0); 1399127675Sbms break; 1400127675Sbms } 1401127675Sbms return(1); 1402127675Sbms 1403127675Sbmstrunctlv: 1404127675Sbms printf("%spacket exceeded snapshot",ident); 1405127675Sbms return(0); 140698527Sfenner} 140717688Spst 1408127675Sbms/* 1409127675Sbms * this is the common IS-REACH subTLV decoder it is called 1410127675Sbms * from isis_print_ext_is_reach() 1411127675Sbms */ 1412127675Sbms 141398527Sfennerstatic int 1414162021Ssamisis_print_is_reach_subtlv (const u_int8_t *tptr,u_int subt,u_int subl,const char *ident) { 141598527Sfenner 1416162021Ssam u_int te_class,priority_level; 1417127675Sbms union { /* int to float conversion buffer for several subTLVs */ 1418127675Sbms float f; 1419127675Sbms u_int32_t i; 1420127675Sbms } bw; 142198527Sfenner 1422127675Sbms /* first lets see if we know the subTLVs name*/ 1423127675Sbms printf("%s%s subTLV #%u, length: %u", 1424127675Sbms ident, 1425127675Sbms tok2str(isis_ext_is_reach_subtlv_values, 1426127675Sbms "unknown", 1427127675Sbms subt), 1428127675Sbms subt, 1429127675Sbms subl); 143098527Sfenner 1431127675Sbms if (!TTEST2(*tptr,subl)) 1432127675Sbms goto trunctlv; 143398527Sfenner 1434127675Sbms switch(subt) { 1435146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: 1436146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: 1437146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: 1438127675Sbms if (subl >= 4) { 1439127675Sbms printf(", 0x%08x", EXTRACT_32BITS(tptr)); 1440127675Sbms if (subl == 8) /* draft-ietf-isis-gmpls-extensions */ 1441127675Sbms printf(", 0x%08x", EXTRACT_32BITS(tptr+4)); 1442127675Sbms } 1443127675Sbms break; 1444146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: 1445146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: 1446162021Ssam if (subl >= sizeof(struct in_addr)) 1447127675Sbms printf(", %s", ipaddr_string(tptr)); 1448127675Sbms break; 1449146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : 1450146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: 1451127675Sbms if (subl >= 4) { 1452127675Sbms bw.i = EXTRACT_32BITS(tptr); 1453127675Sbms printf(", %.3f Mbps", bw.f*8/1000000 ); 1454127675Sbms } 1455127675Sbms break; 1456146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : 1457127675Sbms if (subl >= 32) { 1458162021Ssam for (te_class = 0; te_class < 8; te_class++) { 1459127675Sbms bw.i = EXTRACT_32BITS(tptr); 1460162021Ssam printf("%s TE-Class %u: %.3f Mbps", 1461127675Sbms ident, 1462162021Ssam te_class, 1463127675Sbms bw.f*8/1000000 ); 1464127675Sbms tptr+=4; 1465127675Sbms } 1466127675Sbms } 1467127675Sbms break; 1468162021Ssam case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ 1469162021Ssam case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: 1470146778Ssam printf("%sBandwidth Constraints Model ID: %s (%u)", 1471146778Ssam ident, 1472146778Ssam tok2str(diffserv_te_bc_values, "unknown", *tptr), 1473146778Ssam *tptr); 1474146778Ssam tptr++; 1475146778Ssam /* decode BCs until the subTLV ends */ 1476162021Ssam for (te_class = 0; te_class < (subl-1)/4; te_class++) { 1477146778Ssam bw.i = EXTRACT_32BITS(tptr); 1478162021Ssam printf("%s Bandwidth constraint CT%u: %.3f Mbps", 1479146778Ssam ident, 1480162021Ssam te_class, 1481146778Ssam bw.f*8/1000000 ); 1482146778Ssam tptr+=4; 1483146778Ssam } 1484146778Ssam break; 1485146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: 1486127675Sbms if (subl >= 3) 1487127675Sbms printf(", %u", EXTRACT_24BITS(tptr)); 1488127675Sbms break; 1489146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: 1490127675Sbms if (subl >= 2) { 1491127675Sbms printf(", %s, Priority %u", 1492127675Sbms bittok2str(gmpls_link_prot_values, "none", *tptr), 1493127675Sbms *(tptr+1)); 1494127675Sbms } 1495127675Sbms break; 1496146778Ssam case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: 1497127675Sbms if (subl >= 36) { 1498127675Sbms printf("%s Interface Switching Capability:%s", 1499127675Sbms ident, 1500127675Sbms tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); 1501127675Sbms printf(", LSP Encoding: %s", 1502127675Sbms tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); 1503127675Sbms tptr+=4; 1504127675Sbms printf("%s Max LSP Bandwidth:",ident); 1505127675Sbms for (priority_level = 0; priority_level < 8; priority_level++) { 1506127675Sbms bw.i = EXTRACT_32BITS(tptr); 1507127675Sbms printf("%s priority level %d: %.3f Mbps", 1508127675Sbms ident, 1509127675Sbms priority_level, 1510127675Sbms bw.f*8/1000000 ); 1511127675Sbms tptr+=4; 1512127675Sbms } 1513127675Sbms subl-=36; 1514127675Sbms /* there is some optional stuff left to decode but this is as of yet 1515127675Sbms not specified so just lets hexdump what is left */ 1516127675Sbms if(subl>0){ 1517127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 1518147904Ssam subl)) 1519127675Sbms return(0); 1520127675Sbms } 1521127675Sbms } 1522127675Sbms break; 1523127675Sbms default: 1524127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 1525127675Sbms subl)) 1526127675Sbms return(0); 1527127675Sbms break; 1528127675Sbms } 1529127675Sbms return(1); 153098527Sfenner 1531127675Sbmstrunctlv: 1532127675Sbms printf("%spacket exceeded snapshot",ident); 1533127675Sbms return(0); 1534127675Sbms} 153598527Sfenner 153698527Sfenner 1537127675Sbms/* 1538127675Sbms * this is the common IS-REACH decoder it is called 1539127675Sbms * from various EXTD-IS REACH style TLVs (22,24,222) 1540127675Sbms */ 154198527Sfenner 1542127675Sbmsstatic int 1543127675Sbmsisis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) { 154498527Sfenner 1545127675Sbms char ident_buffer[20]; 1546127675Sbms int subtlv_type,subtlv_len,subtlv_sum_len; 1547127675Sbms int proc_bytes = 0; /* how many bytes did we process ? */ 1548127675Sbms 1549127675Sbms if (!TTEST2(*tptr, NODE_ID_LEN)) 1550127675Sbms return(0); 155198527Sfenner 1552127675Sbms printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)); 1553127675Sbms tptr+=(NODE_ID_LEN); 155498527Sfenner 1555146778Ssam if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ 1556127675Sbms if (!TTEST2(*tptr, 3)) /* and is therefore skipped */ 1557127675Sbms return(0); 1558127675Sbms printf(", Metric: %d",EXTRACT_24BITS(tptr)); 1559127675Sbms tptr+=3; 1560127675Sbms } 1561127675Sbms 1562127675Sbms if (!TTEST2(*tptr, 1)) 1563127675Sbms return(0); 1564127675Sbms subtlv_sum_len=*(tptr++); /* read out subTLV length */ 1565127675Sbms proc_bytes=NODE_ID_LEN+3+1; 1566127675Sbms printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); 1567127675Sbms if (subtlv_sum_len) { 1568127675Sbms printf(" (%u)",subtlv_sum_len); 1569127675Sbms while (subtlv_sum_len>0) { 1570127675Sbms if (!TTEST2(*tptr,2)) 1571127675Sbms return(0); 1572127675Sbms subtlv_type=*(tptr++); 1573127675Sbms subtlv_len=*(tptr++); 1574127675Sbms /* prepend the ident string */ 1575127675Sbms snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 1576127675Sbms if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer)) 1577127675Sbms return(0); 1578127675Sbms tptr+=subtlv_len; 1579127675Sbms subtlv_sum_len-=(subtlv_len+2); 1580127675Sbms proc_bytes+=(subtlv_len+2); 1581127675Sbms } 1582127675Sbms } 1583127675Sbms return(proc_bytes); 158417688Spst} 158517688Spst 158617688Spst/* 1587127675Sbms * this is the common Multi Topology ID decoder 1588127675Sbms * it is called from various MT-TLVs (222,229,235,237) 1589127675Sbms */ 1590127675Sbms 1591127675Sbmsstatic int 1592127675Sbmsisis_print_mtid (const u_int8_t *tptr,const char *ident) { 1593127675Sbms 1594127675Sbms if (!TTEST2(*tptr, 2)) 1595127675Sbms return(0); 1596127675Sbms 1597127675Sbms printf("%s%s", 1598127675Sbms ident, 1599127675Sbms tok2str(isis_mt_values, 1600127675Sbms "Reserved for IETF Consensus", 1601127675Sbms ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))); 1602127675Sbms 1603127675Sbms printf(" Topology (0x%03x), Flags: [%s]", 1604127675Sbms ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), 1605127675Sbms bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))); 1606127675Sbms 1607127675Sbms return(2); 1608127675Sbms} 1609127675Sbms 1610127675Sbms/* 1611127675Sbms * this is the common extended IP reach decoder 1612127675Sbms * it is called from TLVs (135,235,236,237) 1613127675Sbms * we process the TLV and optional subTLVs and return 1614127675Sbms * the amount of processed bytes 1615127675Sbms */ 1616127675Sbms 1617127675Sbmsstatic int 1618127675Sbmsisis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) { 1619127675Sbms 1620127675Sbms char ident_buffer[20]; 1621172686Smlaier#ifdef INET6 1622162021Ssam u_int8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ 1623172686Smlaier#else 1624172686Smlaier u_int8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */ 1625172686Smlaier#endif 1626127675Sbms u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; 1627127675Sbms 1628127675Sbms if (!TTEST2(*tptr, 4)) 1629127675Sbms return (0); 1630127675Sbms metric = EXTRACT_32BITS(tptr); 1631127675Sbms processed=4; 1632127675Sbms tptr+=4; 1633127675Sbms 1634127675Sbms if (afi == IPV4) { 1635127675Sbms if (!TTEST2(*tptr, 1)) /* fetch status byte */ 1636127675Sbms return (0); 1637127675Sbms status_byte=*(tptr++); 1638127675Sbms bit_length = status_byte&0x3f; 1639172686Smlaier if (bit_length > 32) { 1640172686Smlaier printf("%sIPv4 prefix: bad bit length %u", 1641172686Smlaier ident, 1642172686Smlaier bit_length); 1643172686Smlaier return (0); 1644172686Smlaier } 1645127675Sbms processed++; 1646127675Sbms#ifdef INET6 1647127675Sbms } else if (afi == IPV6) { 1648127675Sbms if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ 1649127675Sbms return (0); 1650127675Sbms status_byte=*(tptr++); 1651127675Sbms bit_length=*(tptr++); 1652172686Smlaier if (bit_length > 128) { 1653172686Smlaier printf("%sIPv6 prefix: bad bit length %u", 1654172686Smlaier ident, 1655172686Smlaier bit_length); 1656172686Smlaier return (0); 1657172686Smlaier } 1658127675Sbms processed+=2; 1659127675Sbms#endif 1660127675Sbms } else 1661127675Sbms return (0); /* somebody is fooling us */ 1662127675Sbms 1663127675Sbms byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ 1664127675Sbms 1665127675Sbms if (!TTEST2(*tptr, byte_length)) 1666127675Sbms return (0); 1667172686Smlaier memset(prefix, 0, sizeof prefix); /* clear the copy buffer */ 1668127675Sbms memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ 1669127675Sbms tptr+=byte_length; 1670127675Sbms processed+=byte_length; 1671127675Sbms 1672127675Sbms if (afi == IPV4) 1673127675Sbms printf("%sIPv4 prefix: %15s/%u", 1674127675Sbms ident, 1675127675Sbms ipaddr_string(prefix), 1676127675Sbms bit_length); 1677127675Sbms#ifdef INET6 1678127675Sbms if (afi == IPV6) 1679127675Sbms printf("%sIPv6 prefix: %s/%u", 1680127675Sbms ident, 1681127675Sbms ip6addr_string(prefix), 1682127675Sbms bit_length); 1683127675Sbms#endif 1684127675Sbms 1685127675Sbms printf(", Distribution: %s, Metric: %u", 1686127675Sbms ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", 1687127675Sbms metric); 1688127675Sbms 1689127675Sbms if (afi == IPV4 && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) 1690127675Sbms printf(", sub-TLVs present"); 1691127675Sbms#ifdef INET6 1692127675Sbms if (afi == IPV6) 1693127675Sbms printf(", %s%s", 1694127675Sbms ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", 1695127675Sbms ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); 1696127675Sbms#endif 1697127675Sbms 1698127675Sbms if ((ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte) && afi == IPV4) || 1699127675Sbms (ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) && afi == IPV6)) { 1700127675Sbms /* assume that one prefix can hold more 1701127675Sbms than one subTLV - therefore the first byte must reflect 1702127675Sbms the aggregate bytecount of the subTLVs for this prefix 1703127675Sbms */ 1704127675Sbms if (!TTEST2(*tptr, 1)) 1705127675Sbms return (0); 1706127675Sbms sublen=*(tptr++); 1707127675Sbms processed+=sublen+1; 1708127675Sbms printf(" (%u)",sublen); /* print out subTLV length */ 1709127675Sbms 1710127675Sbms while (sublen>0) { 1711127675Sbms if (!TTEST2(*tptr,2)) 1712127675Sbms return (0); 1713127675Sbms subtlvtype=*(tptr++); 1714127675Sbms subtlvlen=*(tptr++); 1715127675Sbms /* prepend the ident string */ 1716127675Sbms snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 1717127675Sbms if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer)) 1718127675Sbms return(0); 1719127675Sbms tptr+=subtlvlen; 1720127675Sbms sublen-=(subtlvlen+2); 1721127675Sbms } 1722127675Sbms } 1723127675Sbms return (processed); 1724127675Sbms} 1725127675Sbms 1726127675Sbms/* 172717688Spst * isis_print 172817688Spst * Decode IS-IS packets. Return 0 on error. 172917688Spst */ 173017688Spst 1731127675Sbmsstatic int isis_print (const u_int8_t *p, u_int length) 173217688Spst{ 1733146778Ssam const struct isis_common_header *isis_header; 173417688Spst 173598527Sfenner const struct isis_iih_lan_header *header_iih_lan; 173698527Sfenner const struct isis_iih_ptp_header *header_iih_ptp; 173798527Sfenner const struct isis_lsp_header *header_lsp; 173898527Sfenner const struct isis_csnp_header *header_csnp; 173998527Sfenner const struct isis_psnp_header *header_psnp; 174017688Spst 174198527Sfenner const struct isis_tlv_lsp *tlv_lsp; 174298527Sfenner const struct isis_tlv_ptp_adj *tlv_ptp_adj; 174398527Sfenner const struct isis_tlv_is_reach *tlv_is_reach; 1744127675Sbms const struct isis_tlv_es_reach *tlv_es_reach; 174598527Sfenner 1746127675Sbms u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; 1747127675Sbms u_int8_t ext_is_len, ext_ip_len, mt_len; 1748127675Sbms const u_int8_t *optr, *pptr, *tptr; 174998527Sfenner u_short packet_len,pdu_len; 1750146778Ssam u_int i,vendor_id; 175198527Sfenner 175298527Sfenner packet_len=length; 1753127675Sbms optr = p; /* initialize the _o_riginal pointer to the packet start - 1754127675Sbms need it for parsing the checksum TLV */ 1755146778Ssam isis_header = (const struct isis_common_header *)p; 1756146778Ssam TCHECK(*isis_header); 1757127675Sbms pptr = p+(ISIS_COMMON_HEADER_SIZE); 175898527Sfenner header_iih_lan = (const struct isis_iih_lan_header *)pptr; 175998527Sfenner header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; 176098527Sfenner header_lsp = (const struct isis_lsp_header *)pptr; 176198527Sfenner header_csnp = (const struct isis_csnp_header *)pptr; 176298527Sfenner header_psnp = (const struct isis_psnp_header *)pptr; 1763127675Sbms 1764146778Ssam if (!eflag) 1765146778Ssam printf("IS-IS"); 1766146778Ssam 176717688Spst /* 176817688Spst * Sanity checking of the header. 176917688Spst */ 177017688Spst 1771146778Ssam if (isis_header->version != ISIS_VERSION) { 1772146778Ssam printf("version %d packet not supported", isis_header->version); 177398527Sfenner return (0); 177417688Spst } 177517688Spst 1776146778Ssam if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) { 1777146778Ssam printf("system ID length of %d is not supported", 1778146778Ssam isis_header->id_length); 177998527Sfenner return (0); 178017688Spst } 1781127675Sbms 1782146778Ssam if (isis_header->pdu_version != ISIS_VERSION) { 1783146778Ssam printf("version %d packet not supported", isis_header->pdu_version); 178498527Sfenner return (0); 178517688Spst } 178617688Spst 1787146778Ssam max_area = isis_header->max_area; 178817688Spst switch(max_area) { 178917688Spst case 0: 1790127675Sbms max_area = 3; /* silly shit */ 179117688Spst break; 179217688Spst case 255: 1793146778Ssam printf("bad packet -- 255 areas"); 179498527Sfenner return (0); 179517688Spst default: 179617688Spst break; 179717688Spst } 179817688Spst 1799146778Ssam id_length = isis_header->id_length; 1800127675Sbms switch(id_length) { 1801127675Sbms case 0: 1802127675Sbms id_length = 6; /* silly shit again */ 1803127675Sbms break; 1804127675Sbms case 1: /* 1-8 are valid sys-ID lenghts */ 1805127675Sbms case 2: 1806127675Sbms case 3: 1807127675Sbms case 4: 1808127675Sbms case 5: 1809127675Sbms case 6: 1810127675Sbms case 7: 1811127675Sbms case 8: 1812127675Sbms break; 1813127675Sbms case 255: 1814127675Sbms id_length = 0; /* entirely useless */ 1815127675Sbms break; 1816127675Sbms default: 1817127675Sbms break; 1818127675Sbms } 1819127675Sbms 1820127675Sbms /* toss any non 6-byte sys-ID len PDUs */ 1821127675Sbms if (id_length != 6 ) { 1822146778Ssam printf("bad packet -- illegal sys-ID length (%u)", id_length); 1823127675Sbms return (0); 1824127675Sbms } 1825127675Sbms 1826146778Ssam pdu_type=isis_header->pdu_type; 1827127675Sbms 1828127675Sbms /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ 1829127675Sbms if (vflag < 1) { 1830146778Ssam printf("%s%s", 1831146778Ssam eflag ? "" : ", ", 1832127675Sbms tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type)); 1833127675Sbms 1834127675Sbms switch (pdu_type) { 1835127675Sbms 1836146778Ssam case ISIS_PDU_L1_LAN_IIH: 1837146778Ssam case ISIS_PDU_L2_LAN_IIH: 1838127675Sbms printf(", src-id %s", 1839127675Sbms isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN)); 1840127675Sbms printf(", lan-id %s, prio %u", 1841127675Sbms isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), 1842127675Sbms header_iih_lan->priority); 1843127675Sbms break; 1844146778Ssam case ISIS_PDU_PTP_IIH: 1845127675Sbms printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN)); 1846127675Sbms break; 1847146778Ssam case ISIS_PDU_L1_LSP: 1848146778Ssam case ISIS_PDU_L2_LSP: 1849127675Sbms printf(", lsp-id %s, seq 0x%08x, lifetime %5us", 1850127675Sbms isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), 1851127675Sbms EXTRACT_32BITS(header_lsp->sequence_number), 1852127675Sbms EXTRACT_16BITS(header_lsp->remaining_lifetime)); 1853127675Sbms break; 1854146778Ssam case ISIS_PDU_L1_CSNP: 1855146778Ssam case ISIS_PDU_L2_CSNP: 1856146778Ssam printf(", src-id %s", isis_print_id(header_csnp->source_id,NODE_ID_LEN)); 1857127675Sbms break; 1858146778Ssam case ISIS_PDU_L1_PSNP: 1859146778Ssam case ISIS_PDU_L2_PSNP: 1860146778Ssam printf(", src-id %s", isis_print_id(header_psnp->source_id,NODE_ID_LEN)); 1861127675Sbms break; 1862127675Sbms 1863127675Sbms } 1864127675Sbms printf(", length %u", length); 1865127675Sbms 1866127675Sbms return(1); 1867127675Sbms } 1868127675Sbms 1869127675Sbms /* ok they seem to want to know everything - lets fully decode it */ 1870146778Ssam printf("%slength %u", eflag ? "" : ", ",length); 1871127675Sbms 1872127675Sbms printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", 1873127675Sbms tok2str(isis_pdu_values, 1874127675Sbms "unknown, type %u", 1875127675Sbms pdu_type), 1876146778Ssam isis_header->fixed_len, 1877146778Ssam isis_header->version, 1878146778Ssam isis_header->pdu_version, 1879127675Sbms id_length, 1880146778Ssam isis_header->id_length, 188198527Sfenner max_area, 1882146778Ssam isis_header->max_area); 1883127675Sbms 1884127675Sbms if (vflag > 1) { 1885127675Sbms if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */ 1886127675Sbms return(0); /* for optionally debugging the common header */ 1887127675Sbms } 1888127675Sbms 188998527Sfenner switch (pdu_type) { 189098527Sfenner 1891146778Ssam case ISIS_PDU_L1_LAN_IIH: 1892146778Ssam case ISIS_PDU_L2_LAN_IIH: 1893146778Ssam if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { 189498527Sfenner printf(", bogus fixed header length %u should be %lu", 1895146778Ssam isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); 189698527Sfenner return (0); 189717688Spst } 189898527Sfenner 189998527Sfenner pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); 190098527Sfenner if (packet_len>pdu_len) { 1901127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1902127675Sbms length=pdu_len; 190398527Sfenner } 190498527Sfenner 190598527Sfenner TCHECK(*header_iih_lan); 1906127675Sbms printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", 1907127675Sbms isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), 1908127675Sbms EXTRACT_16BITS(header_iih_lan->holding_time), 1909127675Sbms tok2str(isis_iih_circuit_type_values, 1910127675Sbms "unknown circuit type 0x%02x", 1911127675Sbms header_iih_lan->circuit_type)); 191298527Sfenner 1913127675Sbms printf("\n\t lan-id: %s, Priority: %u, PDU length: %u", 1914127675Sbms isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), 1915146778Ssam (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, 1916127675Sbms pdu_len); 191798527Sfenner 1918127675Sbms if (vflag > 1) { 1919127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE)) 1920127675Sbms return(0); 1921127675Sbms } 192298527Sfenner 192398527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 192498527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 192517688Spst break; 192698527Sfenner 1927146778Ssam case ISIS_PDU_PTP_IIH: 1928146778Ssam if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { 192998527Sfenner printf(", bogus fixed header length %u should be %lu", 1930146778Ssam isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); 193198527Sfenner return (0); 193217688Spst } 1933127675Sbms 193498527Sfenner pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); 193598527Sfenner if (packet_len>pdu_len) { 1936127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1937127675Sbms length=pdu_len; 193898527Sfenner } 1939127675Sbms 194098527Sfenner TCHECK(*header_iih_ptp); 1941127675Sbms printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", 1942127675Sbms isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), 1943127675Sbms EXTRACT_16BITS(header_iih_ptp->holding_time), 1944127675Sbms tok2str(isis_iih_circuit_type_values, 1945127675Sbms "unknown circuit type 0x%02x", 1946127675Sbms header_iih_ptp->circuit_type)); 194798527Sfenner 1948127675Sbms printf("\n\t circuit-id: 0x%02x, PDU length: %u", 1949127675Sbms header_iih_ptp->circuit_id, 1950127675Sbms pdu_len); 195198527Sfenner 1952127675Sbms if (vflag > 1) { 1953127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE)) 1954127675Sbms return(0); 1955127675Sbms } 195698527Sfenner 195798527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 195898527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 195917688Spst break; 196098527Sfenner 1961146778Ssam case ISIS_PDU_L1_LSP: 1962146778Ssam case ISIS_PDU_L2_LSP: 1963146778Ssam if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { 196498527Sfenner printf(", bogus fixed header length %u should be %lu", 1965146778Ssam isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); 196698527Sfenner return (0); 196798527Sfenner } 1968127675Sbms 196998527Sfenner pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); 197098527Sfenner if (packet_len>pdu_len) { 1971127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1972127675Sbms length=pdu_len; 197398527Sfenner } 197498527Sfenner 197598527Sfenner TCHECK(*header_lsp); 1976127675Sbms printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", 1977127675Sbms isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), 1978127675Sbms EXTRACT_32BITS(header_lsp->sequence_number), 1979127675Sbms EXTRACT_16BITS(header_lsp->remaining_lifetime), 1980127675Sbms EXTRACT_16BITS(header_lsp->checksum)); 198198527Sfenner 1982127675Sbms /* if this is a purge do not attempt to verify the checksum */ 1983127675Sbms if ( EXTRACT_16BITS(header_lsp->remaining_lifetime) == 0 && 1984127675Sbms EXTRACT_16BITS(header_lsp->checksum) == 0) 1985127675Sbms printf(" (purged)"); 1986127675Sbms else 1987127675Sbms /* verify the checksum - 1988127675Sbms * checking starts at the lsp-id field at byte position [12] 1989127675Sbms * hence the length needs to be reduced by 12 bytes */ 1990127675Sbms printf(" (%s)", (osi_cksum((u_int8_t *)header_lsp->lsp_id, length-12)) ? "incorrect" : "correct"); 1991127675Sbms 1992127675Sbms printf(", PDU length: %u, Flags: [ %s", 1993127675Sbms pdu_len, 1994127675Sbms ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); 1995127675Sbms 199698527Sfenner if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { 199798527Sfenner printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); 199898527Sfenner printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); 199998527Sfenner printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); 200098527Sfenner printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); 200198527Sfenner printf("ATT bit set, "); 200298527Sfenner } 200398527Sfenner printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); 2004127675Sbms printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); 200598527Sfenner 2006127675Sbms if (vflag > 1) { 2007127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE)) 2008127675Sbms return(0); 2009127675Sbms } 2010127675Sbms 201198527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 201298527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 201317688Spst break; 201498527Sfenner 2015146778Ssam case ISIS_PDU_L1_CSNP: 2016146778Ssam case ISIS_PDU_L2_CSNP: 2017146778Ssam if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { 201898527Sfenner printf(", bogus fixed header length %u should be %lu", 2019146778Ssam isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); 202098527Sfenner return (0); 202198527Sfenner } 2022127675Sbms 202398527Sfenner pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); 202498527Sfenner if (packet_len>pdu_len) { 2025127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 2026127675Sbms length=pdu_len; 202798527Sfenner } 202817688Spst 202998527Sfenner TCHECK(*header_csnp); 2030127675Sbms printf("\n\t source-id: %s, PDU length: %u", 2031127675Sbms isis_print_id(header_csnp->source_id, NODE_ID_LEN), 2032127675Sbms pdu_len); 2033127675Sbms printf("\n\t start lsp-id: %s", 2034127675Sbms isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)); 2035127675Sbms printf("\n\t end lsp-id: %s", 2036127675Sbms isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)); 203717688Spst 2038127675Sbms if (vflag > 1) { 2039127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE)) 2040127675Sbms return(0); 2041127675Sbms } 2042127675Sbms 204398527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 204498527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 204598527Sfenner break; 204617688Spst 2047146778Ssam case ISIS_PDU_L1_PSNP: 2048146778Ssam case ISIS_PDU_L2_PSNP: 2049146778Ssam if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { 205098527Sfenner printf("- bogus fixed header length %u should be %lu", 2051146778Ssam isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); 205298527Sfenner return (0); 205398527Sfenner } 205498527Sfenner 205598527Sfenner pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); 205698527Sfenner if (packet_len>pdu_len) { 2057127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 2058127675Sbms length=pdu_len; 205998527Sfenner } 206098527Sfenner 206198527Sfenner TCHECK(*header_psnp); 2062127675Sbms printf("\n\t source-id: %s, PDU length: %u", 2063127675Sbms isis_print_id(header_psnp->source_id, NODE_ID_LEN), 2064127675Sbms pdu_len); 2065127675Sbms 2066127675Sbms if (vflag > 1) { 2067127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE)) 2068127675Sbms return(0); 2069127675Sbms } 2070127675Sbms 207198527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 207298527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 207317688Spst break; 207417688Spst 207598527Sfenner default: 2076127675Sbms if(!print_unknown_data(pptr,"\n\t ",length)) 2077127675Sbms return(0); 2078127675Sbms return (0); 207917688Spst } 208017688Spst 208117688Spst /* 208217688Spst * Now print the TLV's. 208317688Spst */ 2084127675Sbms 208517688Spst while (packet_len >= 2) { 208698527Sfenner if (pptr == snapend) { 208798527Sfenner return (1); 208898527Sfenner } 208998527Sfenner 209098527Sfenner if (!TTEST2(*pptr, 2)) { 2091127675Sbms printf("\n\t\t packet exceeded snapshot (%ld) bytes", 2092127675Sbms (long)(pptr-snapend)); 209398527Sfenner return (1); 209417688Spst } 2095127675Sbms tlv_type = *pptr++; 2096127675Sbms tlv_len = *pptr++; 2097127675Sbms tmp =tlv_len; /* copy temporary len & pointer to packet data */ 2098127675Sbms tptr = pptr; 209917688Spst packet_len -= 2; 2100127675Sbms if (tlv_len > packet_len) { 210117688Spst break; 210217688Spst } 210317688Spst 2104127675Sbms /* first lets see if we know the TLVs name*/ 2105127675Sbms printf("\n\t %s TLV #%u, length: %u", 2106127675Sbms tok2str(isis_tlv_values, 2107127675Sbms "unknown", 2108127675Sbms tlv_type), 2109127675Sbms tlv_type, 2110127675Sbms tlv_len); 2111127675Sbms 2112147175Ssam if (tlv_len == 0) /* something is malformed */ 2113172686Smlaier continue; 2114147175Ssam 2115127675Sbms /* now check if we have a decoder otherwise do a hexdump at the end*/ 2116127675Sbms switch (tlv_type) { 2117146778Ssam case ISIS_TLV_AREA_ADDR: 211898527Sfenner if (!TTEST2(*tptr, 1)) 211998527Sfenner goto trunctlv; 212017688Spst alen = *tptr++; 212117688Spst while (tmp && alen < tmp) { 2122127675Sbms printf("\n\t Area address (length: %u): %s", 2123127675Sbms alen, 2124146778Ssam isonsap_string(tptr,alen)); 212517688Spst tptr += alen; 212617688Spst tmp -= alen + 1; 212798527Sfenner if (tmp==0) /* if this is the last area address do not attemt a boundary check */ 2128127675Sbms break; 212998527Sfenner if (!TTEST2(*tptr, 1)) 213098527Sfenner goto trunctlv; 213117688Spst alen = *tptr++; 213217688Spst } 213317688Spst break; 2134146778Ssam case ISIS_TLV_ISNEIGH: 213575118Sfenner while (tmp >= ETHER_ADDR_LEN) { 2136127675Sbms if (!TTEST2(*tptr, ETHER_ADDR_LEN)) 2137127675Sbms goto trunctlv; 2138127675Sbms printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN)); 2139127675Sbms tmp -= ETHER_ADDR_LEN; 2140127675Sbms tptr += ETHER_ADDR_LEN; 214117688Spst } 214217688Spst break; 214398527Sfenner 2144146778Ssam case ISIS_TLV_ISNEIGH_VARLEN: 2145147175Ssam if (!TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */ 2146127675Sbms goto trunctlv; 2147147904Ssam lan_alen = *tptr++; /* LAN address length */ 2148147904Ssam if (lan_alen == 0) { 2149147904Ssam printf("\n\t LAN address length 0 bytes (invalid)"); 2150147904Ssam break; 2151147904Ssam } 2152127675Sbms tmp --; 2153127675Sbms printf("\n\t LAN address length %u bytes ",lan_alen); 2154127675Sbms while (tmp >= lan_alen) { 2155127675Sbms if (!TTEST2(*tptr, lan_alen)) 2156127675Sbms goto trunctlv; 2157127675Sbms printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen)); 2158127675Sbms tmp -= lan_alen; 2159127675Sbms tptr +=lan_alen; 2160127675Sbms } 2161127675Sbms break; 2162127675Sbms 2163146778Ssam case ISIS_TLV_PADDING: 216417688Spst break; 216598527Sfenner 2166146778Ssam case ISIS_TLV_MT_IS_REACH: 2167127675Sbms while (tmp >= 2+NODE_ID_LEN+3+1) { 2168127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 2169127675Sbms if (mt_len == 0) /* did something go wrong ? */ 2170127675Sbms goto trunctlv; 2171127675Sbms tptr+=mt_len; 2172127675Sbms tmp-=mt_len; 217398527Sfenner 2174127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 2175127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 217698527Sfenner goto trunctlv; 2177127675Sbms 2178127675Sbms tmp-=ext_is_len; 2179127675Sbms tptr+=ext_is_len; 218098527Sfenner } 218198527Sfenner break; 218298527Sfenner 2183146778Ssam case ISIS_TLV_IS_ALIAS_ID: 2184127675Sbms while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ 2185127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 2186127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 2187127675Sbms goto trunctlv; 2188127675Sbms tmp-=ext_is_len; 2189127675Sbms tptr+=ext_is_len; 2190127675Sbms } 2191127675Sbms break; 2192127675Sbms 2193146778Ssam case ISIS_TLV_EXT_IS_REACH: 2194127675Sbms while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ 2195127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 2196127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 2197127675Sbms goto trunctlv; 2198127675Sbms tmp-=ext_is_len; 2199127675Sbms tptr+=ext_is_len; 220098527Sfenner } 220198527Sfenner break; 2202146778Ssam case ISIS_TLV_IS_REACH: 220398527Sfenner if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ 2204127675Sbms goto trunctlv; 2205127675Sbms printf("\n\t %s", 2206127675Sbms tok2str(isis_is_reach_virtual_values, 2207127675Sbms "bogus virtual flag 0x%02x", 2208127675Sbms *tptr++)); 220998527Sfenner tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; 221098527Sfenner while (tmp >= sizeof(struct isis_tlv_is_reach)) { 221198527Sfenner if (!TTEST(*tlv_is_reach)) 221298527Sfenner goto trunctlv; 2213127675Sbms printf("\n\t IS Neighbor: %s", 2214127675Sbms isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); 2215127675Sbms isis_print_metric_block(&tlv_is_reach->isis_metric_block); 221698527Sfenner tmp -= sizeof(struct isis_tlv_is_reach); 221798527Sfenner tlv_is_reach++; 221898527Sfenner } 221998527Sfenner break; 222098527Sfenner 2221146778Ssam case ISIS_TLV_ESNEIGH: 2222127675Sbms tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; 2223127675Sbms while (tmp >= sizeof(struct isis_tlv_es_reach)) { 2224127675Sbms if (!TTEST(*tlv_es_reach)) 2225127675Sbms goto trunctlv; 2226127675Sbms printf("\n\t ES Neighbor: %s", 2227127675Sbms isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN)); 2228127675Sbms isis_print_metric_block(&tlv_es_reach->isis_metric_block); 2229127675Sbms tmp -= sizeof(struct isis_tlv_es_reach); 2230127675Sbms tlv_es_reach++; 2231127675Sbms } 2232127675Sbms break; 2233127675Sbms 2234127675Sbms /* those two TLVs share the same format */ 2235146778Ssam case ISIS_TLV_INT_IP_REACH: 2236146778Ssam case ISIS_TLV_EXT_IP_REACH: 2237127675Sbms if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len)) 223898527Sfenner return (1); 223917688Spst break; 224098527Sfenner 2241146778Ssam case ISIS_TLV_EXTD_IP_REACH: 2242127675Sbms while (tmp>0) { 2243127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); 2244127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 2245127675Sbms goto trunctlv; 2246127675Sbms tptr+=ext_ip_len; 2247127675Sbms tmp-=ext_ip_len; 2248127675Sbms } 224998527Sfenner break; 225098527Sfenner 2251146778Ssam case ISIS_TLV_MT_IP_REACH: 2252172686Smlaier mt_len = isis_print_mtid(tptr, "\n\t "); 2253172686Smlaier if (mt_len == 0) { /* did something go wrong ? */ 2254172686Smlaier goto trunctlv; 2255172686Smlaier } 2256172686Smlaier tptr+=mt_len; 2257172686Smlaier tmp-=mt_len; 225898527Sfenner 2259172686Smlaier while (tmp>0) { 2260127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); 2261127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 2262127675Sbms goto trunctlv; 2263127675Sbms tptr+=ext_ip_len; 2264127675Sbms tmp-=ext_ip_len; 226598527Sfenner } 226698527Sfenner break; 226798527Sfenner 226898527Sfenner#ifdef INET6 2269146778Ssam case ISIS_TLV_IP6_REACH: 2270127675Sbms while (tmp>0) { 2271127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); 2272127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 2273127675Sbms goto trunctlv; 2274127675Sbms tptr+=ext_ip_len; 2275127675Sbms tmp-=ext_ip_len; 2276127675Sbms } 2277127675Sbms break; 227898527Sfenner 2279146778Ssam case ISIS_TLV_MT_IP6_REACH: 2280172686Smlaier mt_len = isis_print_mtid(tptr, "\n\t "); 2281172686Smlaier if (mt_len == 0) { /* did something go wrong ? */ 2282172686Smlaier goto trunctlv; 2283172686Smlaier } 2284172686Smlaier tptr+=mt_len; 2285172686Smlaier tmp-=mt_len; 2286172686Smlaier 2287127675Sbms while (tmp>0) { 2288127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); 2289127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 2290127675Sbms goto trunctlv; 2291127675Sbms tptr+=ext_ip_len; 2292127675Sbms tmp-=ext_ip_len; 229398527Sfenner } 229498527Sfenner break; 229598527Sfenner 2296146778Ssam case ISIS_TLV_IP6ADDR: 2297162021Ssam while (tmp>=sizeof(struct in6_addr)) { 2298162021Ssam if (!TTEST2(*tptr, sizeof(struct in6_addr))) 229998527Sfenner goto trunctlv; 230098527Sfenner 2301127675Sbms printf("\n\t IPv6 interface address: %s", 230298527Sfenner ip6addr_string(tptr)); 230398527Sfenner 2304162021Ssam tptr += sizeof(struct in6_addr); 2305162021Ssam tmp -= sizeof(struct in6_addr); 230698527Sfenner } 230798527Sfenner break; 230898527Sfenner#endif 2309146778Ssam case ISIS_TLV_AUTH: 2310127675Sbms if (!TTEST2(*tptr, 1)) 231198527Sfenner goto trunctlv; 2312127675Sbms 2313127675Sbms printf("\n\t %s: ", 2314127675Sbms tok2str(isis_subtlv_auth_values, 2315127675Sbms "unknown Authentication type 0x%02x", 2316127675Sbms *tptr)); 2317127675Sbms 2318127675Sbms switch (*tptr) { 2319146778Ssam case ISIS_SUBTLV_AUTH_SIMPLE: 2320127675Sbms for(i=1;i<tlv_len;i++) { 2321127675Sbms if (!TTEST2(*(tptr+i), 1)) 232298527Sfenner goto trunctlv; 2323127675Sbms printf("%c",*(tptr+i)); 232498527Sfenner } 2325127675Sbms break; 2326146778Ssam case ISIS_SUBTLV_AUTH_MD5: 2327127675Sbms for(i=1;i<tlv_len;i++) { 2328127675Sbms if (!TTEST2(*(tptr+i), 1)) 232998527Sfenner goto trunctlv; 2330127675Sbms printf("%02x",*(tptr+i)); 233198527Sfenner } 2332146778Ssam if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1) 2333127675Sbms printf(", (malformed subTLV) "); 2334127675Sbms break; 2335146778Ssam case ISIS_SUBTLV_AUTH_PRIVATE: 2336127675Sbms default: 2337127675Sbms if(!print_unknown_data(tptr+1,"\n\t\t ",tlv_len-1)) 2338127675Sbms return(0); 2339127675Sbms break; 234098527Sfenner } 234198527Sfenner break; 234298527Sfenner 2343146778Ssam case ISIS_TLV_PTP_ADJ: 2344127675Sbms tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr; 2345127675Sbms if(tmp>=1) { 2346127675Sbms if (!TTEST2(*tptr, 1)) 234798527Sfenner goto trunctlv; 2348127675Sbms printf("\n\t Adjacency State: %s (%u)", 2349127675Sbms tok2str(isis_ptp_adjancey_values, "unknown", *tptr), 2350127675Sbms *tptr); 2351127675Sbms tmp--; 235298527Sfenner } 2353127675Sbms if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { 2354127675Sbms if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id, 2355127675Sbms sizeof(tlv_ptp_adj->extd_local_circuit_id))) 235698527Sfenner goto trunctlv; 2357127675Sbms printf("\n\t Extended Local circuit-ID: 0x%08x", 2358127675Sbms EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)); 2359127675Sbms tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); 236098527Sfenner } 2361127675Sbms if(tmp>=SYSTEM_ID_LEN) { 2362127675Sbms if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) 236398527Sfenner goto trunctlv; 2364127675Sbms printf("\n\t Neighbor System-ID: %s", 2365127675Sbms isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN)); 2366127675Sbms tmp-=SYSTEM_ID_LEN; 236798527Sfenner } 2368127675Sbms if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { 2369127675Sbms if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, 2370127675Sbms sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) 237198527Sfenner goto trunctlv; 2372127675Sbms printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x", 2373127675Sbms EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)); 237498527Sfenner } 237532149Spst break; 237698527Sfenner 2377146778Ssam case ISIS_TLV_PROTOCOLS: 2378127675Sbms printf("\n\t NLPID(s): "); 2379127675Sbms while (tmp>0) { 2380127675Sbms if (!TTEST2(*(tptr), 1)) 238198527Sfenner goto trunctlv; 2382127675Sbms printf("%s (0x%02x)", 2383146778Ssam tok2str(nlpid_values, 2384127675Sbms "unknown", 2385127675Sbms *tptr), 2386127675Sbms *tptr); 2387127675Sbms if (tmp>1) /* further NPLIDs ? - put comma */ 238898527Sfenner printf(", "); 2389127675Sbms tptr++; 2390127675Sbms tmp--; 239198527Sfenner } 239232149Spst break; 239398527Sfenner 2394146778Ssam case ISIS_TLV_TE_ROUTER_ID: 2395162021Ssam if (!TTEST2(*pptr, sizeof(struct in_addr))) 239698527Sfenner goto trunctlv; 2397127675Sbms printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr)); 239898527Sfenner break; 239998527Sfenner 2400146778Ssam case ISIS_TLV_IPADDR: 2401162021Ssam while (tmp>=sizeof(struct in_addr)) { 2402162021Ssam if (!TTEST2(*tptr, sizeof(struct in_addr))) 240398527Sfenner goto trunctlv; 2404127675Sbms printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); 2405162021Ssam tptr += sizeof(struct in_addr); 2406162021Ssam tmp -= sizeof(struct in_addr); 240798527Sfenner } 240832149Spst break; 240998527Sfenner 2410146778Ssam case ISIS_TLV_HOSTNAME: 2411127675Sbms printf("\n\t Hostname: "); 2412127675Sbms while (tmp>0) { 2413127675Sbms if (!TTEST2(*tptr, 1)) 241498527Sfenner goto trunctlv; 2415127675Sbms printf("%c",*tptr++); 2416127675Sbms tmp--; 241798527Sfenner } 241898527Sfenner break; 241998527Sfenner 2420146778Ssam case ISIS_TLV_SHARED_RISK_GROUP: 2421147904Ssam if (tmp < NODE_ID_LEN) 2422147904Ssam break; 2423127675Sbms if (!TTEST2(*tptr, NODE_ID_LEN)) 2424127675Sbms goto trunctlv; 2425127675Sbms printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)); 2426127675Sbms tptr+=(NODE_ID_LEN); 2427127675Sbms tmp-=(NODE_ID_LEN); 2428127675Sbms 2429147904Ssam if (tmp < 1) 2430147904Ssam break; 2431127675Sbms if (!TTEST2(*tptr, 1)) 2432127675Sbms goto trunctlv; 2433127675Sbms printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"); 2434127675Sbms tmp--; 2435127675Sbms 2436162021Ssam if (tmp < sizeof(struct in_addr)) 2437147904Ssam break; 2438162021Ssam if (!TTEST2(*tptr,sizeof(struct in_addr))) 2439127675Sbms goto trunctlv; 2440127675Sbms printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); 2441162021Ssam tptr+=sizeof(struct in_addr); 2442162021Ssam tmp-=sizeof(struct in_addr); 2443127675Sbms 2444162021Ssam if (tmp < sizeof(struct in_addr)) 2445147904Ssam break; 2446162021Ssam if (!TTEST2(*tptr,sizeof(struct in_addr))) 2447127675Sbms goto trunctlv; 2448127675Sbms printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr)); 2449162021Ssam tptr+=sizeof(struct in_addr); 2450162021Ssam tmp-=sizeof(struct in_addr); 2451127675Sbms 2452147904Ssam while (tmp>=4) { 2453127675Sbms if (!TTEST2(*tptr, 4)) 2454127675Sbms goto trunctlv; 2455127675Sbms printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)); 2456127675Sbms tptr+=4; 2457127675Sbms tmp-=4; 2458127675Sbms } 2459127675Sbms break; 2460127675Sbms 2461146778Ssam case ISIS_TLV_LSP: 2462127675Sbms tlv_lsp = (const struct isis_tlv_lsp *)tptr; 2463147904Ssam while(tmp>=sizeof(struct isis_tlv_lsp)) { 2464127675Sbms if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) 246598527Sfenner goto trunctlv; 2466127675Sbms printf("\n\t lsp-id: %s", 2467127675Sbms isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)); 246898527Sfenner if (!TTEST2(tlv_lsp->sequence_number, 4)) 246998527Sfenner goto trunctlv; 2470127675Sbms printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); 247198527Sfenner if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) 247298527Sfenner goto trunctlv; 2473127675Sbms printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); 247498527Sfenner if (!TTEST2(tlv_lsp->checksum, 2)) 247598527Sfenner goto trunctlv; 2476127675Sbms printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); 2477127675Sbms tmp-=sizeof(struct isis_tlv_lsp); 247898527Sfenner tlv_lsp++; 247998527Sfenner } 248098527Sfenner break; 248198527Sfenner 2482146778Ssam case ISIS_TLV_CHECKSUM: 2483162021Ssam if (tmp < ISIS_TLV_CHECKSUM_MINLEN) 2484147904Ssam break; 2485162021Ssam if (!TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN)) 248698527Sfenner goto trunctlv; 2487127675Sbms printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)); 2488127675Sbms /* do not attempt to verify the checksum if it is zero 2489127675Sbms * most likely a HMAC-MD5 TLV is also present and 2490127675Sbms * to avoid conflicts the checksum TLV is zeroed. 2491127675Sbms * see rfc3358 for details 2492127675Sbms */ 2493127675Sbms if (EXTRACT_16BITS(tptr) == 0) 2494127675Sbms printf("(unverified)"); 2495127675Sbms else printf("(%s)", osi_cksum(optr, length) ? "incorrect" : "correct"); 249698527Sfenner break; 249798527Sfenner 2498146778Ssam case ISIS_TLV_MT_SUPPORTED: 2499162021Ssam if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN) 2500162021Ssam break; 2501127675Sbms while (tmp>1) { 2502127675Sbms /* length can only be a multiple of 2, otherwise there is 250398527Sfenner something broken -> so decode down until length is 1 */ 2504127675Sbms if (tmp!=1) { 2505127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 2506127675Sbms if (mt_len == 0) /* did something go wrong ? */ 2507127675Sbms goto trunctlv; 2508127675Sbms tptr+=mt_len; 2509127675Sbms tmp-=mt_len; 251098527Sfenner } else { 2511127675Sbms printf("\n\t malformed MT-ID"); 251298527Sfenner break; 251398527Sfenner } 251498527Sfenner } 251598527Sfenner break; 251698527Sfenner 2517146778Ssam case ISIS_TLV_RESTART_SIGNALING: 2518162021Ssam /* first attempt to decode the flags */ 2519162021Ssam if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) 2520162021Ssam break; 2521162021Ssam if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN)) 2522127675Sbms goto trunctlv; 2523162021Ssam printf("\n\t Flags [%s]", 2524162021Ssam bittok2str(isis_restart_flag_values, "none", *tptr)); 2525162021Ssam tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; 2526162021Ssam tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; 2527162021Ssam 2528162021Ssam /* is there anything other than the flags field? */ 2529162021Ssam if (tmp == 0) 2530162021Ssam break; 2531162021Ssam 2532162021Ssam if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) 2533162021Ssam break; 2534162021Ssam if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)) 2535162021Ssam goto trunctlv; 2536162021Ssam 2537172686Smlaier printf(", Remaining holding time %us", EXTRACT_16BITS(tptr)); 2538162021Ssam tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; 2539162021Ssam tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; 2540162021Ssam 2541162021Ssam /* is there an additional sysid field present ?*/ 2542147904Ssam if (tmp == SYSTEM_ID_LEN) { 2543147904Ssam if (!TTEST2(*tptr, SYSTEM_ID_LEN)) 2544147904Ssam goto trunctlv; 2545147904Ssam printf(", for %s",isis_print_id(tptr,SYSTEM_ID_LEN)); 2546162021Ssam } 254798527Sfenner break; 254898527Sfenner 2549146778Ssam case ISIS_TLV_IDRP_INFO: 2550162021Ssam if (tmp < ISIS_TLV_IDRP_INFO_MINLEN) 2551147904Ssam break; 2552162021Ssam if (!TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN)) 2553127675Sbms goto trunctlv; 2554127675Sbms printf("\n\t Inter-Domain Information Type: %s", 2555127675Sbms tok2str(isis_subtlv_idrp_values, 2556127675Sbms "Unknown (0x%02x)", 2557127675Sbms *tptr)); 2558127675Sbms switch (*tptr++) { 2559146778Ssam case ISIS_SUBTLV_IDRP_ASN: 2560127675Sbms if (!TTEST2(*tptr, 2)) /* fetch AS number */ 2561127675Sbms goto trunctlv; 2562127675Sbms printf("AS Number: %u",EXTRACT_16BITS(tptr)); 2563127675Sbms break; 2564146778Ssam case ISIS_SUBTLV_IDRP_LOCAL: 2565146778Ssam case ISIS_SUBTLV_IDRP_RES: 2566127675Sbms default: 2567127675Sbms if(!print_unknown_data(tptr,"\n\t ",tlv_len-1)) 2568127675Sbms return(0); 2569127675Sbms break; 2570127675Sbms } 2571127675Sbms break; 2572127675Sbms 2573146778Ssam case ISIS_TLV_LSP_BUFFERSIZE: 2574162021Ssam if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN) 2575147904Ssam break; 2576162021Ssam if (!TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN)) 2577127675Sbms goto trunctlv; 2578127675Sbms printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr)); 2579127675Sbms break; 2580127675Sbms 2581146778Ssam case ISIS_TLV_PART_DIS: 2582127675Sbms while (tmp >= SYSTEM_ID_LEN) { 2583127675Sbms if (!TTEST2(*tptr, SYSTEM_ID_LEN)) 2584127675Sbms goto trunctlv; 2585127675Sbms printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN)); 2586127675Sbms tptr+=SYSTEM_ID_LEN; 2587127675Sbms tmp-=SYSTEM_ID_LEN; 2588127675Sbms } 2589127675Sbms break; 2590127675Sbms 2591146778Ssam case ISIS_TLV_PREFIX_NEIGH: 2592147904Ssam if (tmp < sizeof(struct isis_metric_block)) 2593147904Ssam break; 2594127675Sbms if (!TTEST2(*tptr, sizeof(struct isis_metric_block))) 2595127675Sbms goto trunctlv; 2596127675Sbms printf("\n\t Metric Block"); 2597127675Sbms isis_print_metric_block((const struct isis_metric_block *)tptr); 2598127675Sbms tptr+=sizeof(struct isis_metric_block); 2599127675Sbms tmp-=sizeof(struct isis_metric_block); 2600127675Sbms 2601127675Sbms while(tmp>0) { 2602127675Sbms if (!TTEST2(*tptr, 1)) 2603127675Sbms goto trunctlv; 2604127675Sbms prefix_len=*tptr++; /* read out prefix length in semioctets*/ 2605147904Ssam if (prefix_len < 2) { 2606147904Ssam printf("\n\t\tAddress: prefix length %u < 2", prefix_len); 2607147904Ssam break; 2608147904Ssam } 2609127675Sbms tmp--; 2610147904Ssam if (tmp < prefix_len/2) 2611147904Ssam break; 2612127675Sbms if (!TTEST2(*tptr, prefix_len/2)) 2613127675Sbms goto trunctlv; 2614127675Sbms printf("\n\t\tAddress: %s/%u", 2615146778Ssam isonsap_string(tptr,prefix_len/2), 2616127675Sbms prefix_len*4); 2617127675Sbms tptr+=prefix_len/2; 2618127675Sbms tmp-=prefix_len/2; 2619127675Sbms } 2620127675Sbms break; 2621127675Sbms 2622146778Ssam case ISIS_TLV_IIH_SEQNR: 2623162021Ssam if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN) 2624147904Ssam break; 2625162021Ssam if (!TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */ 2626127675Sbms goto trunctlv; 2627127675Sbms printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) ); 2628127675Sbms break; 2629127675Sbms 2630146778Ssam case ISIS_TLV_VENDOR_PRIVATE: 2631162021Ssam if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN) 2632147904Ssam break; 2633162021Ssam if (!TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */ 2634127675Sbms goto trunctlv; 2635146778Ssam vendor_id = EXTRACT_24BITS(tptr); 2636146778Ssam printf("\n\t Vendor: %s (%u)", 2637146778Ssam tok2str(oui_values,"Unknown",vendor_id), 2638146778Ssam vendor_id); 2639127675Sbms tptr+=3; 2640127675Sbms tmp-=3; 2641127675Sbms if (tmp > 0) /* hexdump the rest */ 2642127675Sbms if(!print_unknown_data(tptr,"\n\t\t",tmp)) 2643127675Sbms return(0); 2644127675Sbms break; 2645127675Sbms /* 2646127675Sbms * FIXME those are the defined TLVs that lack a decoder 2647127675Sbms * you are welcome to contribute code ;-) 2648127675Sbms */ 2649127675Sbms 2650146778Ssam case ISIS_TLV_DECNET_PHASE4: 2651146778Ssam case ISIS_TLV_LUCENT_PRIVATE: 2652146778Ssam case ISIS_TLV_IPAUTH: 2653146778Ssam case ISIS_TLV_NORTEL_PRIVATE1: 2654146778Ssam case ISIS_TLV_NORTEL_PRIVATE2: 2655127675Sbms 265617688Spst default: 2657127675Sbms if (vflag <= 1) { 2658127675Sbms if(!print_unknown_data(pptr,"\n\t\t",tlv_len)) 2659127675Sbms return(0); 2660127675Sbms } 266117688Spst break; 266217688Spst } 2663127675Sbms /* do we want to see an additionally hexdump ? */ 2664127675Sbms if (vflag> 1) { 2665127675Sbms if(!print_unknown_data(pptr,"\n\t ",tlv_len)) 2666127675Sbms return(0); 2667127675Sbms } 266817688Spst 2669127675Sbms pptr += tlv_len; 2670127675Sbms packet_len -= tlv_len; 267117688Spst } 267217688Spst 267317688Spst if (packet_len != 0) { 2674127675Sbms printf("\n\t %u straggler bytes", packet_len); 267517688Spst } 267698527Sfenner return (1); 267798527Sfenner 2678127675Sbms trunc: 267998527Sfenner fputs("[|isis]", stdout); 268098527Sfenner return (1); 268198527Sfenner 2682127675Sbms trunctlv: 2683127675Sbms printf("\n\t\t packet exceeded snapshot"); 268417688Spst return(1); 268517688Spst} 268617688Spst 268717751Spst/* 268817751Spst * Verify the checksum. See 8473-1, Appendix C, section C.4. 268917751Spst */ 269017751Spst 269117688Spststatic int 2692127675Sbmsosi_cksum(const u_int8_t *tptr, u_int len) 269317680Spst{ 269417680Spst int32_t c0 = 0, c1 = 0; 269517680Spst 269639300Sfenner while ((int)--len >= 0) { 2697127675Sbms c0 += *tptr++; 269817751Spst c0 %= 255; 269917680Spst c1 += c0; 270017680Spst c1 %= 255; 270117680Spst } 270217751Spst return (c0 | c1); 270317680Spst} 2704146778Ssam 2705146778Ssam 2706146778Ssam/* 2707146778Ssam * Local Variables: 2708146778Ssam * c-style: whitesmith 2709146778Ssam * c-basic-offset: 8 2710146778Ssam * End: 2711146778Ssam */ 2712