138032Speter/* 290792Sgshapiro * Copyright (c) 1992, 1993, 1994, 1995, 1996 364562Sgshapiro * The Regents of the University of California. All rights reserved. 438032Speter * 538032Speter * Redistribution and use in source and binary forms, with or without 638032Speter * modification, are permitted provided that: (1) source code distributions 738032Speter * retain the above copyright notice and this paragraph in its entirety, (2) 838032Speter * distributions including binary code include the above copyright notice and 938032Speter * this paragraph in its entirety in the documentation or other materials 1038032Speter * provided with the distribution, and (3) all advertising materials mentioning 1138032Speter * features or use of this software display the following acknowledgement: 1238032Speter * ``This product includes software developed by the University of California, 1338032Speter * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1464562Sgshapiro * the University nor the names of its contributors may be used to endorse 1590792Sgshapiro * or promote products derived from this software without specific prior 1638032Speter * written permission. 17110560Sgshapiro * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1864562Sgshapiro * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1938032Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2038032Speter * 2164562Sgshapiro * Original code by Matt Thomas, Digital Equipment Corporation 2238032Speter * 2394334Sgshapiro * Extensively modified by Hannes Gredler (hannes@gredler.at) for more 2494334Sgshapiro * complete IS-IS & CLNP support. 2594334Sgshapiro */ 2694334Sgshapiro 2790792Sgshapiro/* \summary: ISO CLNS, ESIS, and ISIS printer */ 2864562Sgshapiro 2990792Sgshapiro/* 3064562Sgshapiro * specification: 3190792Sgshapiro * 3264562Sgshapiro * CLNP: ISO 8473 (respective ITU version is at https://www.itu.int/rec/T-REC-X.233/en/) 3364562Sgshapiro * ES-IS: ISO 9542 3464562Sgshapiro * IS-IS: ISO 10589 3564562Sgshapiro */ 3664562Sgshapiro 3790792Sgshapiro#ifdef HAVE_CONFIG_H 3890792Sgshapiro#include <config.h> 3964562Sgshapiro#endif 4090792Sgshapiro 4164562Sgshapiro#include "netdissect-stdinc.h" 4290792Sgshapiro 4390792Sgshapiro#include <string.h> 4490792Sgshapiro 4590792Sgshapiro#include "netdissect.h" 4690792Sgshapiro#include "addrtoname.h" 4738032Speter#include "nlpid.h" 4838032Speter#include "extract.h" 4938032Speter#include "gmpls.h" 5038032Speter#include "oui.h" 5138032Speter#include "signature.h" 5238032Speter 5338032Speter 5438032Speter/* 5538032Speter * IS-IS is defined in ISO 10589. Look there for protocol definitions. 5638032Speter */ 5738032Speter 5838032Speter#define SYSTEM_ID_LEN MAC_ADDR_LEN 5938032Speter#define NODE_ID_LEN (SYSTEM_ID_LEN+1) 6038032Speter#define LSP_ID_LEN (SYSTEM_ID_LEN+2) 6138032Speter 6238032Speter#define ISIS_VERSION 1 6338032Speter#define ESIS_VERSION 1 6438032Speter#define CLNP_VERSION 1 6538032Speter 6638032Speter#define ISIS_PDU_TYPE_MASK 0x1F 6738032Speter#define ESIS_PDU_TYPE_MASK 0x1F 6838032Speter#define CLNP_PDU_TYPE_MASK 0x1F 6938032Speter#define CLNP_FLAG_MASK 0xE0 7038032Speter#define ISIS_LAN_PRIORITY_MASK 0x7F 7138032Speter 7238032Speter#define ISIS_PDU_L1_LAN_IIH 15 7338032Speter#define ISIS_PDU_L2_LAN_IIH 16 7464562Sgshapiro#define ISIS_PDU_PTP_IIH 17 7538032Speter#define ISIS_PDU_L1_LSP 18 7638032Speter#define ISIS_PDU_L2_LSP 20 7738032Speter#define ISIS_PDU_L1_CSNP 24 7890792Sgshapiro#define ISIS_PDU_L2_CSNP 25 7938032Speter#define ISIS_PDU_L1_PSNP 26 8038032Speter#define ISIS_PDU_L2_PSNP 27 8138032Speter 8238032Speterstatic const struct tok isis_pdu_values[] = { 8338032Speter { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"}, 8438032Speter { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"}, 8538032Speter { ISIS_PDU_PTP_IIH, "p2p IIH"}, 8638032Speter { ISIS_PDU_L1_LSP, "L1 LSP"}, 8738032Speter { ISIS_PDU_L2_LSP, "L2 LSP"}, 8838032Speter { ISIS_PDU_L1_CSNP, "L1 CSNP"}, 8990792Sgshapiro { ISIS_PDU_L2_CSNP, "L2 CSNP"}, 9038032Speter { ISIS_PDU_L1_PSNP, "L1 PSNP"}, 9190792Sgshapiro { ISIS_PDU_L2_PSNP, "L2 PSNP"}, 9290792Sgshapiro { 0, NULL} 9390792Sgshapiro}; 9438032Speter 9590792Sgshapiro/* 9638032Speter * A TLV is a tuple of a type, length and a value and is normally used for 9738032Speter * encoding information in all sorts of places. This is an enumeration of 9838032Speter * the well known types. 9938032Speter * 10038032Speter * list taken from rfc3359 plus some memory from veterans ;-) 10138032Speter */ 10238032Speter 10338032Speter#define ISIS_TLV_AREA_ADDR 1 /* iso10589 */ 10438032Speter#define ISIS_TLV_IS_REACH 2 /* iso10589 */ 10538032Speter#define ISIS_TLV_ESNEIGH 3 /* iso10589 */ 10638032Speter#define ISIS_TLV_PART_DIS 4 /* iso10589 */ 10738032Speter#define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ 10838032Speter#define ISIS_TLV_ISNEIGH 6 /* iso10589 */ 10938032Speter#define ISIS_TLV_INSTANCE_ID 7 /* rfc8202 */ 11038032Speter#define ISIS_TLV_PADDING 8 /* iso10589 */ 11138032Speter#define ISIS_TLV_LSP 9 /* iso10589 */ 11238032Speter#define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ 11338032Speter#define ISIS_TLV_CHECKSUM 12 /* rfc3358 */ 11438032Speter#define ISIS_TLV_CHECKSUM_MINLEN 2 11538032Speter#define ISIS_TLV_POI 13 /* rfc6232 */ 11638032Speter#define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ 11738032Speter#define ISIS_TLV_EXT_IS_REACH 22 /* rfc5305 */ 11838032Speter#define ISIS_TLV_IS_ALIAS_ID 24 /* rfc5311 */ 11938032Speter#define ISIS_TLV_DECNET_PHASE4 42 12038032Speter#define ISIS_TLV_LUCENT_PRIVATE 66 12138032Speter#define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ 12238032Speter#define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */ 12338032Speter#define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ 12490792Sgshapiro#define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */ 12538032Speter#define ISIS_TLV_IPADDR 132 /* rfc1195 */ 12690792Sgshapiro#define ISIS_TLV_IPAUTH 133 /* rfc1195 */ 12790792Sgshapiro#define ISIS_TLV_TE_ROUTER_ID 134 /* rfc5305 */ 12838032Speter#define ISIS_TLV_EXTD_IP_REACH 135 /* rfc5305 */ 12990792Sgshapiro#define ISIS_TLV_HOSTNAME 137 /* rfc2763 */ 13090792Sgshapiro#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ 13138032Speter#define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */ 13238032Speter#define ISIS_TLV_MT_CAPABILITY 144 /* rfc6329 */ 13338032Speter#define ISIS_TLV_NORTEL_PRIVATE1 176 13438032Speter#define ISIS_TLV_NORTEL_PRIVATE2 177 13538032Speter#define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */ 13638032Speter#define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1 13738032Speter#define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2 13838032Speter#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ 13938032Speter#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ 14038032Speter#define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ 14138032Speter#define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ 14238032Speter#define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ 14338032Speter#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ 14438032Speter#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ 14577349Sgshapiro#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ 14677349Sgshapiro#define ISIS_TLV_ROUTER_CAPABILITY 242 /* rfc7981 */ 14777349Sgshapiro#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ 14877349Sgshapiro#define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 14977349Sgshapiro 15077349Sgshapirostatic const struct tok isis_tlv_values[] = { 15177349Sgshapiro { ISIS_TLV_AREA_ADDR, "Area address(es)"}, 15277349Sgshapiro { ISIS_TLV_IS_REACH, "IS Reachability"}, 15338032Speter { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"}, 15490792Sgshapiro { ISIS_TLV_PART_DIS, "Partition DIS"}, 15538032Speter { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, 15664562Sgshapiro { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, 15777349Sgshapiro { ISIS_TLV_INSTANCE_ID, "Instance Identifier"}, 15877349Sgshapiro { ISIS_TLV_PADDING, "Padding"}, 15977349Sgshapiro { ISIS_TLV_LSP, "LSP entries"}, 16077349Sgshapiro { ISIS_TLV_AUTH, "Authentication"}, 16164562Sgshapiro { ISIS_TLV_CHECKSUM, "Checksum"}, 16264562Sgshapiro { ISIS_TLV_POI, "Purge Originator Identifier"}, 16364562Sgshapiro { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, 16464562Sgshapiro { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"}, 16564562Sgshapiro { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"}, 16664562Sgshapiro { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"}, 16777349Sgshapiro { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, 16864562Sgshapiro { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, 16938032Speter { ISIS_TLV_PROTOCOLS, "Protocols supported"}, 17038032Speter { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"}, 17138032Speter { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"}, 17238032Speter { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"}, 17338032Speter { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"}, 17438032Speter { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, 17564562Sgshapiro { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, 17638032Speter { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, 17738032Speter { ISIS_TLV_MT_PORT_CAP, "Multi-Topology-Aware Port Capability"}, 17838032Speter { ISIS_TLV_MT_CAPABILITY, "Multi-Topology Capability"}, 17938032Speter { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, 18038032Speter { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, 18138032Speter { ISIS_TLV_HOSTNAME, "Hostname"}, 18264562Sgshapiro { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"}, 18338032Speter { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, 18438032Speter { ISIS_TLV_MT_SUPPORTED, "Multi Topology"}, 18538032Speter { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"}, 18690792Sgshapiro { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, 18790792Sgshapiro { ISIS_TLV_IP6_REACH, "IPv6 reachability"}, 18838032Speter { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, 18964562Sgshapiro { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, 19038032Speter { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, 19138032Speter { ISIS_TLV_ROUTER_CAPABILITY, "IS-IS Router Capability"}, 19238032Speter { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, 19338032Speter { 0, NULL } 19438032Speter}; 19538032Speter 19638032Speter#define ESIS_OPTION_PROTOCOLS 129 19738032Speter#define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */ 19838032Speter#define ESIS_OPTION_SECURITY 197 /* iso9542 */ 19938032Speter#define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */ 20038032Speter#define ESIS_OPTION_PRIORITY 205 /* iso9542 */ 20138032Speter#define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */ 20238032Speter#define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */ 20338032Speter 20438032Speterstatic const struct tok esis_option_values[] = { 20538032Speter { ESIS_OPTION_PROTOCOLS, "Protocols supported"}, 20638032Speter { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" }, 20738032Speter { ESIS_OPTION_SECURITY, "Security" }, 20838032Speter { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" }, 20938032Speter { ESIS_OPTION_PRIORITY, "Priority" }, 21064562Sgshapiro { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" }, 21138032Speter { ESIS_OPTION_SNPA_MASK, "SNPA Mask" }, 21238032Speter { 0, NULL } 21338032Speter}; 21438032Speter 21538032Speter#define CLNP_OPTION_DISCARD_REASON 193 21638032Speter#define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */ 21790792Sgshapiro#define CLNP_OPTION_SECURITY 197 /* iso8473 */ 21890792Sgshapiro#define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */ 21938032Speter#define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */ 22038032Speter#define CLNP_OPTION_PADDING 204 /* iso8473 */ 22138032Speter#define CLNP_OPTION_PRIORITY 205 /* iso8473 */ 22238032Speter 22338032Speterstatic const struct tok clnp_option_values[] = { 22438032Speter { CLNP_OPTION_DISCARD_REASON, "Discard Reason"}, 22538032Speter { CLNP_OPTION_PRIORITY, "Priority"}, 22690792Sgshapiro { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"}, 22790792Sgshapiro { CLNP_OPTION_SECURITY, "Security"}, 22838032Speter { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"}, 22938032Speter { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"}, 23038032Speter { CLNP_OPTION_PADDING, "Padding"}, 23138032Speter { 0, NULL } 23238032Speter}; 23338032Speter 23438032Speterstatic const struct tok clnp_option_rfd_class_values[] = { 23590792Sgshapiro { 0x0, "General"}, 23690792Sgshapiro { 0x8, "Address"}, 23738032Speter { 0x9, "Source Routeing"}, 23864562Sgshapiro { 0xa, "Lifetime"}, 23938032Speter { 0xb, "PDU Discarded"}, 24038032Speter { 0xc, "Reassembly"}, 24190792Sgshapiro { 0, NULL } 24238032Speter}; 24338032Speter 24438032Speterstatic const struct tok clnp_option_rfd_general_values[] = { 24538032Speter { 0x0, "Reason not specified"}, 24690792Sgshapiro { 0x1, "Protocol procedure error"}, 24790792Sgshapiro { 0x2, "Incorrect checksum"}, 24838032Speter { 0x3, "PDU discarded due to congestion"}, 24938032Speter { 0x4, "Header syntax error (cannot be parsed)"}, 25038032Speter { 0x5, "Segmentation needed but not permitted"}, 25138032Speter { 0x6, "Incomplete PDU received"}, 25238032Speter { 0x7, "Duplicate option"}, 25338032Speter { 0, NULL } 25438032Speter}; 25590792Sgshapiro 25690792Sgshapirostatic const struct tok clnp_option_rfd_address_values[] = { 25738032Speter { 0x0, "Destination address unreachable"}, 25838032Speter { 0x1, "Destination address unknown"}, 25938032Speter { 0, NULL } 26038032Speter}; 26138032Speter 26238032Speterstatic const struct tok clnp_option_rfd_source_routeing_values[] = { 26338032Speter { 0x0, "Unspecified source routeing error"}, 26490792Sgshapiro { 0x1, "Syntax error in source routeing field"}, 26590792Sgshapiro { 0x2, "Unknown address in source routeing field"}, 26638032Speter { 0x3, "Path not acceptable"}, 26738032Speter { 0, NULL } 26838032Speter}; 26938032Speter 27038032Speterstatic const struct tok clnp_option_rfd_lifetime_values[] = { 27138032Speter { 0x0, "Lifetime expired while data unit in transit"}, 27238032Speter { 0x1, "Lifetime expired during reassembly"}, 27390792Sgshapiro { 0, NULL } 27490792Sgshapiro}; 27538032Speter 27638032Speterstatic const struct tok clnp_option_rfd_pdu_discard_values[] = { 27738032Speter { 0x0, "Unsupported option not specified"}, 27838032Speter { 0x1, "Unsupported protocol version"}, 27938032Speter { 0x2, "Unsupported security option"}, 28090792Sgshapiro { 0x3, "Unsupported source routeing option"}, 28190792Sgshapiro { 0x4, "Unsupported recording of route option"}, 28238032Speter { 0, NULL } 28338032Speter}; 28438032Speter 28538032Speterstatic const struct tok clnp_option_rfd_reassembly_values[] = { 28690792Sgshapiro { 0x0, "Reassembly interference"}, 28738032Speter { 0, NULL } 28838032Speter}; 28938032Speter 29064562Sgshapiro/* array of 16 error-classes */ 29164562Sgshapirostatic const struct tok *clnp_option_rfd_error_class[] = { 29264562Sgshapiro clnp_option_rfd_general_values, 29390792Sgshapiro NULL, 29464562Sgshapiro NULL, 29564562Sgshapiro NULL, 29664562Sgshapiro NULL, 29764562Sgshapiro NULL, 29864562Sgshapiro NULL, 29964562Sgshapiro NULL, 30064562Sgshapiro clnp_option_rfd_address_values, 30164562Sgshapiro clnp_option_rfd_source_routeing_values, 30264562Sgshapiro clnp_option_rfd_lifetime_values, 30364562Sgshapiro clnp_option_rfd_pdu_discard_values, 30464562Sgshapiro clnp_option_rfd_reassembly_values, 30564562Sgshapiro NULL, 30664562Sgshapiro NULL, 30764562Sgshapiro NULL 30864562Sgshapiro}; 30964562Sgshapiro 31090792Sgshapiro#define CLNP_OPTION_OPTION_QOS_MASK 0x3f 31190792Sgshapiro#define CLNP_OPTION_SCOPE_MASK 0xc0 31264562Sgshapiro#define CLNP_OPTION_SCOPE_SA_SPEC 0x40 31390792Sgshapiro#define CLNP_OPTION_SCOPE_DA_SPEC 0x80 31464562Sgshapiro#define CLNP_OPTION_SCOPE_GLOBAL 0xc0 31564562Sgshapiro 31664562Sgshapirostatic const struct tok clnp_option_scope_values[] = { 31764562Sgshapiro { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"}, 31864562Sgshapiro { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"}, 31990792Sgshapiro { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"}, 32064562Sgshapiro { 0, NULL } 32190792Sgshapiro}; 32290792Sgshapiro 32390792Sgshapirostatic const struct tok clnp_option_sr_rr_values[] = { 32464562Sgshapiro { 0x0, "partial"}, 32564562Sgshapiro { 0x1, "complete"}, 32664562Sgshapiro { 0, NULL } 32764562Sgshapiro}; 32864562Sgshapiro 32964562Sgshapirostatic const struct tok clnp_option_sr_rr_string_values[] = { 33090792Sgshapiro { CLNP_OPTION_SOURCE_ROUTING, "source routing"}, 33164562Sgshapiro { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"}, 33264562Sgshapiro { 0, NULL } 33364562Sgshapiro}; 33464562Sgshapiro 33538032Speterstatic const struct tok clnp_option_qos_global_values[] = { 33638032Speter { 0x20, "reserved"}, 33738032Speter { 0x10, "sequencing vs. delay"}, 33838032Speter { 0x08, "congested"}, 33938032Speter { 0x04, "delay vs. cost"}, 34038032Speter { 0x02, "error vs. delay"}, 34138032Speter { 0x01, "error vs. cost"}, 34238032Speter { 0, NULL } 34338032Speter}; 34464562Sgshapiro 34564562Sgshapirostatic const struct tok isis_tlv_router_capability_flags[] = { 34638032Speter { 0x01, "S bit"}, 34738032Speter { 0x02, "D bit"}, 34890792Sgshapiro { 0, NULL } 34964562Sgshapiro}; 35090792Sgshapiro 35138032Speter#define ISIS_SUBTLV_ROUTER_CAP_SR 2 /* rfc 8667 */ 35264562Sgshapiro 35364562Sgshapirostatic const struct tok isis_router_capability_subtlv_values[] = { 35464562Sgshapiro { ISIS_SUBTLV_ROUTER_CAP_SR, "SR-Capabilities"}, 35564562Sgshapiro { 0, NULL } 35638032Speter}; 35738032Speter 35890792Sgshapirostatic const struct tok isis_router_capability_sr_flags[] = { 35964562Sgshapiro { 0x80, "ipv4"}, 36090792Sgshapiro { 0x40, "ipv6"}, 36138032Speter { 0, NULL } 36290792Sgshapiro}; 36390792Sgshapiro 36490792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* rfc5305 */ 36590792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */ 36690792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* rfc5305 */ 36790792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* rfc5305 */ 36890792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* rfc5305 */ 36990792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* rfc5305 */ 37090792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* rfc5305 */ 37190792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */ 37290792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */ 37338032Speter#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* rfc5305 */ 37438032Speter#define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */ 37538032Speter#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */ 37690792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */ 37790792Sgshapiro#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */ 37838032Speter#define ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID 32 /* rfc8667 */ 37938032Speter 38038032Speter#define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */ 38138032Speter 38238032Speterstatic const struct tok isis_ext_is_reach_subtlv_values[] = { 38338032Speter { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, 38438032Speter { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, 38538032Speter { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, 38638032Speter { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, 38790792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, 38890792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, 38990792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, 39064562Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, 39138032Speter { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, 39264562Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" }, 39338032Speter { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, 39438032Speter { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, 39590792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" }, 39690792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" }, 39790792Sgshapiro { ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID, "LAN Adjacency Segment Identifier" }, 39838032Speter { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" }, 39990792Sgshapiro { 250, "Reserved for cisco specific extensions" }, 40090792Sgshapiro { 251, "Reserved for cisco specific extensions" }, 40190792Sgshapiro { 252, "Reserved for cisco specific extensions" }, 40290792Sgshapiro { 253, "Reserved for cisco specific extensions" }, 40390792Sgshapiro { 254, "Reserved for cisco specific extensions" }, 40438032Speter { 255, "Reserved for future expansion" }, 40538032Speter { 0, NULL } 40690792Sgshapiro}; 40738032Speter 40838032Speter#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ 40990792Sgshapiro#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ 41090792Sgshapiro#define ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID 3 /* rfc8667 */ 41138032Speter#define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ 41264562Sgshapiro 41338032Speterstatic const struct tok isis_ext_ip_reach_subtlv_values[] = { 41464562Sgshapiro { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, 41538032Speter { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, 41690792Sgshapiro { ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID, "Prefix SID" }, 41790792Sgshapiro { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, 41838032Speter { 0, NULL } 41938032Speter}; 42064562Sgshapiro 42190792Sgshapiro#define ISIS_PREFIX_SID_FLAG_R 0x80 /* rfc 8667 */ 42290792Sgshapiro#define ISIS_PREFIX_SID_FLAG_N 0x40 /* rfc 8667 */ 42390792Sgshapiro#define ISIS_PREFIX_SID_FLAG_P 0x20 /* rfc 8667 */ 42490792Sgshapiro#define ISIS_PREFIX_SID_FLAG_E 0x10 /* rfc 8667 */ 42590792Sgshapiro#define ISIS_PREFIX_SID_FLAG_V 0x08 /* rfc 8667 */ 42638032Speter#define ISIS_PREFIX_SID_FLAG_L 0x04 /* rfc 8667 */ 42738032Speter 42838032Speterstatic const struct tok prefix_sid_flag_values[] = { 42938032Speter { ISIS_PREFIX_SID_FLAG_R, "Readvertisement"}, 43038032Speter { ISIS_PREFIX_SID_FLAG_N, "Node"}, 43138032Speter { ISIS_PREFIX_SID_FLAG_P, "No-PHP"}, 43264562Sgshapiro { ISIS_PREFIX_SID_FLAG_E, "Explicit NULL"}, 43338032Speter { ISIS_PREFIX_SID_FLAG_V, "Value"}, 43490792Sgshapiro { ISIS_PREFIX_SID_FLAG_L, "Local"}, 43590792Sgshapiro { 0, NULL} 43638032Speter}; 43738032Speter 43838032Speter 43938032Speter/* rfc 8667 */ 44038032Speterstatic const struct tok prefix_sid_algo_values[] = { 44138032Speter { 0, "SPF"}, 44264562Sgshapiro { 1, "strict-SPF"}, 44338032Speter { 0, NULL} 44490792Sgshapiro}; 44590792Sgshapiro 44638032Speterstatic const struct tok isis_subtlv_link_attribute_values[] = { 44738032Speter { 0x01, "Local Protection Available" }, 44838032Speter { 0x02, "Link excluded from local protection path" }, 44938032Speter { 0x04, "Local maintenance required"}, 45038032Speter { 0, NULL } 45138032Speter}; 45238032Speter 45390792Sgshapirostatic const struct tok isis_lan_adj_sid_flag_values[] = { 45490792Sgshapiro { 0x80, "Address family IPv6" }, 45538032Speter { 0x40, "Backup" }, 45638032Speter { 0x20, "Value" }, 45738032Speter { 0x10, "Local significance" }, 45838032Speter { 0x08, "Set of adjacencies" }, 45990792Sgshapiro { 0x04, "Persistent" }, 46064562Sgshapiro { 0, NULL } 46164562Sgshapiro}; 46264562Sgshapiro 46364562Sgshapiro#define ISIS_SUBTLV_AUTH_SIMPLE 1 46464562Sgshapiro#define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */ 46564562Sgshapiro#define ISIS_SUBTLV_AUTH_MD5 54 46664562Sgshapiro#define ISIS_SUBTLV_AUTH_MD5_LEN 16 46764562Sgshapiro#define ISIS_SUBTLV_AUTH_PRIVATE 255 46864562Sgshapiro 46990792Sgshapirostatic const struct tok isis_subtlv_auth_values[] = { 47064562Sgshapiro { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"}, 47164562Sgshapiro { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"}, 47264562Sgshapiro { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, 47364562Sgshapiro { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, 47464562Sgshapiro { 0, NULL } 47542575Speter}; 47690792Sgshapiro 47790792Sgshapiro#define ISIS_SUBTLV_IDRP_RES 0 47890792Sgshapiro#define ISIS_SUBTLV_IDRP_LOCAL 1 47938032Speter#define ISIS_SUBTLV_IDRP_ASN 2 48038032Speter 48138032Speterstatic const struct tok isis_subtlv_idrp_values[] = { 48238032Speter { ISIS_SUBTLV_IDRP_RES, "Reserved"}, 48338032Speter { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, 48490792Sgshapiro { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"}, 48538032Speter { 0, NULL} 48638032Speter}; 48790792Sgshapiro 48890792Sgshapiro#define ISIS_SUBTLV_SPB_MCID 4 48938032Speter#define ISIS_SUBTLV_SPB_DIGEST 5 49064562Sgshapiro#define ISIS_SUBTLV_SPB_BVID 6 49138032Speter 49238032Speter#define ISIS_SUBTLV_SPB_INSTANCE 1 49338032Speter#define ISIS_SUBTLV_SPBM_SI 3 49438032Speter 49538032Speter#define ISIS_SPB_MCID_LEN 51 49638032Speter#define ISIS_SUBTLV_SPB_MCID_MIN_LEN 102 49790792Sgshapiro#define ISIS_SUBTLV_SPB_DIGEST_MIN_LEN 33 49838032Speter#define ISIS_SUBTLV_SPB_BVID_MIN_LEN 6 49938032Speter#define ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN 19 50090792Sgshapiro#define ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN 8 50171345Sgshapiro 50238032Speterstatic const struct tok isis_mt_port_cap_subtlv_values[] = { 50390792Sgshapiro { ISIS_SUBTLV_SPB_MCID, "SPB MCID" }, 50438032Speter { ISIS_SUBTLV_SPB_DIGEST, "SPB Digest" }, 50590792Sgshapiro { ISIS_SUBTLV_SPB_BVID, "SPB BVID" }, 50638032Speter { 0, NULL } 50738032Speter}; 50871345Sgshapiro 50938032Speterstatic const struct tok isis_mt_capability_subtlv_values[] = { 51038032Speter { ISIS_SUBTLV_SPB_INSTANCE, "SPB Instance" }, 51138032Speter { ISIS_SUBTLV_SPBM_SI, "SPBM Service Identifier and Unicast Address" }, 51238032Speter { 0, NULL } 51371345Sgshapiro}; 51438032Speter 51538032Speterstruct isis_spb_mcid { 51638032Speter nd_uint8_t format_id; 51738032Speter nd_byte name[32]; 51838032Speter nd_uint16_t revision_lvl; 51990792Sgshapiro nd_byte digest[16]; 52090792Sgshapiro}; 52138032Speter 52238032Speterstruct isis_subtlv_spb_mcid { 52390792Sgshapiro struct isis_spb_mcid mcid; 52490792Sgshapiro struct isis_spb_mcid aux_mcid; 52566494Sgshapiro}; 52666494Sgshapiro 52766494Sgshapirostruct isis_subtlv_spb_instance { 52866494Sgshapiro nd_byte cist_root_id[8]; 52966494Sgshapiro nd_uint32_t cist_external_root_path_cost; 53066494Sgshapiro nd_uint16_t bridge_priority; 53166494Sgshapiro nd_uint32_t spsourceid; 53290792Sgshapiro nd_uint8_t no_of_trees; 53390792Sgshapiro}; 53490792Sgshapiro 53590792Sgshapiro#define CLNP_SEGMENT_PART 0x80 53690792Sgshapiro#define CLNP_MORE_SEGMENTS 0x40 53790792Sgshapiro#define CLNP_REQUEST_ER 0x20 53838032Speter 53990792Sgshapirostatic const struct tok clnp_flag_values[] = { 54090792Sgshapiro { CLNP_SEGMENT_PART, "Segmentation permitted"}, 54138032Speter { CLNP_MORE_SEGMENTS, "more Segments"}, 54238032Speter { CLNP_REQUEST_ER, "request Error Report"}, 54338032Speter { 0, NULL} 54438032Speter}; 54538032Speter 54638032Speter#define ISIS_MASK_LSP_OL_BIT(x) (GET_U_1(x)&0x4) 54738032Speter#define ISIS_MASK_LSP_ISTYPE_BITS(x) (GET_U_1(x)&0x3) 54838032Speter#define ISIS_MASK_LSP_PARTITION_BIT(x) (GET_U_1(x)&0x80) 54938032Speter#define ISIS_MASK_LSP_ATT_BITS(x) (GET_U_1(x)&0x78) 55038032Speter#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) (GET_U_1(x)&0x40) 55138032Speter#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) (GET_U_1(x)&0x20) 55290792Sgshapiro#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) (GET_U_1(x)&0x10) 55338032Speter#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) (GET_U_1(x)&0x8) 55438032Speter 55590792Sgshapiro#define ISIS_MASK_MTID(x) ((x)&0x0fff) 55690792Sgshapiro#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) 55790792Sgshapiro 55890792Sgshapirostatic const struct tok isis_mt_flag_values[] = { 55938032Speter { 0x4000, "ATT bit set"}, 56038032Speter { 0x8000, "Overload bit set"}, 56190792Sgshapiro { 0, NULL} 56290792Sgshapiro}; 56390792Sgshapiro 56438032Speter#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) 56590792Sgshapiro#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) 56638032Speter 56738032Speter#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) 56838032Speter#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) 56938032Speter 57038032Speter#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) (GET_U_1(x)&0x80) 57138032Speter#define ISIS_LSP_TLV_METRIC_IE(x) (GET_U_1(x)&0x40) 57238032Speter#define ISIS_LSP_TLV_METRIC_UPDOWN(x) (GET_U_1(x)&0x80) 57338032Speter#define ISIS_LSP_TLV_METRIC_VALUE(x) (GET_U_1(x)&0x3f) 57438032Speter 57538032Speter#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) 57664562Sgshapiro 57738032Speterstatic const struct tok isis_mt_values[] = { 57864562Sgshapiro { 0, "IPv4 unicast"}, 57938032Speter { 1, "In-Band Management"}, 58038032Speter { 2, "IPv6 unicast"}, 58190792Sgshapiro { 3, "Multicast"}, 58238032Speter { 4095, "Development, Experimental or Proprietary"}, 58338032Speter { 0, NULL } 58438032Speter}; 58538032Speter 58690792Sgshapirostatic const struct tok isis_iih_circuit_type_values[] = { 58738032Speter { 1, "Level 1 only"}, 58838032Speter { 2, "Level 2 only"}, 58938032Speter { 3, "Level 1, Level 2"}, 59038032Speter { 0, NULL} 59138032Speter}; 59290792Sgshapiro 59338032Speter#define ISIS_LSP_TYPE_UNUSED0 0 59464562Sgshapiro#define ISIS_LSP_TYPE_LEVEL_1 1 59538032Speter#define ISIS_LSP_TYPE_UNUSED2 2 59638032Speter#define ISIS_LSP_TYPE_LEVEL_2 3 59738032Speter 59838032Speterstatic const struct tok isis_lsp_istype_values[] = { 59938032Speter { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, 60038032Speter { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, 60138032Speter { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, 60238032Speter { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"}, 60338032Speter { 0, NULL } 60438032Speter}; 60538032Speter 60638032Speter/* 60738032Speter * Katz's point to point adjacency TLV uses codes to tell us the state of 60890792Sgshapiro * the remote adjacency. Enumerate them. 60938032Speter */ 61038032Speter 61138032Speter#define ISIS_PTP_ADJ_UP 0 61238032Speter#define ISIS_PTP_ADJ_INIT 1 61338032Speter#define ISIS_PTP_ADJ_DOWN 2 61438032Speter 61538032Speterstatic const struct tok isis_ptp_adjancey_values[] = { 61638032Speter { ISIS_PTP_ADJ_UP, "Up" }, 61738032Speter { ISIS_PTP_ADJ_INIT, "Initializing" }, 61838032Speter { ISIS_PTP_ADJ_DOWN, "Down" }, 61938032Speter { 0, NULL} 62038032Speter}; 62190792Sgshapiro 62238032Speterstruct isis_tlv_ptp_adj { 62338032Speter nd_uint8_t adjacency_state; 62438032Speter nd_uint32_t extd_local_circuit_id; 62538032Speter nd_byte neighbor_sysid[SYSTEM_ID_LEN]; 62664562Sgshapiro nd_uint32_t neighbor_extd_local_circuit_id; 62738032Speter}; 62864562Sgshapiro 62964562Sgshapirostatic void osi_print_cksum(netdissect_options *, const uint8_t *pptr, 63064562Sgshapiro uint16_t checksum, int checksum_offset, u_int length); 63164562Sgshapirostatic int clnp_print(netdissect_options *, const uint8_t *, u_int); 63264562Sgshapirostatic void esis_print(netdissect_options *, const uint8_t *, u_int); 63364562Sgshapirostatic int isis_print(netdissect_options *, const uint8_t *, u_int); 63464562Sgshapiro 63564562Sgshapirostruct isis_metric_block { 63690792Sgshapiro nd_uint8_t metric_default; 63764562Sgshapiro nd_uint8_t metric_delay; 63838032Speter nd_uint8_t metric_expense; 63938032Speter nd_uint8_t metric_error; 64038032Speter}; 64164562Sgshapiro 64264562Sgshapirostruct isis_tlv_is_reach { 64338032Speter struct isis_metric_block isis_metric_block; 64464562Sgshapiro nd_byte neighbor_nodeid[NODE_ID_LEN]; 64538032Speter}; 64638032Speter 64738032Speterstruct isis_tlv_es_reach { 64838032Speter struct isis_metric_block isis_metric_block; 64964562Sgshapiro nd_byte neighbor_sysid[SYSTEM_ID_LEN]; 65038032Speter}; 65138032Speter 65238032Speterstruct isis_tlv_ip_reach { 65364562Sgshapiro struct isis_metric_block isis_metric_block; 65438032Speter nd_ipv4 prefix; 65538032Speter nd_ipv4 mask; 65638032Speter}; 65738032Speter 65890792Sgshapirostatic const struct tok isis_is_reach_virtual_values[] = { 65938032Speter { 0, "IsNotVirtual"}, 66038032Speter { 1, "IsVirtual"}, 66138032Speter { 0, NULL } 66238032Speter}; 66338032Speter 66490792Sgshapirostatic const struct tok isis_restart_flag_values[] = { 66564562Sgshapiro { 0x1, "Restart Request"}, 66664562Sgshapiro { 0x2, "Restart Acknowledgement"}, 66738032Speter { 0x4, "Suppress adjacency advertisement"}, 66864562Sgshapiro { 0, NULL } 66938032Speter}; 67038032Speter 67138032Speterstruct isis_common_header { 67238032Speter nd_uint8_t nlpid; 67390792Sgshapiro nd_uint8_t fixed_len; 67438032Speter nd_uint8_t version; /* Protocol version */ 67538032Speter nd_uint8_t id_length; 67690792Sgshapiro nd_uint8_t pdu_type; /* 3 MSbits are reserved */ 67738032Speter nd_uint8_t pdu_version; /* Packet format version */ 67838032Speter nd_byte reserved; 67938032Speter nd_uint8_t max_area; 68077349Sgshapiro}; 68177349Sgshapiro 68290792Sgshapirostruct isis_iih_lan_header { 68377349Sgshapiro nd_uint8_t circuit_type; 68477349Sgshapiro nd_byte source_id[SYSTEM_ID_LEN]; 68577349Sgshapiro nd_uint16_t holding_time; 68666494Sgshapiro nd_uint16_t pdu_len; 68790792Sgshapiro nd_uint8_t priority; 68890792Sgshapiro nd_byte lan_id[NODE_ID_LEN]; 68990792Sgshapiro}; 69090792Sgshapiro 69190792Sgshapirostruct isis_iih_ptp_header { 69290792Sgshapiro nd_uint8_t circuit_type; 69390792Sgshapiro nd_byte source_id[SYSTEM_ID_LEN]; 69466494Sgshapiro nd_uint16_t holding_time; 69566494Sgshapiro nd_uint16_t pdu_len; 69666494Sgshapiro nd_uint8_t circuit_id; 69766494Sgshapiro}; 69866494Sgshapiro 69966494Sgshapirostruct isis_lsp_header { 70090792Sgshapiro nd_uint16_t pdu_len; 70166494Sgshapiro nd_uint16_t remaining_lifetime; 70290792Sgshapiro nd_byte lsp_id[LSP_ID_LEN]; 70338032Speter nd_uint32_t sequence_number; 70438032Speter nd_uint16_t checksum; 70538032Speter nd_uint8_t typeblock; 70638032Speter}; 70764562Sgshapiro 70890792Sgshapirostruct isis_csnp_header { 70938032Speter nd_uint16_t pdu_len; 71090792Sgshapiro nd_byte source_id[NODE_ID_LEN]; 71190792Sgshapiro nd_byte start_lsp_id[LSP_ID_LEN]; 71238032Speter nd_byte end_lsp_id[LSP_ID_LEN]; 71338032Speter}; 71464562Sgshapiro 71538032Speterstruct isis_psnp_header { 71638032Speter nd_uint16_t pdu_len; 71738032Speter nd_byte source_id[NODE_ID_LEN]; 71838032Speter}; 71964562Sgshapiro 72064562Sgshapirostruct isis_tlv_lsp { 72164562Sgshapiro nd_uint16_t remaining_lifetime; 72238032Speter nd_byte lsp_id[LSP_ID_LEN]; 72364562Sgshapiro nd_uint32_t sequence_number; 72438032Speter nd_uint16_t checksum; 72564562Sgshapiro}; 72690792Sgshapiro 72738032Speter#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) 72838032Speter#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) 72938032Speter#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) 73090792Sgshapiro#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) 73138032Speter#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) 73238032Speter#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) 73338032Speter 73438032Spetervoid 73538032Speterisoclns_print(netdissect_options *ndo, const u_char *p, u_int length) 73638032Speter{ 73738032Speter ndo->ndo_protocol = "isoclns"; 73838032Speter 73938032Speter if (ndo->ndo_eflag) 74038032Speter ND_PRINT("OSI NLPID %s (0x%02x): ", 74138032Speter tok2str(nlpid_values, "Unknown", GET_U_1(p)), 74290792Sgshapiro GET_U_1(p)); 74338032Speter 74464562Sgshapiro switch (GET_U_1(p)) { 74538032Speter 74664562Sgshapiro case NLPID_CLNP: 74738032Speter if (!clnp_print(ndo, p, length)) 74838032Speter print_unknown_data(ndo, p, "\n\t", length); 74938032Speter break; 75038032Speter 75138032Speter case NLPID_ESIS: 75238032Speter esis_print(ndo, p, length); 75338032Speter return; 75438032Speter 75538032Speter case NLPID_ISIS: 75690792Sgshapiro if (!isis_print(ndo, p, length)) 75790792Sgshapiro print_unknown_data(ndo, p, "\n\t", length); 75838032Speter break; 75938032Speter 76090792Sgshapiro case NLPID_NULLNS: 76190792Sgshapiro ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length); 76290792Sgshapiro break; 76364562Sgshapiro 76438032Speter case NLPID_Q933: 76538032Speter q933_print(ndo, p + 1, length - 1); 76638032Speter break; 76790792Sgshapiro 76838032Speter case NLPID_IP: 76938032Speter ip_print(ndo, p + 1, length - 1); 77038032Speter break; 77138032Speter 77238032Speter case NLPID_IP6: 77338032Speter ip6_print(ndo, p + 1, length - 1); 77490792Sgshapiro break; 77538032Speter 77638032Speter case NLPID_PPP: 77738032Speter ppp_print(ndo, p + 1, length - 1); 77838032Speter break; 77938032Speter 78090792Sgshapiro default: 78138032Speter if (!ndo->ndo_eflag) 78238032Speter ND_PRINT("OSI NLPID 0x%02x unknown", GET_U_1(p)); 78364562Sgshapiro ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length); 78438032Speter if (length > 1) 78538032Speter print_unknown_data(ndo, p, "\n\t", length); 78638032Speter break; 78738032Speter } 78838032Speter} 78938032Speter 79038032Speter#define CLNP_PDU_ER 1 79138032Speter#define CLNP_PDU_DT 28 79290792Sgshapiro#define CLNP_PDU_MD 29 79390792Sgshapiro#define CLNP_PDU_ERQ 30 79490792Sgshapiro#define CLNP_PDU_ERP 31 79538032Speter 79638032Speterstatic const struct tok clnp_pdu_values[] = { 79764562Sgshapiro { CLNP_PDU_ER, "Error Report"}, 79864562Sgshapiro { CLNP_PDU_MD, "MD"}, 79938032Speter { CLNP_PDU_DT, "Data"}, 80038032Speter { CLNP_PDU_ERQ, "Echo Request"}, 80138032Speter { CLNP_PDU_ERP, "Echo Response"}, 80238032Speter { 0, NULL } 80338032Speter}; 80438032Speter 80538032Speterstruct clnp_header_t { 80638032Speter nd_uint8_t nlpid; 80738032Speter nd_uint8_t length_indicator; 80838032Speter nd_uint8_t version; 80938032Speter nd_uint8_t lifetime; /* units of 500ms */ 81038032Speter nd_uint8_t type; 81138032Speter nd_uint16_t segment_length; 81238032Speter nd_uint16_t cksum; 81338032Speter}; 81490792Sgshapiro 81590792Sgshapirostruct clnp_segment_header_t { 81690792Sgshapiro nd_uint16_t data_unit_id; 81790792Sgshapiro nd_uint16_t segment_offset; 81890792Sgshapiro nd_uint16_t total_length; 81964562Sgshapiro}; 82090792Sgshapiro 82190792Sgshapiro/* 82290792Sgshapiro * clnp_print 82364562Sgshapiro * Decode CLNP packets. Return 0 on error. 82464562Sgshapiro */ 82538032Speter 82638032Speterstatic int 82738032Speterclnp_print(netdissect_options *ndo, 82838032Speter const uint8_t *pptr, u_int length) 82938032Speter{ 83038032Speter const uint8_t *optr,*source_address,*dest_address; 83138032Speter u_int li,li_remaining,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; 83238032Speter const struct clnp_header_t *clnp_header; 83338032Speter const struct clnp_segment_header_t *clnp_segment_header; 83464562Sgshapiro uint8_t rfd_error,rfd_error_major,rfd_error_minor; 83590792Sgshapiro 83690792Sgshapiro ndo->ndo_protocol = "clnp"; 83790792Sgshapiro clnp_header = (const struct clnp_header_t *) pptr; 83838032Speter ND_TCHECK_SIZE(clnp_header); 83990792Sgshapiro 84090792Sgshapiro li = GET_U_1(clnp_header->length_indicator); 84190792Sgshapiro li_remaining = li; 84290792Sgshapiro optr = pptr; 84390792Sgshapiro 84490792Sgshapiro if (!ndo->ndo_eflag) 84590792Sgshapiro nd_print_protocol_caps(ndo); 84690792Sgshapiro 84790792Sgshapiro /* 84890792Sgshapiro * Sanity checking of the header. 84990792Sgshapiro */ 85090792Sgshapiro 85190792Sgshapiro if (GET_U_1(clnp_header->version) != CLNP_VERSION) { 85290792Sgshapiro ND_PRINT("version %u packet not supported", 85390792Sgshapiro GET_U_1(clnp_header->version)); 85490792Sgshapiro return (0); 85590792Sgshapiro } 85690792Sgshapiro 85790792Sgshapiro if (li > length) { 85890792Sgshapiro ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length); 85990792Sgshapiro return (0); 86090792Sgshapiro } 86190792Sgshapiro 86290792Sgshapiro if (li < sizeof(struct clnp_header_t)) { 86390792Sgshapiro ND_PRINT(" length indicator %u < min PDU size:", li); 86490792Sgshapiro while (pptr < ndo->ndo_snapend) { 86590792Sgshapiro ND_PRINT("%02X", GET_U_1(pptr)); 86690792Sgshapiro pptr++; 86790792Sgshapiro } 86890792Sgshapiro return (0); 86990792Sgshapiro } 87090792Sgshapiro 87190792Sgshapiro /* FIXME further header sanity checking */ 87290792Sgshapiro 87390792Sgshapiro clnp_pdu_type = GET_U_1(clnp_header->type) & CLNP_PDU_TYPE_MASK; 87490792Sgshapiro clnp_flags = GET_U_1(clnp_header->type) & CLNP_FLAG_MASK; 87590792Sgshapiro 87690792Sgshapiro pptr += sizeof(struct clnp_header_t); 87790792Sgshapiro li_remaining -= sizeof(struct clnp_header_t); 87890792Sgshapiro 87990792Sgshapiro if (li_remaining < 1) { 88090792Sgshapiro ND_PRINT("li < size of fixed part of CLNP header and addresses"); 88190792Sgshapiro return (0); 88238032Speter } 88338032Speter dest_address_length = GET_U_1(pptr); 88438032Speter pptr += 1; 88538032Speter li_remaining -= 1; 88638032Speter if (li_remaining < dest_address_length) { 88738032Speter ND_PRINT("li < size of fixed part of CLNP header and addresses"); 88890792Sgshapiro return (0); 88990792Sgshapiro } 89038032Speter ND_TCHECK_LEN(pptr, dest_address_length); 89164562Sgshapiro dest_address = pptr; 89238032Speter pptr += dest_address_length; 89338032Speter li_remaining -= dest_address_length; 89438032Speter 89564562Sgshapiro if (li_remaining < 1) { 89638032Speter ND_PRINT("li < size of fixed part of CLNP header and addresses"); 89738032Speter return (0); 89838032Speter } 89938032Speter source_address_length = GET_U_1(pptr); 90038032Speter pptr += 1; 90138032Speter li_remaining -= 1; 90238032Speter if (li_remaining < source_address_length) { 90338032Speter ND_PRINT("li < size of fixed part of CLNP header and addresses"); 90438032Speter return (0); 90538032Speter } 90638032Speter ND_TCHECK_LEN(pptr, source_address_length); 90738032Speter source_address = pptr; 90864562Sgshapiro pptr += source_address_length; 90938032Speter li_remaining -= source_address_length; 91038032Speter 91138032Speter if (ndo->ndo_vflag < 1) { 91238032Speter ND_PRINT("%s%s > %s, %s, length %u", 91338032Speter ndo->ndo_eflag ? "" : ", ", 91466494Sgshapiro GET_ISONSAP_STRING(source_address, source_address_length), 91566494Sgshapiro GET_ISONSAP_STRING(dest_address, dest_address_length), 91638032Speter tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), 91790792Sgshapiro length); 91838032Speter return (1); 91938032Speter } 92038032Speter ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length); 92190792Sgshapiro 92238032Speter ND_PRINT("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x", 92338032Speter tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type), 92438032Speter GET_U_1(clnp_header->length_indicator), 92538032Speter GET_U_1(clnp_header->version), 92638032Speter GET_U_1(clnp_header->lifetime)/2, 92738032Speter (GET_U_1(clnp_header->lifetime)%2)*5, 92838032Speter GET_BE_U_2(clnp_header->segment_length), 92938032Speter GET_BE_U_2(clnp_header->cksum)); 93038032Speter 93138032Speter osi_print_cksum(ndo, optr, GET_BE_U_2(clnp_header->cksum), 7, 93264562Sgshapiro GET_U_1(clnp_header->length_indicator)); 93338032Speter 93490792Sgshapiro ND_PRINT("\n\tFlags [%s]", 93590792Sgshapiro bittok2str(clnp_flag_values, "none", clnp_flags)); 93690792Sgshapiro 93790792Sgshapiro ND_PRINT("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", 93890792Sgshapiro source_address_length, 93990792Sgshapiro GET_ISONSAP_STRING(source_address, source_address_length), 94090792Sgshapiro dest_address_length, 94190792Sgshapiro GET_ISONSAP_STRING(dest_address, dest_address_length)); 94290792Sgshapiro 94390792Sgshapiro if (clnp_flags & CLNP_SEGMENT_PART) { 94490792Sgshapiro if (li_remaining < sizeof(struct clnp_segment_header_t)) { 94590792Sgshapiro ND_PRINT("li < size of fixed part of CLNP header, addresses, and segment part"); 94690792Sgshapiro return (0); 94790792Sgshapiro } 94890792Sgshapiro clnp_segment_header = (const struct clnp_segment_header_t *) pptr; 94990792Sgshapiro ND_TCHECK_SIZE(clnp_segment_header); 95090792Sgshapiro ND_PRINT("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", 95190792Sgshapiro GET_BE_U_2(clnp_segment_header->data_unit_id), 95290792Sgshapiro GET_BE_U_2(clnp_segment_header->segment_offset), 95390792Sgshapiro GET_BE_U_2(clnp_segment_header->total_length)); 95490792Sgshapiro pptr+=sizeof(struct clnp_segment_header_t); 95590792Sgshapiro li_remaining-=sizeof(struct clnp_segment_header_t); 956110560Sgshapiro } 957110560Sgshapiro 958110560Sgshapiro /* now walk the options */ 959110560Sgshapiro while (li_remaining != 0) { 960110560Sgshapiro u_int op, opli; 96190792Sgshapiro const uint8_t *tptr; 96290792Sgshapiro 96390792Sgshapiro if (li_remaining < 2) { 96490792Sgshapiro ND_PRINT(", bad opts/li"); 96590792Sgshapiro return (0); 96690792Sgshapiro } 96790792Sgshapiro op = GET_U_1(pptr); 96890792Sgshapiro opli = GET_U_1(pptr + 1); 96990792Sgshapiro pptr += 2; 97090792Sgshapiro li_remaining -= 2; 97190792Sgshapiro if (opli > li_remaining) { 97290792Sgshapiro ND_PRINT(", opt (%u) too long", op); 97390792Sgshapiro return (0); 97490792Sgshapiro } 97590792Sgshapiro ND_TCHECK_LEN(pptr, opli); 97690792Sgshapiro li_remaining -= opli; 97790792Sgshapiro tptr = pptr; 97890792Sgshapiro tlen = opli; 97990792Sgshapiro 98090792Sgshapiro ND_PRINT("\n\t %s Option #%u, length %u, value: ", 98190792Sgshapiro tok2str(clnp_option_values,"Unknown",op), 98290792Sgshapiro op, 98390792Sgshapiro opli); 98490792Sgshapiro 98590792Sgshapiro /* 98690792Sgshapiro * We've already checked that the entire option is present 98790792Sgshapiro * in the captured packet with the ND_TCHECK_LEN() call. 98890792Sgshapiro * Therefore, we don't need to do ND_TCHECK()/ND_TCHECK_LEN() 98990792Sgshapiro * checks. 99090792Sgshapiro * We do, however, need to check tlen, to make sure we 99190792Sgshapiro * don't run past the end of the option. 99290792Sgshapiro */ 99338032Speter switch (op) { 99438032Speter 99538032Speter 99638032Speter case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */ 99738032Speter case CLNP_OPTION_SOURCE_ROUTING: 99890792Sgshapiro if (tlen < 2) { 99938032Speter ND_PRINT(", bad opt len"); 100038032Speter return (0); 100138032Speter } 100238032Speter ND_PRINT("%s %s", 100338032Speter tok2str(clnp_option_sr_rr_values,"Unknown",GET_U_1(tptr)), 100464562Sgshapiro tok2str(clnp_option_sr_rr_string_values, "Unknown Option %u", op)); 100538032Speter nsap_offset=GET_U_1(tptr + 1); 100690792Sgshapiro if (nsap_offset == 0) { 100738032Speter ND_PRINT(" Bad NSAP offset (0)"); 100838032Speter break; 100964562Sgshapiro } 101038032Speter nsap_offset-=1; /* offset to nsap list */ 101138032Speter if (nsap_offset > tlen) { 101238032Speter ND_PRINT(" Bad NSAP offset (past end of option)"); 101364562Sgshapiro break; 101464562Sgshapiro } 101564562Sgshapiro tptr+=nsap_offset; 101664562Sgshapiro tlen-=nsap_offset; 101764562Sgshapiro while (tlen > 0) { 101890792Sgshapiro source_address_length=GET_U_1(tptr); 101990792Sgshapiro if (tlen < source_address_length+1) { 1020102528Sgshapiro ND_PRINT("\n\t NSAP address goes past end of option"); 1021102528Sgshapiro break; 1022102528Sgshapiro } 1023102528Sgshapiro if (source_address_length > 0) { 1024102528Sgshapiro source_address=(tptr+1); 1025102528Sgshapiro ND_PRINT("\n\t NSAP address (length %u): %s", 1026102528Sgshapiro source_address_length, 1027102528Sgshapiro GET_ISONSAP_STRING(source_address, source_address_length)); 1028102528Sgshapiro } 1029102528Sgshapiro tlen-=source_address_length+1; 103038032Speter } 103138032Speter break; 103264562Sgshapiro 103338032Speter case CLNP_OPTION_PRIORITY: 103438032Speter if (tlen < 1) { 103564562Sgshapiro ND_PRINT(", bad opt len"); 103638032Speter return (0); 103738032Speter } 103838032Speter ND_PRINT("0x%1x", GET_U_1(tptr)&0x0f); 103938032Speter break; 104090792Sgshapiro 104164562Sgshapiro case CLNP_OPTION_QOS_MAINTENANCE: 104238032Speter if (tlen < 1) { 104338032Speter ND_PRINT(", bad opt len"); 104438032Speter return (0); 104538032Speter } 104690792Sgshapiro ND_PRINT("\n\t Format Code: %s", 104764562Sgshapiro tok2str(clnp_option_scope_values, "Reserved", GET_U_1(tptr) & CLNP_OPTION_SCOPE_MASK)); 104838032Speter 104938032Speter if ((GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) 105038032Speter ND_PRINT("\n\t QoS Flags [%s]", 105190792Sgshapiro bittok2str(clnp_option_qos_global_values, 105238032Speter "none", 105390792Sgshapiro GET_U_1(tptr)&CLNP_OPTION_OPTION_QOS_MASK)); 105438032Speter break; 105538032Speter 105638032Speter case CLNP_OPTION_SECURITY: 105738032Speter if (tlen < 2) { 105838032Speter ND_PRINT(", bad opt len"); 105938032Speter return (0); 106038032Speter } 106138032Speter ND_PRINT("\n\t Format Code: %s, Security-Level %u", 106238032Speter tok2str(clnp_option_scope_values,"Reserved",GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK), 106338032Speter GET_U_1(tptr + 1)); 106438032Speter break; 106538032Speter 106638032Speter case CLNP_OPTION_DISCARD_REASON: 106738032Speter if (tlen < 1) { 106838032Speter ND_PRINT(", bad opt len"); 106938032Speter return (0); 107038032Speter } 107138032Speter rfd_error = GET_U_1(tptr); 107238032Speter rfd_error_major = (rfd_error&0xf0) >> 4; 107338032Speter rfd_error_minor = rfd_error&0x0f; 107438032Speter ND_PRINT("\n\t Class: %s Error (0x%01x), %s (0x%01x)", 107564562Sgshapiro tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major), 107638032Speter rfd_error_major, 107764562Sgshapiro tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor), 107838032Speter rfd_error_minor); 107964562Sgshapiro break; 108038032Speter 108164562Sgshapiro case CLNP_OPTION_PADDING: 108238032Speter ND_PRINT("padding data"); 108338032Speter break; 108438032Speter 108538032Speter /* 108638032Speter * FIXME those are the defined Options that lack a decoder 108738032Speter * you are welcome to contribute code ;-) 108838032Speter */ 108938032Speter 109038032Speter default: 109164562Sgshapiro print_unknown_data(ndo, tptr, "\n\t ", opli); 109238032Speter break; 109338032Speter } 109490792Sgshapiro if (ndo->ndo_vflag > 1) 109538032Speter print_unknown_data(ndo, pptr, "\n\t ", opli); 109638032Speter pptr += opli; 109738032Speter } 109838032Speter 109938032Speter switch (clnp_pdu_type) { 110038032Speter 110138032Speter case CLNP_PDU_ER: /* fall through */ 110238032Speter case CLNP_PDU_ERP: 110338032Speter if (GET_U_1(pptr) == NLPID_CLNP) { 110438032Speter ND_PRINT("\n\t-----original packet-----\n\t"); 110538032Speter /* FIXME recursion protection */ 110638032Speter clnp_print(ndo, pptr, length - li); 110738032Speter break; 110838032Speter } 110977349Sgshapiro 111038032Speter /* The cases above break from the switch block if they see and print 111138032Speter * a CLNP header in the Data part. For an Error Report PDU this is 111238032Speter * described in Section 7.9.6 of ITU X.233 (1997 E), also known as 111338032Speter * ISO/IEC 8473-1:1998(E). It is not clear why in this code the same 111438032Speter * applies to an Echo Response PDU, as the standard does not specify 111564562Sgshapiro * the contents -- could be a proprietary extension or a bug. In either 111638032Speter * case, if the Data part does not contain a CLNP header, its structure 111790792Sgshapiro * is considered unknown and the decoding falls through to print the 111890792Sgshapiro * contents as-is. 111990792Sgshapiro */ 112090792Sgshapiro ND_FALL_THROUGH; 112190792Sgshapiro 112290792Sgshapiro case CLNP_PDU_DT: 112390792Sgshapiro case CLNP_PDU_MD: 112490792Sgshapiro case CLNP_PDU_ERQ: 112590792Sgshapiro 112690792Sgshapiro default: 112790792Sgshapiro /* dump the PDU specific data */ 112890792Sgshapiro if (length > ND_BYTES_BETWEEN(pptr, optr)) { 112990792Sgshapiro ND_PRINT("\n\t undecoded non-header data, length %u", length-li); 113090792Sgshapiro print_unknown_data(ndo, pptr, "\n\t ", length - ND_BYTES_BETWEEN(pptr, optr)); 113190792Sgshapiro } 113290792Sgshapiro } 113390792Sgshapiro 113490792Sgshapiro return (1); 113590792Sgshapiro 113690792Sgshapiro trunc: 113790792Sgshapiro nd_print_trunc(ndo); 113890792Sgshapiro return (1); 113990792Sgshapiro 114090792Sgshapiro} 114190792Sgshapiro 114290792Sgshapiro 114390792Sgshapiro#define ESIS_PDU_REDIRECT 6 114490792Sgshapiro#define ESIS_PDU_ESH 2 114590792Sgshapiro#define ESIS_PDU_ISH 4 114690792Sgshapiro 114790792Sgshapirostatic const struct tok esis_pdu_values[] = { 114890792Sgshapiro { ESIS_PDU_REDIRECT, "redirect"}, 114990792Sgshapiro { ESIS_PDU_ESH, "ESH"}, 115090792Sgshapiro { ESIS_PDU_ISH, "ISH"}, 115190792Sgshapiro { 0, NULL } 115290792Sgshapiro}; 115390792Sgshapiro 115490792Sgshapirostruct esis_header_t { 115590792Sgshapiro nd_uint8_t nlpid; 115690792Sgshapiro nd_uint8_t length_indicator; 115790792Sgshapiro nd_uint8_t version; 115890792Sgshapiro nd_byte reserved; 115990792Sgshapiro nd_uint8_t type; 116090792Sgshapiro nd_uint16_t holdtime; 116190792Sgshapiro nd_uint16_t cksum; 116290792Sgshapiro}; 116390792Sgshapiro 116490792Sgshapirostatic void 116590792Sgshapiroesis_print(netdissect_options *ndo, 116690792Sgshapiro const uint8_t *pptr, u_int length) 116790792Sgshapiro{ 116890792Sgshapiro const uint8_t *optr; 116990792Sgshapiro u_int li, version, esis_pdu_type, source_address_length, source_address_number; 117090792Sgshapiro const struct esis_header_t *esis_header; 117190792Sgshapiro 117290792Sgshapiro ndo->ndo_protocol = "esis"; 117390792Sgshapiro if (!ndo->ndo_eflag) 117490792Sgshapiro ND_PRINT("ES-IS"); 117590792Sgshapiro 117690792Sgshapiro if (length <= 2) { 117790792Sgshapiro ND_PRINT(ndo->ndo_qflag ? "bad pkt!" : "no header at all!"); 117890792Sgshapiro return; 117990792Sgshapiro } 118090792Sgshapiro 118190792Sgshapiro esis_header = (const struct esis_header_t *) pptr; 118290792Sgshapiro ND_TCHECK_SIZE(esis_header); 118390792Sgshapiro li = GET_U_1(esis_header->length_indicator); 118438032Speter optr = pptr; 118538032Speter 118638032Speter /* 118738032Speter * Sanity checking of the header. 118838032Speter */ 118938032Speter 119038032Speter if (GET_U_1(esis_header->nlpid) != NLPID_ESIS) { 119138032Speter ND_PRINT(" nlpid 0x%02x packet not supported", 119290792Sgshapiro GET_U_1(esis_header->nlpid)); 119390792Sgshapiro return; 119490792Sgshapiro } 119590792Sgshapiro 119690792Sgshapiro version = GET_U_1(esis_header->version); 119790792Sgshapiro if (version != ESIS_VERSION) { 119890792Sgshapiro ND_PRINT(" version %u packet not supported", version); 119990792Sgshapiro return; 120090792Sgshapiro } 120190792Sgshapiro 120290792Sgshapiro if (li > length) { 120390792Sgshapiro ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length); 120490792Sgshapiro return; 120590792Sgshapiro } 120690792Sgshapiro 120790792Sgshapiro if (li < sizeof(struct esis_header_t) + 2) { 120890792Sgshapiro ND_PRINT(" length indicator %u < min PDU size:", li); 120990792Sgshapiro while (pptr < ndo->ndo_snapend) { 121090792Sgshapiro ND_PRINT("%02X", GET_U_1(pptr)); 121190792Sgshapiro pptr++; 121290792Sgshapiro } 121390792Sgshapiro return; 121490792Sgshapiro } 121590792Sgshapiro 121690792Sgshapiro esis_pdu_type = GET_U_1(esis_header->type) & ESIS_PDU_TYPE_MASK; 121790792Sgshapiro 121890792Sgshapiro if (ndo->ndo_vflag < 1) { 121990792Sgshapiro ND_PRINT("%s%s, length %u", 122090792Sgshapiro ndo->ndo_eflag ? "" : ", ", 122190792Sgshapiro tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type), 122290792Sgshapiro length); 122390792Sgshapiro return; 122490792Sgshapiro } else 122590792Sgshapiro ND_PRINT("%slength %u\n\t%s (%u)", 122690792Sgshapiro ndo->ndo_eflag ? "" : ", ", 122790792Sgshapiro length, 122890792Sgshapiro tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type), 122990792Sgshapiro esis_pdu_type); 123090792Sgshapiro 123138032Speter ND_PRINT(", v: %u%s", version, version == ESIS_VERSION ? "" : "unsupported" ); 123238032Speter ND_PRINT(", checksum: 0x%04x", GET_BE_U_2(esis_header->cksum)); 123338032Speter 123438032Speter osi_print_cksum(ndo, pptr, GET_BE_U_2(esis_header->cksum), 7, 123538032Speter li); 123638032Speter 123738032Speter ND_PRINT(", holding time: %us, length indicator: %u", 123838032Speter GET_BE_U_2(esis_header->holdtime), li); 123938032Speter 124038032Speter if (ndo->ndo_vflag > 1) 124138032Speter print_unknown_data(ndo, optr, "\n\t", sizeof(struct esis_header_t)); 124238032Speter 124338032Speter pptr += sizeof(struct esis_header_t); 124438032Speter li -= sizeof(struct esis_header_t); 124538032Speter 124664562Sgshapiro switch (esis_pdu_type) { 124738032Speter case ESIS_PDU_REDIRECT: { 124838032Speter const uint8_t *dst, *snpa, *neta; 124964562Sgshapiro u_int dstl, snpal, netal; 125038032Speter 125164562Sgshapiro ND_TCHECK_1(pptr); 125238032Speter if (li < 1) { 125338032Speter ND_PRINT(", bad redirect/li"); 125438032Speter return; 125538032Speter } 125638032Speter dstl = GET_U_1(pptr); 125738032Speter pptr++; 125838032Speter li--; 125938032Speter ND_TCHECK_LEN(pptr, dstl); 126038032Speter if (li < dstl) { 126138032Speter ND_PRINT(", bad redirect/li"); 126238032Speter return; 126390792Sgshapiro } 126438032Speter dst = pptr; 126590792Sgshapiro pptr += dstl; 126638032Speter li -= dstl; 126790792Sgshapiro ND_PRINT("\n\t %s", GET_ISONSAP_STRING(dst, dstl)); 126890792Sgshapiro 126938032Speter ND_TCHECK_1(pptr); 127038032Speter if (li < 1) { 127190792Sgshapiro ND_PRINT(", bad redirect/li"); 127290792Sgshapiro return; 127390792Sgshapiro } 127438032Speter snpal = GET_U_1(pptr); 127590792Sgshapiro pptr++; 127638032Speter li--; 127790792Sgshapiro ND_TCHECK_LEN(pptr, snpal); 127890792Sgshapiro if (li < snpal) { 127964562Sgshapiro ND_PRINT(", bad redirect/li"); 128090792Sgshapiro return; 128164562Sgshapiro } 128238032Speter snpa = pptr; 128338032Speter pptr += snpal; 128438032Speter li -= snpal; 128590792Sgshapiro ND_TCHECK_1(pptr); 128664562Sgshapiro if (li < 1) { 128790792Sgshapiro ND_PRINT(", bad redirect/li"); 128890792Sgshapiro return; 128990792Sgshapiro } 129064562Sgshapiro netal = GET_U_1(pptr); 129164562Sgshapiro pptr++; 129290792Sgshapiro ND_TCHECK_LEN(pptr, netal); 129364562Sgshapiro if (li < netal) { 129464562Sgshapiro ND_PRINT(", bad redirect/li"); 129590792Sgshapiro return; 129638032Speter } 129738032Speter neta = pptr; 129864562Sgshapiro pptr += netal; 129964562Sgshapiro li -= netal; 130038032Speter 130198121Sgshapiro if (snpal == MAC_ADDR_LEN) 130238032Speter ND_PRINT("\n\t SNPA (length: %u): %s", 130338032Speter snpal, 130464562Sgshapiro GET_ETHERADDR_STRING(snpa)); 130564562Sgshapiro else 130638032Speter ND_PRINT("\n\t SNPA (length: %u): %s", 130738032Speter snpal, 130838032Speter GET_LINKADDR_STRING(snpa, LINKADDR_OTHER, snpal)); 130938032Speter if (netal != 0) 131038032Speter ND_PRINT("\n\t NET (length: %u) %s", 131138032Speter netal, 131238032Speter GET_ISONSAP_STRING(neta, netal)); 131338032Speter break; 131438032Speter } 131538032Speter 131638032Speter case ESIS_PDU_ESH: 131790792Sgshapiro ND_TCHECK_1(pptr); 131838032Speter if (li < 1) { 131938032Speter ND_PRINT(", bad esh/li"); 132090792Sgshapiro return; 132138032Speter } 132238032Speter source_address_number = GET_U_1(pptr); 132390792Sgshapiro pptr++; 132438032Speter li--; 132538032Speter 132664562Sgshapiro ND_PRINT("\n\t Number of Source Addresses: %u", source_address_number); 132738032Speter 132838032Speter while (source_address_number > 0) { 132990792Sgshapiro ND_TCHECK_1(pptr); 133090792Sgshapiro if (li < 1) { 133190792Sgshapiro ND_PRINT(", bad esh/li"); 133290792Sgshapiro return; 133338032Speter } 133464562Sgshapiro source_address_length = GET_U_1(pptr); 133590792Sgshapiro pptr++; 133690792Sgshapiro li--; 133790792Sgshapiro 133890792Sgshapiro ND_TCHECK_LEN(pptr, source_address_length); 133938032Speter if (li < source_address_length) { 134038032Speter ND_PRINT(", bad esh/li"); 134138032Speter return; 134238032Speter } 134338032Speter ND_PRINT("\n\t NET (length: %u): %s", 134438032Speter source_address_length, 134538032Speter GET_ISONSAP_STRING(pptr, source_address_length)); 134638032Speter pptr += source_address_length; 134738032Speter li -= source_address_length; 134838032Speter source_address_number--; 134938032Speter } 135038032Speter 135138032Speter break; 135238032Speter 135338032Speter case ESIS_PDU_ISH: { 135438032Speter ND_TCHECK_1(pptr); 135538032Speter if (li < 1) { 135690792Sgshapiro ND_PRINT(", bad ish/li"); 135790792Sgshapiro return; 135838032Speter } 135990792Sgshapiro source_address_length = GET_U_1(pptr); 136090792Sgshapiro pptr++; 136190792Sgshapiro li--; 136290792Sgshapiro ND_TCHECK_LEN(pptr, source_address_length); 136390792Sgshapiro if (li < source_address_length) { 136438032Speter ND_PRINT(", bad ish/li"); 136590792Sgshapiro return; 136690792Sgshapiro } 136790792Sgshapiro ND_PRINT("\n\t NET (length: %u): %s", source_address_length, GET_ISONSAP_STRING(pptr, source_address_length)); 136838032Speter pptr += source_address_length; 136938032Speter li -= source_address_length; 137038032Speter break; 137138032Speter } 137238032Speter 137364562Sgshapiro default: 137464562Sgshapiro if (ndo->ndo_vflag <= 1) { 137564562Sgshapiro /* 137638032Speter * If there's at least one byte to print, print 137738032Speter * it/them. 137838032Speter */ 137938032Speter if (ND_TTEST_LEN(pptr, 1)) 138038032Speter print_unknown_data(ndo, pptr, "\n\t ", ND_BYTES_AVAILABLE_AFTER(pptr)); 138190792Sgshapiro } 138238032Speter return; 138338032Speter } 138438032Speter 138538032Speter /* now walk the options */ 138638032Speter while (li != 0) { 138738032Speter u_int op, opli; 138838032Speter const uint8_t *tptr; 138938032Speter 139038032Speter if (li < 2) { 139138032Speter ND_PRINT(", bad opts/li"); 139238032Speter return; 139338032Speter } 139438032Speter op = GET_U_1(pptr); 139538032Speter opli = GET_U_1(pptr + 1); 139638032Speter pptr += 2; 139738032Speter li -= 2; 139838032Speter if (opli > li) { 139938032Speter ND_PRINT(", opt (%u) too long", op); 140038032Speter return; 140138032Speter } 140238032Speter li -= opli; 140338032Speter tptr = pptr; 140438032Speter 140538032Speter ND_PRINT("\n\t %s Option #%u, length %u, value: ", 140638032Speter tok2str(esis_option_values,"Unknown",op), 140738032Speter op, 140890792Sgshapiro opli); 140938032Speter 141038032Speter switch (op) { 141164562Sgshapiro 141264562Sgshapiro case ESIS_OPTION_ES_CONF_TIME: 141390792Sgshapiro if (opli == 2) { 141490792Sgshapiro ND_TCHECK_2(pptr); 141538032Speter ND_PRINT("%us", GET_BE_U_2(tptr)); 141638032Speter } else 141738032Speter ND_PRINT("(bad length)"); 141838032Speter break; 141938032Speter 142038032Speter case ESIS_OPTION_PROTOCOLS: 142138032Speter while (opli>0) { 142238032Speter ND_PRINT("%s (0x%02x)", 142338032Speter tok2str(nlpid_values, 142438032Speter "unknown", 142538032Speter GET_U_1(tptr)), 142673188Sgshapiro GET_U_1(tptr)); 142790792Sgshapiro if (opli>1) /* further NPLIDs ? - put comma */ 142838032Speter ND_PRINT(", "); 142938032Speter tptr++; 143073188Sgshapiro opli--; 143173188Sgshapiro } 143273188Sgshapiro break; 143373188Sgshapiro 143473188Sgshapiro /* 143573188Sgshapiro * FIXME those are the defined Options that lack a decoder 143673188Sgshapiro * you are welcome to contribute code ;-) 143773188Sgshapiro */ 143838032Speter 143938032Speter case ESIS_OPTION_QOS_MAINTENANCE: 144038032Speter case ESIS_OPTION_SECURITY: 144138032Speter case ESIS_OPTION_PRIORITY: 144238032Speter case ESIS_OPTION_ADDRESS_MASK: 144338032Speter case ESIS_OPTION_SNPA_MASK: 144438032Speter 144538032Speter default: 144664562Sgshapiro print_unknown_data(ndo, tptr, "\n\t ", opli); 144764562Sgshapiro break; 144864562Sgshapiro } 144990792Sgshapiro if (ndo->ndo_vflag > 1) 145090792Sgshapiro print_unknown_data(ndo, pptr, "\n\t ", opli); 145190792Sgshapiro pptr += opli; 145290792Sgshapiro } 145390792Sgshapiro return; 145464562Sgshapiro 145538032Spetertrunc: 145638032Speter nd_print_trunc(ndo); 145738032Speter} 145864562Sgshapiro 145964562Sgshapirostatic void 146038032Speterisis_print_mcid(netdissect_options *ndo, 146138032Speter const struct isis_spb_mcid *mcid) 146290792Sgshapiro{ 146338032Speter int i; 146438032Speter 146590792Sgshapiro ND_TCHECK_SIZE(mcid); 146690792Sgshapiro ND_PRINT("ID: %u, Name: ", GET_U_1(mcid->format_id)); 146790792Sgshapiro 146890792Sgshapiro nd_printjnp(ndo, mcid->name, sizeof(mcid->name)); 146990792Sgshapiro 147090792Sgshapiro ND_PRINT("\n\t Lvl: %u", GET_BE_U_2(mcid->revision_lvl)); 147190792Sgshapiro 147290792Sgshapiro ND_PRINT(", Digest: "); 147390792Sgshapiro 147490792Sgshapiro for(i=0;i<16;i++) 147590792Sgshapiro ND_PRINT("%.2x ", mcid->digest[i]); 147690792Sgshapiro return; 147790792Sgshapiro 147890792Sgshapirotrunc: 147990792Sgshapiro nd_print_trunc(ndo); 148090792Sgshapiro} 148190792Sgshapiro 148290792Sgshapirostatic int 148390792Sgshapiroisis_print_mt_port_cap_subtlv(netdissect_options *ndo, 148490792Sgshapiro const uint8_t *tptr, u_int len) 148590792Sgshapiro{ 148690792Sgshapiro u_int stlv_type, stlv_len; 148790792Sgshapiro const struct isis_subtlv_spb_mcid *subtlv_spb_mcid; 148890792Sgshapiro int i; 148990792Sgshapiro 149090792Sgshapiro while (len > 2) 149190792Sgshapiro { 149290792Sgshapiro stlv_type = GET_U_1(tptr); 149390792Sgshapiro stlv_len = GET_U_1(tptr + 1); 149464562Sgshapiro 149564562Sgshapiro /* first lets see if we know the subTLVs name*/ 149690792Sgshapiro ND_PRINT("\n\t %s subTLV #%u, length: %u", 149790792Sgshapiro tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type), 149890792Sgshapiro stlv_type, 149990792Sgshapiro stlv_len); 150090792Sgshapiro 150190792Sgshapiro tptr += 2; 150290792Sgshapiro /*len -= TLV_TYPE_LEN_OFFSET;*/ 150390792Sgshapiro len -= 2; 150464562Sgshapiro 150564562Sgshapiro /* Make sure the subTLV fits within the space left */ 150638032Speter if (len < stlv_len) 150738032Speter goto subtlv_too_long; 150838032Speter /* Make sure the entire subTLV is in the captured data */ 150990792Sgshapiro ND_TCHECK_LEN(tptr, stlv_len); 151090792Sgshapiro 151138032Speter switch (stlv_type) 151238032Speter { 151338032Speter case ISIS_SUBTLV_SPB_MCID: 151438032Speter { 151590792Sgshapiro if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN) 151638032Speter goto subtlv_too_short; 151790792Sgshapiro 151890792Sgshapiro subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr; 151990792Sgshapiro 152038032Speter ND_PRINT("\n\t MCID: "); 152138032Speter isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid)); 152238032Speter 152390792Sgshapiro /*tptr += SPB_MCID_MIN_LEN; 152490792Sgshapiro len -= SPB_MCID_MIN_LEN; */ 152538032Speter 152638032Speter ND_PRINT("\n\t AUX-MCID: "); 152738032Speter isis_print_mcid(ndo, &(subtlv_spb_mcid->aux_mcid)); 152838032Speter 152938032Speter /*tptr += SPB_MCID_MIN_LEN; 153038032Speter len -= SPB_MCID_MIN_LEN; */ 153138032Speter tptr += ISIS_SUBTLV_SPB_MCID_MIN_LEN; 153238032Speter len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN; 153366494Sgshapiro stlv_len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN; 153438032Speter 153538032Speter break; 153666494Sgshapiro } 153766494Sgshapiro 153838032Speter case ISIS_SUBTLV_SPB_DIGEST: 153938032Speter { 154038032Speter if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN) 154138032Speter goto subtlv_too_short; 154238032Speter 154338032Speter ND_PRINT("\n\t RES: %u V: %u A: %u D: %u", 154490792Sgshapiro (GET_U_1(tptr) >> 5), 154564562Sgshapiro ((GET_U_1(tptr) >> 4) & 0x01), 154664562Sgshapiro ((GET_U_1(tptr) >> 2) & 0x03), 154764562Sgshapiro (GET_U_1(tptr) & 0x03)); 154864562Sgshapiro 154990792Sgshapiro tptr++; 155064562Sgshapiro 155190792Sgshapiro ND_PRINT("\n\t Digest: "); 155238032Speter 155338032Speter for(i=1;i<=8; i++) 155473188Sgshapiro { 155590792Sgshapiro ND_PRINT("%08x ", GET_BE_U_4(tptr)); 155638032Speter if (i%4 == 0 && i != 8) 155738032Speter ND_PRINT("\n\t "); 155890792Sgshapiro tptr += 4; 155990792Sgshapiro } 156090792Sgshapiro 156164562Sgshapiro len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; 1562102528Sgshapiro stlv_len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; 1563102528Sgshapiro 156438032Speter break; 156538032Speter } 156642575Speter 156742575Speter case ISIS_SUBTLV_SPB_BVID: 156864562Sgshapiro { 156942575Speter while (stlv_len != 0) 157090792Sgshapiro { 157164562Sgshapiro if (stlv_len < 4) 157238032Speter goto subtlv_too_short; 157338032Speter ND_PRINT("\n\t ECT: %08x", 157438032Speter GET_BE_U_4(tptr)); 157564562Sgshapiro 157664562Sgshapiro tptr += 4; 157790792Sgshapiro len -= 4; 157838032Speter stlv_len -= 4; 157938032Speter 158090792Sgshapiro if (stlv_len < 2) 158190792Sgshapiro goto subtlv_too_short; 158290792Sgshapiro ND_PRINT(" BVID: %u, U:%01x M:%01x ", 158390792Sgshapiro (GET_BE_U_2(tptr) >> 4) , 158490792Sgshapiro (GET_BE_U_2(tptr) >> 3) & 0x01, 158590792Sgshapiro (GET_BE_U_2(tptr) >> 2) & 0x01); 158690792Sgshapiro 158790792Sgshapiro tptr += 2; 158890792Sgshapiro len -= 2; 158990792Sgshapiro stlv_len -= 2; 159090792Sgshapiro } 159190792Sgshapiro 159290792Sgshapiro break; 159390792Sgshapiro } 159442575Speter 159542575Speter default: 159642575Speter break; 159742575Speter } 159890792Sgshapiro tptr += stlv_len; 159990792Sgshapiro len -= stlv_len; 160042575Speter } 160138032Speter return (0); 160264562Sgshapiro 160364562Sgshapirotrunc: 160464562Sgshapiro nd_print_trunc(ndo); 160564562Sgshapiro return (1); 160642575Speter 160742575Spetersubtlv_too_long: 160864562Sgshapiro ND_PRINT(" (> containing TLV length)"); 160964562Sgshapiro return (1); 161064562Sgshapiro 161142575Spetersubtlv_too_short: 161264562Sgshapiro ND_PRINT(" (too short)"); 161342575Speter return (1); 161442575Speter} 161542575Speter 161642575Speterstatic int 161738032Speterisis_print_mt_capability_subtlv(netdissect_options *ndo, 161838032Speter const uint8_t *tptr, u_int len) 161938032Speter{ 162038032Speter u_int stlv_type, stlv_len, treecount; 162138032Speter 162238032Speter while (len > 2) 162338032Speter { 162438032Speter stlv_type = GET_U_1(tptr); 162538032Speter stlv_len = GET_U_1(tptr + 1); 162638032Speter tptr += 2; 1627110560Sgshapiro len -= 2; 1628110560Sgshapiro 1629110560Sgshapiro /* first lets see if we know the subTLVs name*/ 1630110560Sgshapiro ND_PRINT("\n\t %s subTLV #%u, length: %u", 1631110560Sgshapiro tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type), 1632110560Sgshapiro stlv_type, 163338032Speter stlv_len); 1634110560Sgshapiro 1635110560Sgshapiro /* Make sure the subTLV fits within the space left */ 1636110560Sgshapiro if (len < stlv_len) 1637110560Sgshapiro goto subtlv_too_long; 163838032Speter /* Make sure the entire subTLV is in the captured data */ 163938032Speter ND_TCHECK_LEN(tptr, stlv_len); 164038032Speter 164138032Speter switch (stlv_type) 164238032Speter { 164338032Speter case ISIS_SUBTLV_SPB_INSTANCE: 164438032Speter if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN) 164538032Speter goto subtlv_too_short; 164638032Speter 164738032Speter ND_PRINT("\n\t CIST Root-ID: %08x", GET_BE_U_4(tptr)); 164838032Speter tptr += 4; 164938032Speter ND_PRINT(" %08x", GET_BE_U_4(tptr)); 165038032Speter tptr += 4; 165164562Sgshapiro ND_PRINT(", Path Cost: %08x", GET_BE_U_4(tptr)); 165238032Speter tptr += 4; 165338032Speter ND_PRINT(", Prio: %u", GET_BE_U_2(tptr)); 165438032Speter tptr += 2; 165538032Speter ND_PRINT("\n\t RES: %u", 165638032Speter GET_BE_U_2(tptr) >> 5); 165738032Speter ND_PRINT(", V: %u", 165838032Speter (GET_BE_U_2(tptr) >> 4) & 0x0001); 165938032Speter ND_PRINT(", SPSource-ID: %u", 166038032Speter (GET_BE_U_4(tptr) & 0x000fffff)); 166138032Speter tptr += 4; 166238032Speter ND_PRINT(", No of Trees: %x", GET_U_1(tptr)); 166338032Speter 166490792Sgshapiro treecount = GET_U_1(tptr); 166538032Speter tptr++; 166638032Speter 166738032Speter len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; 166890792Sgshapiro stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; 166938032Speter 167038032Speter while (treecount) 167138032Speter { 167238032Speter if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN) 167338032Speter goto trunc; 167438032Speter 167538032Speter ND_PRINT("\n\t U:%u, M:%u, A:%u, RES:%u", 167638032Speter GET_U_1(tptr) >> 7, 167738032Speter (GET_U_1(tptr) >> 6) & 0x01, 167864562Sgshapiro (GET_U_1(tptr) >> 5) & 0x01, 167990792Sgshapiro (GET_U_1(tptr) & 0x1f)); 168090792Sgshapiro 168138032Speter tptr++; 168238032Speter 168338032Speter ND_PRINT(", ECT: %08x", GET_BE_U_4(tptr)); 168464562Sgshapiro 168538032Speter tptr += 4; 168638032Speter 168738032Speter ND_PRINT(", BVID: %u, SPVID: %u", 168838032Speter (GET_BE_U_3(tptr) >> 12) & 0x000fff, 168938032Speter GET_BE_U_3(tptr) & 0x000fff); 169090792Sgshapiro 169190792Sgshapiro tptr += 3; 169290792Sgshapiro len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; 169390792Sgshapiro stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; 169438032Speter treecount--; 169538032Speter } 169638032Speter 169790792Sgshapiro break; 169838032Speter 169938032Speter case ISIS_SUBTLV_SPBM_SI: 170038032Speter if (stlv_len < 8) 170138032Speter goto trunc; 170238032Speter 170338032Speter ND_PRINT("\n\t BMAC: %08x", GET_BE_U_4(tptr)); 170438032Speter tptr += 4; 170538032Speter ND_PRINT("%04x", GET_BE_U_2(tptr)); 170638032Speter tptr += 2; 170738032Speter 170838032Speter ND_PRINT(", RES: %u, VID: %u", GET_BE_U_2(tptr) >> 12, 170964562Sgshapiro (GET_BE_U_2(tptr)) & 0x0fff); 171064562Sgshapiro 171190792Sgshapiro tptr += 2; 171238032Speter len -= 8; 171338032Speter stlv_len -= 8; 171438032Speter 171590792Sgshapiro while (stlv_len >= 4) { 171638032Speter ND_PRINT("\n\t T: %u, R: %u, RES: %u, ISID: %u", 171764562Sgshapiro (GET_BE_U_4(tptr) >> 31), 171864562Sgshapiro (GET_BE_U_4(tptr) >> 30) & 0x01, 171964562Sgshapiro (GET_BE_U_4(tptr) >> 24) & 0x03f, 172064562Sgshapiro (GET_BE_U_4(tptr)) & 0x0ffffff); 172164562Sgshapiro 172264562Sgshapiro tptr += 4; 172364562Sgshapiro len -= 4; 172490792Sgshapiro stlv_len -= 4; 172590792Sgshapiro } 172664562Sgshapiro 172790792Sgshapiro break; 172890792Sgshapiro 172964562Sgshapiro default: 173090792Sgshapiro break; 173190792Sgshapiro } 173264562Sgshapiro tptr += stlv_len; 173364562Sgshapiro len -= stlv_len; 173464562Sgshapiro } 173590792Sgshapiro return (0); 173690792Sgshapiro 173764562Sgshapirotrunc: 173864562Sgshapiro nd_print_trunc(ndo); 173964562Sgshapiro return (1); 174090792Sgshapiro 174190792Sgshapirosubtlv_too_long: 174264562Sgshapiro ND_PRINT(" (> containing TLV length)"); 174364562Sgshapiro return (1); 174490792Sgshapiro 174590792Sgshapirosubtlv_too_short: 174664562Sgshapiro ND_PRINT(" (too short)"); 174738032Speter return (1); 174838032Speter} 174938032Speter 175038032Speter/* shared routine for printing system, node and lsp-ids */ 175138032Speterstatic char * 175238032Speterisis_print_id(netdissect_options *ndo, const uint8_t *cp, u_int id_len) 175338032Speter{ 175490792Sgshapiro u_int i; 175538032Speter static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; 175638032Speter char *pos = id; 175738032Speter u_int sysid_len; 175838032Speter 175938032Speter sysid_len = SYSTEM_ID_LEN; 176038032Speter if (sysid_len > id_len) 176138032Speter sysid_len = id_len; 176238032Speter for (i = 1; i <= sysid_len; i++) { 176338032Speter snprintf(pos, sizeof(id) - (pos - id), "%02x", GET_U_1(cp)); 176464562Sgshapiro cp++; 176538032Speter pos += strlen(pos); 176690792Sgshapiro if (i == 2 || i == 4) 176790792Sgshapiro *pos++ = '.'; 176838032Speter } 176938032Speter if (id_len >= NODE_ID_LEN) { 177038032Speter snprintf(pos, sizeof(id) - (pos - id), ".%02x", GET_U_1(cp)); 177190792Sgshapiro cp++; 177290792Sgshapiro pos += strlen(pos); 177390792Sgshapiro } 177490792Sgshapiro if (id_len == LSP_ID_LEN) 177590792Sgshapiro snprintf(pos, sizeof(id) - (pos - id), "-%02x", GET_U_1(cp)); 177690792Sgshapiro return (id); 177764562Sgshapiro} 177890792Sgshapiro 177990792Sgshapiro/* print the 4-byte metric block which is common found in the old-style TLVs */ 178090792Sgshapirostatic int 178164562Sgshapiroisis_print_metric_block(netdissect_options *ndo, 178290792Sgshapiro const struct isis_metric_block *isis_metric_block) 178390792Sgshapiro{ 178490792Sgshapiro ND_PRINT(", Default Metric: %u, %s", 178590792Sgshapiro ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), 178690792Sgshapiro ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); 178790792Sgshapiro if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) 178890792Sgshapiro ND_PRINT("\n\t\t Delay Metric: %u, %s", 178990792Sgshapiro ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), 179038032Speter ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); 179138032Speter if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) 179238032Speter ND_PRINT("\n\t\t Expense Metric: %u, %s", 179338032Speter ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), 179438032Speter ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); 179538032Speter if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) 179690792Sgshapiro ND_PRINT("\n\t\t Error Metric: %u, %s", 179738032Speter ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), 179890792Sgshapiro ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); 179990792Sgshapiro 180090792Sgshapiro return(1); /* everything is ok */ 180190792Sgshapiro} 180290792Sgshapiro 180390792Sgshapirostatic int 180490792Sgshapiroisis_print_tlv_ip_reach(netdissect_options *ndo, 180590792Sgshapiro const uint8_t *cp, const char *ident, u_int length) 180638032Speter{ 180738032Speter int prefix_len; 180838032Speter const struct isis_tlv_ip_reach *tlv_ip_reach; 180938032Speter 181038032Speter tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; 181138032Speter 181238032Speter while (length > 0) { 181338032Speter if ((size_t)length < sizeof(*tlv_ip_reach)) { 181438032Speter ND_PRINT("short IPv4 Reachability (%u vs %zu)", 181538032Speter length, 181638032Speter sizeof(*tlv_ip_reach)); 181764562Sgshapiro return (0); 181838032Speter } 181938032Speter 182038032Speter ND_TCHECK_SIZE(tlv_ip_reach); 182138032Speter 182238032Speter prefix_len = mask2plen(GET_IPV4_TO_HOST_ORDER(tlv_ip_reach->mask)); 182338032Speter 182438032Speter if (prefix_len == -1) 182564562Sgshapiro ND_PRINT("%sIPv4 prefix: %s mask %s", 182638032Speter ident, 182738032Speter GET_IPADDR_STRING(tlv_ip_reach->prefix), 182838032Speter GET_IPADDR_STRING(tlv_ip_reach->mask)); 182990792Sgshapiro else 183038032Speter ND_PRINT("%sIPv4 prefix: %15s/%u", 183138032Speter ident, 183238032Speter GET_IPADDR_STRING(tlv_ip_reach->prefix), 183373188Sgshapiro prefix_len); 183438032Speter 183538032Speter ND_PRINT(", Distribution: %s, Metric: %u, %s", 183638032Speter ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", 183738032Speter ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), 183838032Speter ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); 183938032Speter 184038032Speter if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) 184138032Speter ND_PRINT("%s Delay Metric: %u, %s", 184238032Speter ident, 184338032Speter ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), 184438032Speter ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); 184538032Speter 184638032Speter if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) 184738032Speter ND_PRINT("%s Expense Metric: %u, %s", 184838032Speter ident, 184938032Speter ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), 185038032Speter ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); 185138032Speter 185238032Speter if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) 185338032Speter ND_PRINT("%s Error Metric: %u, %s", 185490792Sgshapiro ident, 185590792Sgshapiro ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), 185690792Sgshapiro ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); 185738032Speter 185838032Speter length -= sizeof(struct isis_tlv_ip_reach); 185964562Sgshapiro tlv_ip_reach++; 186038032Speter } 186138032Speter return (1); 186238032Spetertrunc: 186338032Speter return 0; 186438032Speter} 186538032Speter 186638032Speter/* 186764562Sgshapiro * this is the common IP-REACH subTLV decoder it is called 186838032Speter * from various EXTD-IP REACH TLVs (135,235,236,237) 186964562Sgshapiro */ 187064562Sgshapiro 187190792Sgshapirostatic int 187238032Speterisis_print_ip_reach_subtlv(netdissect_options *ndo, 187338032Speter const uint8_t *tptr, u_int subt, u_int subl, 187438032Speter const char *ident) 187538032Speter{ 187638032Speter /* first lets see if we know the subTLVs name*/ 187738032Speter ND_PRINT("%s%s subTLV #%u, length: %u", 187838032Speter ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt), 187938032Speter subt, subl); 188038032Speter 188138032Speter ND_TCHECK_LEN(tptr, subl); 188290792Sgshapiro 188390792Sgshapiro switch(subt) { 188490792Sgshapiro case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ 188590792Sgshapiro case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: 188690792Sgshapiro while (subl >= 4) { 188790792Sgshapiro ND_PRINT(", 0x%08x (=%u)", 188890792Sgshapiro GET_BE_U_4(tptr), 188990792Sgshapiro GET_BE_U_4(tptr)); 189090792Sgshapiro tptr+=4; 189190792Sgshapiro subl-=4; 189290792Sgshapiro } 189390792Sgshapiro break; 189490792Sgshapiro case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: 189590792Sgshapiro while (subl >= 8) { 189690792Sgshapiro ND_PRINT(", 0x%08x%08x", 189790792Sgshapiro GET_BE_U_4(tptr), 189890792Sgshapiro GET_BE_U_4(tptr + 4)); 189990792Sgshapiro tptr+=8; 190090792Sgshapiro subl-=8; 190190792Sgshapiro } 190290792Sgshapiro break; 190390792Sgshapiro case ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID: 190490792Sgshapiro { 190590792Sgshapiro uint8_t algo, flags; 190690792Sgshapiro uint32_t sid; 190790792Sgshapiro 190890792Sgshapiro flags = GET_U_1(tptr); 190990792Sgshapiro algo = GET_U_1(tptr+1); 191090792Sgshapiro 191190792Sgshapiro if (flags & ISIS_PREFIX_SID_FLAG_V) { 191290792Sgshapiro if (subl < 5) 191390792Sgshapiro goto trunc; 191490792Sgshapiro sid = GET_BE_U_3(tptr+2); 191590792Sgshapiro tptr+=5; 191690792Sgshapiro subl-=5; 191790792Sgshapiro } else { 191890792Sgshapiro if (subl < 6) 191990792Sgshapiro goto trunc; 192038032Speter sid = GET_BE_U_4(tptr+2); 192138032Speter tptr+=6; 192290792Sgshapiro subl-=6; 192338032Speter } 192490792Sgshapiro 192538032Speter ND_PRINT(", Flags [%s], Algo %s (%u), %s %u", 192638032Speter bittok2str(prefix_sid_flag_values, "None", flags), 192738032Speter tok2str(prefix_sid_algo_values, "Unknown", algo), algo, 192838032Speter flags & ISIS_PREFIX_SID_FLAG_V ? "label" : "index", 192938032Speter sid); 193064562Sgshapiro } 193138032Speter break; 193238032Speter default: 193338032Speter if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl)) 193438032Speter return(0); 193564562Sgshapiro break; 193664562Sgshapiro } 193764562Sgshapiro return(1); 193864562Sgshapiro 193964562Sgshapirotrunc: 194064562Sgshapiro nd_print_trunc(ndo); 194164562Sgshapiro return(0); 194264562Sgshapiro} 194364562Sgshapiro 194464562Sgshapiro/* 194564562Sgshapiro * this is the common IS-REACH decoder it is called 194664562Sgshapiro * from various EXTD-IS REACH style TLVs (22,24,222) 194738032Speter */ 194838032Speter 194938032Speterstatic int 195038032Speterisis_print_ext_is_reach(netdissect_options *ndo, 195138032Speter const uint8_t *tptr, const char *ident, u_int tlv_type, 195238032Speter u_int tlv_remaining) 195338032Speter{ 195438032Speter char ident_buffer[20]; 195538032Speter u_int subtlv_type,subtlv_len,subtlv_sum_len; 195638032Speter int proc_bytes = 0; /* how many bytes did we process ? */ 195764562Sgshapiro u_int te_class,priority_level,gmpls_switch_cap; 195838032Speter union { /* int to float conversion buffer for several subTLVs */ 195938032Speter float f; 196038032Speter uint32_t i; 196164562Sgshapiro } bw; 196264562Sgshapiro 196364562Sgshapiro ND_TCHECK_LEN(tptr, NODE_ID_LEN); 196464562Sgshapiro if (tlv_remaining < NODE_ID_LEN) 196564562Sgshapiro return(0); 196638032Speter 196790792Sgshapiro ND_PRINT("%sIS Neighbor: %s", ident, isis_print_id(ndo, tptr, NODE_ID_LEN)); 196838032Speter tptr+=NODE_ID_LEN; 196938032Speter tlv_remaining-=NODE_ID_LEN; 197064562Sgshapiro proc_bytes+=NODE_ID_LEN; 197164562Sgshapiro 197264562Sgshapiro if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ 197338032Speter ND_TCHECK_3(tptr); 197438032Speter if (tlv_remaining < 3) 197538032Speter return(0); 197638032Speter ND_PRINT(", Metric: %u", GET_BE_U_3(tptr)); 197738032Speter tptr+=3; 197838032Speter tlv_remaining-=3; 197964562Sgshapiro proc_bytes+=3; 198038032Speter } 198138032Speter 198264562Sgshapiro ND_TCHECK_1(tptr); 198364562Sgshapiro if (tlv_remaining < 1) 198490792Sgshapiro return(0); 198590792Sgshapiro subtlv_sum_len=GET_U_1(tptr); /* read out subTLV length */ 198638032Speter tptr++; 198764562Sgshapiro tlv_remaining--; 198838032Speter proc_bytes++; 198964562Sgshapiro ND_PRINT(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); 199064562Sgshapiro if (subtlv_sum_len) { 199138032Speter ND_PRINT(" (%u)", subtlv_sum_len); 199238032Speter /* prepend the indent string */ 199364562Sgshapiro snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 199464562Sgshapiro ident = ident_buffer; 199538032Speter while (subtlv_sum_len != 0) { 199664562Sgshapiro ND_TCHECK_2(tptr); 199764562Sgshapiro if (tlv_remaining < 2) { 199864562Sgshapiro ND_PRINT("%sRemaining data in TLV shorter than a subTLV header",ident); 199964562Sgshapiro proc_bytes += tlv_remaining; 200064562Sgshapiro break; 200164562Sgshapiro } 200264562Sgshapiro if (subtlv_sum_len < 2) { 200364562Sgshapiro ND_PRINT("%sRemaining data in subTLVs shorter than a subTLV header",ident); 200464562Sgshapiro proc_bytes += subtlv_sum_len; 200564562Sgshapiro break; 200664562Sgshapiro } 200764562Sgshapiro subtlv_type=GET_U_1(tptr); 200864562Sgshapiro subtlv_len=GET_U_1(tptr + 1); 200964562Sgshapiro tptr += 2; 201064562Sgshapiro tlv_remaining -= 2; 201190792Sgshapiro subtlv_sum_len -= 2; 201290792Sgshapiro proc_bytes += 2; 201390792Sgshapiro ND_PRINT("%s%s subTLV #%u, length: %u", 201490792Sgshapiro ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subtlv_type), 201590792Sgshapiro subtlv_type, subtlv_len); 201690792Sgshapiro 201790792Sgshapiro if (subtlv_sum_len < subtlv_len) { 201890792Sgshapiro ND_PRINT(" (remaining data in subTLVs shorter than the current subTLV)"); 201990792Sgshapiro proc_bytes += subtlv_sum_len; 202090792Sgshapiro break; 202190792Sgshapiro } 202290792Sgshapiro 202390792Sgshapiro if (tlv_remaining < subtlv_len) { 202490792Sgshapiro ND_PRINT(" (> remaining tlv length)"); 202590792Sgshapiro proc_bytes += tlv_remaining; 202690792Sgshapiro break; 202790792Sgshapiro } 202890792Sgshapiro 202964562Sgshapiro ND_TCHECK_LEN(tptr, subtlv_len); 203064562Sgshapiro 203138032Speter switch(subtlv_type) { 203264562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: 203364562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: 203464562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: 203538032Speter if (subtlv_len >= 4) { 203638032Speter ND_PRINT(", 0x%08x", GET_BE_U_4(tptr)); 203790792Sgshapiro if (subtlv_len == 8) /* rfc4205 */ 203890792Sgshapiro ND_PRINT(", 0x%08x", GET_BE_U_4(tptr + 4)); 203964562Sgshapiro } 204064562Sgshapiro break; 204164562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: 204238032Speter case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: 204338032Speter if (subtlv_len >= sizeof(nd_ipv4)) 204438032Speter ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); 204538032Speter break; 204638032Speter case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : 204738032Speter case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: 204890792Sgshapiro if (subtlv_len >= 4) { 204990792Sgshapiro bw.i = GET_BE_U_4(tptr); 205038032Speter ND_PRINT(", %.3f Mbps", bw.f * 8 / 1000000); 205138032Speter } 205290792Sgshapiro break; 205390792Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : 205438032Speter if (subtlv_len >= 32) { 205538032Speter for (te_class = 0; te_class < 8; te_class++) { 205690792Sgshapiro bw.i = GET_BE_U_4(tptr); 205790792Sgshapiro ND_PRINT("%s TE-Class %u: %.3f Mbps", 205890792Sgshapiro ident, 205990792Sgshapiro te_class, 206090792Sgshapiro bw.f * 8 / 1000000); 206190792Sgshapiro tptr += 4; 206290792Sgshapiro subtlv_len -= 4; 206390792Sgshapiro subtlv_sum_len -= 4; 206464562Sgshapiro proc_bytes += 4; 206538032Speter } 206638032Speter } 206738032Speter break; 206838032Speter case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ 206938032Speter case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: 207038032Speter if (subtlv_len == 0) 207190792Sgshapiro break; 207238032Speter ND_PRINT("%sBandwidth Constraints Model ID: %s (%u)", 207338032Speter ident, 207438032Speter tok2str(diffserv_te_bc_values, "unknown", GET_U_1(tptr)), 207538032Speter GET_U_1(tptr)); 207638032Speter tptr++; 207738032Speter subtlv_len--; 207890792Sgshapiro subtlv_sum_len--; 207938032Speter proc_bytes++; 208038032Speter /* decode BCs until the subTLV ends */ 208138032Speter for (te_class = 0; subtlv_len != 0; te_class++) { 208238032Speter if (subtlv_len < 4) 208390792Sgshapiro break; 208464562Sgshapiro bw.i = GET_BE_U_4(tptr); 208564562Sgshapiro ND_PRINT("%s Bandwidth constraint CT%u: %.3f Mbps", 208664562Sgshapiro ident, 208764562Sgshapiro te_class, 208864562Sgshapiro bw.f * 8 / 1000000); 208938032Speter tptr += 4; 209064562Sgshapiro subtlv_len -= 4; 209190792Sgshapiro subtlv_sum_len -= 4; 209264562Sgshapiro proc_bytes += 4; 209338032Speter } 209464562Sgshapiro break; 209564562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: 209664562Sgshapiro if (subtlv_len >= 3) 209764562Sgshapiro ND_PRINT(", %u", GET_BE_U_3(tptr)); 209864562Sgshapiro break; 209964562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE: 210064562Sgshapiro if (subtlv_len == 2) { 210164562Sgshapiro ND_PRINT(", [ %s ] (0x%04x)", 210264562Sgshapiro bittok2str(isis_subtlv_link_attribute_values, 210390792Sgshapiro "Unknown", 210490792Sgshapiro GET_BE_U_2(tptr)), 210564562Sgshapiro GET_BE_U_2(tptr)); 210677349Sgshapiro } 210738032Speter break; 210864562Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: 210938032Speter if (subtlv_len >= 2) { 211064562Sgshapiro ND_PRINT(", %s, Priority %u", 211138032Speter bittok2str(gmpls_link_prot_values, "none", GET_U_1(tptr)), 211264562Sgshapiro GET_U_1(tptr + 1)); 211390792Sgshapiro } 211490792Sgshapiro break; 211590792Sgshapiro case ISIS_SUBTLV_SPB_METRIC: 211690792Sgshapiro if (subtlv_len >= 6) { 211790792Sgshapiro ND_PRINT(", LM: %u", GET_BE_U_3(tptr)); 211890792Sgshapiro tptr += 3; 211990792Sgshapiro subtlv_len -= 3; 212090792Sgshapiro subtlv_sum_len -= 3; 212190792Sgshapiro proc_bytes += 3; 212290792Sgshapiro ND_PRINT(", P: %u", GET_U_1(tptr)); 212390792Sgshapiro tptr++; 212490792Sgshapiro subtlv_len--; 212590792Sgshapiro subtlv_sum_len--; 212690792Sgshapiro proc_bytes++; 212790792Sgshapiro ND_PRINT(", P-ID: %u", GET_BE_U_2(tptr)); 212890792Sgshapiro } 212990792Sgshapiro break; 213090792Sgshapiro case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: 213190792Sgshapiro if (subtlv_len >= 36) { 213290792Sgshapiro gmpls_switch_cap = GET_U_1(tptr); 213390792Sgshapiro ND_PRINT("%s Interface Switching Capability:%s", 213490792Sgshapiro ident, 213590792Sgshapiro tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap)); 213690792Sgshapiro ND_PRINT(", LSP Encoding: %s", 213790792Sgshapiro tok2str(gmpls_encoding_values, "Unknown", GET_U_1((tptr + 1)))); 213890792Sgshapiro tptr += 4; 213990792Sgshapiro subtlv_len -= 4; 214090792Sgshapiro subtlv_sum_len -= 4; 214190792Sgshapiro proc_bytes += 4; 214238032Speter ND_PRINT("%s Max LSP Bandwidth:", ident); 214338032Speter for (priority_level = 0; priority_level < 8; priority_level++) { 214490792Sgshapiro bw.i = GET_BE_U_4(tptr); 214594334Sgshapiro ND_PRINT("%s priority level %u: %.3f Mbps", 214638032Speter ident, 214738032Speter priority_level, 214838032Speter bw.f * 8 / 1000000); 214990792Sgshapiro tptr += 4; 215090792Sgshapiro subtlv_len -= 4; 215190792Sgshapiro subtlv_sum_len -= 4; 215290792Sgshapiro proc_bytes += 4; 215390792Sgshapiro } 215438032Speter switch (gmpls_switch_cap) { 215538032Speter case GMPLS_PSC1: 215638032Speter case GMPLS_PSC2: 215738032Speter case GMPLS_PSC3: 215864562Sgshapiro case GMPLS_PSC4: 215990792Sgshapiro if (subtlv_len < 6) 216090792Sgshapiro break; 216138032Speter bw.i = GET_BE_U_4(tptr); 216290792Sgshapiro ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000); 216338032Speter ND_PRINT("%s Interface MTU: %u", ident, 216438032Speter GET_BE_U_2(tptr + 4)); 216538032Speter break; 216638032Speter case GMPLS_TSC: 216738032Speter if (subtlv_len < 8) 216838032Speter break; 216938032Speter bw.i = GET_BE_U_4(tptr); 217038032Speter ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000); 217138032Speter ND_PRINT("%s Indication %s", ident, 217238032Speter tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", GET_U_1((tptr + 4)))); 217338032Speter break; 217438032Speter default: 217538032Speter /* there is some optional stuff left to decode but this is as of yet 217638032Speter not specified so just lets hexdump what is left */ 217738032Speter if (subtlv_len != 0) { 217838032Speter if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len)) 217938032Speter return(0); 218038032Speter } 218138032Speter } 218238032Speter } 218338032Speter break; 218438032Speter case ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID: 218538032Speter if (subtlv_len >= 8) { 218638032Speter ND_PRINT("%s Flags: [%s]", ident, 218738032Speter bittok2str(isis_lan_adj_sid_flag_values, 218838032Speter "none", 218938032Speter GET_U_1(tptr))); 219038032Speter int vflag = (GET_U_1(tptr) & 0x20) ? 1:0; 219138032Speter int lflag = (GET_U_1(tptr) & 0x10) ? 1:0; 219238032Speter tptr++; 219338032Speter subtlv_len--; 219438032Speter subtlv_sum_len--; 219538032Speter proc_bytes++; 219664562Sgshapiro ND_PRINT("%s Weight: %u", ident, GET_U_1(tptr)); 219738032Speter tptr++; 219838032Speter subtlv_len--; 219938032Speter subtlv_sum_len--; 220038032Speter proc_bytes++; 220138032Speter if(subtlv_len>=SYSTEM_ID_LEN) { 220238032Speter ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); 220338032Speter ND_PRINT("%s Neighbor System-ID: %s", ident, 220438032Speter isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); 220538032Speter } 220638032Speter /* RFC 8667 section 2.2.2 */ 220738032Speter /* if V-flag is set to 1 and L-flag is set to 1 ==> 3 octet label */ 220838032Speter /* if V-flag is set to 0 and L-flag is set to 0 ==> 4 octet index */ 220938032Speter if (vflag && lflag) { 221090792Sgshapiro ND_PRINT("%s Label: %u", 221190792Sgshapiro ident, GET_BE_U_3(tptr+SYSTEM_ID_LEN)); 221238032Speter } else if ((!vflag) && (!lflag)) { 221390792Sgshapiro ND_PRINT("%s Index: %u", 221490792Sgshapiro ident, GET_BE_U_4(tptr+SYSTEM_ID_LEN)); 221590792Sgshapiro } else 221690792Sgshapiro nd_print_invalid(ndo); 221790792Sgshapiro } 221838032Speter break; 221938032Speter default: 222038032Speter if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len)) 222138032Speter return(0); 222264562Sgshapiro break; 222338032Speter } 222438032Speter 222538032Speter tptr += subtlv_len; 222638032Speter tlv_remaining -= subtlv_len; 222738032Speter subtlv_sum_len -= subtlv_len; 222890792Sgshapiro proc_bytes += subtlv_len; 222938032Speter } 223090792Sgshapiro } 223138032Speter return(proc_bytes); 223238032Speter 223338032Spetertrunc: 223438032Speter return(0); 223538032Speter} 223638032Speter 223738032Speter/* 223838032Speter * this is the common Multi Topology ID decoder 223938032Speter * it is called from various MT-TLVs (222,229,235,237) 224090792Sgshapiro */ 224190792Sgshapiro 224290792Sgshapirostatic uint8_t 224338032Speterisis_print_mtid(netdissect_options *ndo, 224490792Sgshapiro const uint8_t *tptr, const char *ident, u_int tlv_remaining) 224538032Speter{ 224638032Speter if (tlv_remaining < 2) 224738032Speter goto trunc; 224838032Speter 224938032Speter ND_PRINT("%s%s", 225038032Speter ident, 225138032Speter tok2str(isis_mt_values, 225238032Speter "Reserved for IETF Consensus", 225338032Speter ISIS_MASK_MTID(GET_BE_U_2(tptr)))); 225490792Sgshapiro 225590792Sgshapiro ND_PRINT(" Topology (0x%03x), Flags: [%s]", 225690792Sgshapiro ISIS_MASK_MTID(GET_BE_U_2(tptr)), 225790792Sgshapiro bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(GET_BE_U_2(tptr)))); 225838032Speter 225938032Speter return(2); 226038032Spetertrunc: 226190792Sgshapiro return 0; 226290792Sgshapiro} 226338032Speter 226438032Speter/* 226590792Sgshapiro * this is the common extended IP reach decoder 226690792Sgshapiro * it is called from TLVs (135,235,236,237) 226790792Sgshapiro * we process the TLV and optional subTLVs and return 226890792Sgshapiro * the amount of processed bytes 226938032Speter */ 227064562Sgshapiro 227138032Speterstatic u_int 227264562Sgshapiroisis_print_extd_ip_reach(netdissect_options *ndo, 227364562Sgshapiro const uint8_t *tptr, const char *ident, uint16_t afi) 227438032Speter{ 227564562Sgshapiro char ident_buffer[20]; 227690792Sgshapiro uint8_t prefix[sizeof(nd_ipv6)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ 227790792Sgshapiro u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; 227864562Sgshapiro 227964562Sgshapiro metric = GET_BE_U_4(tptr); 228064562Sgshapiro processed=4; 228190792Sgshapiro tptr+=4; 228264562Sgshapiro 228364562Sgshapiro if (afi == AF_INET) { 228438032Speter status_byte=GET_U_1(tptr); 228564562Sgshapiro tptr++; 228664562Sgshapiro bit_length = status_byte&0x3f; 228764562Sgshapiro if (bit_length > 32) { 228864562Sgshapiro ND_PRINT("%sIPv4 prefix: bad bit length %u", 228938032Speter ident, 229038032Speter bit_length); 229138032Speter return (0); 229238032Speter } 229338032Speter processed++; 229438032Speter } else if (afi == AF_INET6) { 229564562Sgshapiro status_byte=GET_U_1(tptr); 229638032Speter bit_length=GET_U_1(tptr + 1); 229738032Speter if (bit_length > 128) { 229890792Sgshapiro ND_PRINT("%sIPv6 prefix: bad bit length %u", 229990792Sgshapiro ident, 230090792Sgshapiro bit_length); 230190792Sgshapiro return (0); 230264562Sgshapiro } 230364562Sgshapiro tptr+=2; 230438032Speter processed+=2; 230538032Speter } else 230664562Sgshapiro return (0); /* somebody is fooling us */ 230738032Speter 230838032Speter byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ 230938032Speter 231038032Speter memset(prefix, 0, sizeof(prefix)); /* clear the copy buffer */ 231190792Sgshapiro GET_CPY_BYTES(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ 231238032Speter tptr+=byte_length; 231338032Speter processed+=byte_length; 231464562Sgshapiro 231564562Sgshapiro if (afi == AF_INET) 231638032Speter ND_PRINT("%sIPv4 prefix: %15s/%u", 231790792Sgshapiro ident, 231838032Speter ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */ 231938032Speter bit_length); 232038032Speter else if (afi == AF_INET6) 232138032Speter ND_PRINT("%sIPv6 prefix: %s/%u", 232238032Speter ident, 232338032Speter ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */ 232464562Sgshapiro bit_length); 232590792Sgshapiro 232638032Speter ND_PRINT(", Distribution: %s, Metric: %u", 232738032Speter ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", 232838032Speter metric); 232990792Sgshapiro 233038032Speter if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) 233138032Speter ND_PRINT(", sub-TLVs present"); 233238032Speter else if (afi == AF_INET6) 233390792Sgshapiro ND_PRINT(", %s%s", 233490792Sgshapiro ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", 233580785Sgshapiro ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); 233690792Sgshapiro 233780785Sgshapiro if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) 233877349Sgshapiro || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte)) 233977349Sgshapiro ) { 234090792Sgshapiro /* assume that one prefix can hold more 234177349Sgshapiro than one subTLV - therefore the first byte must reflect 234277349Sgshapiro the aggregate bytecount of the subTLVs for this prefix 234377349Sgshapiro */ 234438032Speter sublen=GET_U_1(tptr); 234590792Sgshapiro tptr++; 234690792Sgshapiro processed+=sublen+1; 234790792Sgshapiro ND_PRINT(" (%u)", sublen); /* print out subTLV length */ 234838032Speter 234938032Speter while (sublen>0) { 235090792Sgshapiro subtlvtype=GET_U_1(tptr); 235190792Sgshapiro subtlvlen=GET_U_1(tptr + 1); 235290792Sgshapiro tptr+=2; 235390792Sgshapiro /* prepend the indent string */ 235490792Sgshapiro snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 235580785Sgshapiro if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer)) 235690792Sgshapiro return(0); 235780785Sgshapiro tptr+=subtlvlen; 235838032Speter sublen-=(subtlvlen+2); 235938032Speter } 236038032Speter } 236138032Speter return (processed); 236264562Sgshapiro} 236338032Speter 236438032Speterstatic void 236538032Speterisis_print_router_cap_subtlv(netdissect_options *ndo, const uint8_t *tptr, uint8_t tlen) 236638032Speter{ 236738032Speter uint8_t subt, subl; 236838032Speter 2369110560Sgshapiro while (tlen >= 2) { 237038032Speter subt = GET_U_1(tptr); 237138032Speter subl = GET_U_1(tptr+1); 237238032Speter tlen -= 2; 237338032Speter tptr += 2; 237438032Speter 237538032Speter /* first lets see if we know the subTLVs name*/ 2376110560Sgshapiro ND_PRINT("\n\t\t%s subTLV #%u, length: %u", 2377110560Sgshapiro tok2str(isis_router_capability_subtlv_values, "unknown", subt), 2378110560Sgshapiro subt, subl); 2379110560Sgshapiro 2380102528Sgshapiro /* 2381102528Sgshapiro * Boundary check. 2382110560Sgshapiro */ 2383102528Sgshapiro if (subl > tlen) { 2384102528Sgshapiro break; 2385102528Sgshapiro } 2386102528Sgshapiro ND_TCHECK_LEN(tptr, subl); 2387102528Sgshapiro 238838032Speter switch (subt) { 238964562Sgshapiro case ISIS_SUBTLV_ROUTER_CAP_SR: 239038032Speter { 239190792Sgshapiro uint8_t flags, sid_tlen, sid_type, sid_len; 239238032Speter uint32_t range; 239338032Speter const uint8_t *sid_ptr; 239464562Sgshapiro 239590792Sgshapiro flags = GET_U_1(tptr); 239638032Speter range = GET_BE_U_3(tptr+1); 239738032Speter ND_PRINT(", Flags [%s], Range %u", 239838032Speter bittok2str(isis_router_capability_sr_flags, "None", flags), 239938032Speter range); 240038032Speter sid_ptr = tptr + 4; 240138032Speter sid_tlen = subl - 4; 240238032Speter 240338032Speter while (sid_tlen >= 5) { 240438032Speter sid_type = GET_U_1(sid_ptr); 240538032Speter sid_len = GET_U_1(sid_ptr+1); 240690792Sgshapiro sid_tlen -= 2; 240790792Sgshapiro sid_ptr += 2; 240890792Sgshapiro 240938032Speter /* 241090792Sgshapiro * Boundary check. 241190792Sgshapiro */ 241290792Sgshapiro if (sid_len > sid_tlen) { 241364562Sgshapiro break; 241438032Speter } 241590792Sgshapiro 241664562Sgshapiro switch (sid_type) { 241764562Sgshapiro case 1: 241838032Speter if (sid_len == 3) { 241938032Speter ND_PRINT(", SID value %u", GET_BE_U_3(sid_ptr)); 242038032Speter } else if (sid_len == 4) { 242138032Speter ND_PRINT(", SID value %u", GET_BE_U_4(sid_ptr)); 242238032Speter } else { 242338032Speter ND_PRINT(", Unknown SID length%u", sid_len); 242490792Sgshapiro } 242590792Sgshapiro break; 242664562Sgshapiro default: 242738032Speter print_unknown_data(ndo, sid_ptr, "\n\t\t ", sid_len); 242864562Sgshapiro } 242964562Sgshapiro 243038032Speter sid_ptr += sid_len; 243138032Speter sid_tlen -= sid_len; 243238032Speter } 243338032Speter } 243438032Speter break; 243538032Speter default: 243638032Speter print_unknown_data(ndo, tptr, "\n\t\t", subl); 243790792Sgshapiro break; 243890792Sgshapiro } 243990792Sgshapiro 244064562Sgshapiro tlen -= subl; 244138032Speter tptr += subl; 244290792Sgshapiro } 244364562Sgshapiro trunc: 244464562Sgshapiro return; 244538032Speter} 244638032Speter 244738032Speter/* 244838032Speter * Clear checksum and lifetime prior to signature verification. 244938032Speter */ 245038032Speterstatic void 245190792Sgshapiroisis_clear_checksum_lifetime(void *header) 245290792Sgshapiro{ 245364562Sgshapiro struct isis_lsp_header *header_lsp = (struct isis_lsp_header *) header; 245438032Speter 245564562Sgshapiro header_lsp->checksum[0] = 0; 245664562Sgshapiro header_lsp->checksum[1] = 0; 245738032Speter header_lsp->remaining_lifetime[0] = 0; 245838032Speter header_lsp->remaining_lifetime[1] = 0; 245938032Speter} 246038032Speter 246138032Speter/* 246238032Speter * isis_print 246364562Sgshapiro * Decode IS-IS packets. Return 0 on error. 246464562Sgshapiro */ 246564562Sgshapiro 246664562Sgshapiro#define INVALID_OR_DECREMENT(length,decr) \ 246764562Sgshapiro if ((length) < (decr)) { \ 246864562Sgshapiro ND_PRINT(" [packet length %u < %zu]", (length), (decr)); \ 246964562Sgshapiro nd_print_invalid(ndo); \ 247064562Sgshapiro return 1; \ 247190792Sgshapiro } \ 247290792Sgshapiro length -= (decr); 247390792Sgshapiro 247464562Sgshapirostatic int 247564562Sgshapiroisis_print(netdissect_options *ndo, 247638032Speter const uint8_t *p, u_int length) 247764562Sgshapiro{ 247864562Sgshapiro const struct isis_common_header *isis_header; 247964562Sgshapiro 248064562Sgshapiro const struct isis_iih_lan_header *header_iih_lan; 248164562Sgshapiro const struct isis_iih_ptp_header *header_iih_ptp; 248264562Sgshapiro const struct isis_lsp_header *header_lsp; 248364562Sgshapiro const struct isis_csnp_header *header_csnp; 248464562Sgshapiro const struct isis_psnp_header *header_psnp; 248564562Sgshapiro 248664562Sgshapiro const struct isis_tlv_lsp *tlv_lsp; 248764562Sgshapiro const struct isis_tlv_ptp_adj *tlv_ptp_adj; 248898121Sgshapiro const struct isis_tlv_is_reach *tlv_is_reach; 248964562Sgshapiro const struct isis_tlv_es_reach *tlv_es_reach; 249090792Sgshapiro 249198121Sgshapiro uint8_t version, pdu_version, fixed_len; 249298121Sgshapiro uint8_t pdu_type, pdu_max_area, max_area, pdu_id_length, id_length, tlv_type, tlv_len, tlen, alen, prefix_len; 249364562Sgshapiro u_int ext_is_len, ext_ip_len; 249464562Sgshapiro uint8_t mt_len; 249598121Sgshapiro uint8_t isis_subtlv_idrp; 249664562Sgshapiro const uint8_t *optr, *pptr, *tptr; 249764562Sgshapiro u_int packet_len; 249864562Sgshapiro u_short pdu_len, key_id; 249964562Sgshapiro u_int i,vendor_id, num_vals; 250064562Sgshapiro uint8_t auth_type; 250164562Sgshapiro uint8_t num_system_ids; 250264562Sgshapiro int sigcheck; 250364562Sgshapiro 250464562Sgshapiro ndo->ndo_protocol = "isis"; 250538032Speter packet_len=length; 250638032Speter optr = p; /* initialize the _o_riginal pointer to the packet start - 250790792Sgshapiro need it for parsing the checksum TLV and authentication 250838032Speter TLV verification */ 250980785Sgshapiro isis_header = (const struct isis_common_header *)p; 251038032Speter ND_TCHECK_SIZE(isis_header); 251180785Sgshapiro if (length < ISIS_COMMON_HEADER_SIZE) 251280785Sgshapiro goto trunc; 251380785Sgshapiro pptr = p+(ISIS_COMMON_HEADER_SIZE); 251480785Sgshapiro header_iih_lan = (const struct isis_iih_lan_header *)pptr; 251580785Sgshapiro header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; 251680785Sgshapiro header_lsp = (const struct isis_lsp_header *)pptr; 251780785Sgshapiro header_csnp = (const struct isis_csnp_header *)pptr; 251880785Sgshapiro header_psnp = (const struct isis_psnp_header *)pptr; 251980785Sgshapiro 252090792Sgshapiro if (!ndo->ndo_eflag) 252190792Sgshapiro ND_PRINT("IS-IS"); 252290792Sgshapiro 252390792Sgshapiro /* 252490792Sgshapiro * Sanity checking of the header. 252590792Sgshapiro */ 252690792Sgshapiro 252790792Sgshapiro version = GET_U_1(isis_header->version); 252890792Sgshapiro if (version != ISIS_VERSION) { 252990792Sgshapiro ND_PRINT("version %u packet not supported", version); 253090792Sgshapiro return (0); 253190792Sgshapiro } 253280785Sgshapiro 253390792Sgshapiro pdu_id_length = GET_U_1(isis_header->id_length); 253490792Sgshapiro if ((pdu_id_length != SYSTEM_ID_LEN) && (pdu_id_length != 0)) { 253580785Sgshapiro ND_PRINT("system ID length of %u is not supported", 253638032Speter pdu_id_length); 253738032Speter return (0); 253838032Speter } 253938032Speter 254038032Speter pdu_version = GET_U_1(isis_header->pdu_version); 254138032Speter if (pdu_version != ISIS_VERSION) { 254238032Speter ND_PRINT("version %u packet not supported", pdu_version); 254338032Speter return (0); 254494334Sgshapiro } 254594334Sgshapiro 254694334Sgshapiro fixed_len = GET_U_1(isis_header->fixed_len); 254794334Sgshapiro if (length < fixed_len) { 254894334Sgshapiro ND_PRINT("fixed header length %u > packet length %u", fixed_len, length); 254994334Sgshapiro return (0); 255094334Sgshapiro } 255194334Sgshapiro 255294334Sgshapiro if (fixed_len < ISIS_COMMON_HEADER_SIZE) { 255394334Sgshapiro ND_PRINT("fixed header length %u < minimum header size %u", fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE); 255494334Sgshapiro return (0); 255594334Sgshapiro } 255694334Sgshapiro 255794334Sgshapiro pdu_max_area = GET_U_1(isis_header->max_area); 255894334Sgshapiro switch(pdu_max_area) { 255994334Sgshapiro case 0: 256038032Speter max_area = 3; /* silly shit */ 256138032Speter break; 256264562Sgshapiro case 255: 256364562Sgshapiro ND_PRINT("bad packet -- 255 areas"); 256464562Sgshapiro return (0); 256590792Sgshapiro default: 256690792Sgshapiro max_area = pdu_max_area; 256764562Sgshapiro break; 256864562Sgshapiro } 256964562Sgshapiro 257038032Speter switch(pdu_id_length) { 257164562Sgshapiro case 0: 257238032Speter id_length = 6; /* silly shit again */ 257364562Sgshapiro break; 257438032Speter case 1: /* 1-8 are valid sys-ID lengths */ 257590792Sgshapiro case 2: 257664562Sgshapiro case 3: 257764562Sgshapiro case 4: 257864562Sgshapiro case 5: 257964562Sgshapiro case 6: 258038032Speter case 7: 258164562Sgshapiro case 8: 258238032Speter id_length = pdu_id_length; 258390792Sgshapiro break; 258464562Sgshapiro case 255: 258564562Sgshapiro id_length = 0; /* entirely useless */ 258664562Sgshapiro break; 258764562Sgshapiro default: 258838032Speter id_length = pdu_id_length; 258964562Sgshapiro break; 259038032Speter } 259190792Sgshapiro 259264562Sgshapiro /* toss any non 6-byte sys-ID len PDUs */ 259364562Sgshapiro if (id_length != 6 ) { 259464562Sgshapiro ND_PRINT("bad packet -- illegal sys-ID length (%u)", id_length); 259538032Speter return (0); 259638032Speter } 259738032Speter 259838032Speter pdu_type = GET_U_1(isis_header->pdu_type); 259938032Speter 260064562Sgshapiro /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ 260138032Speter if (ndo->ndo_vflag == 0) { 260290792Sgshapiro ND_PRINT("%s%s", 260364562Sgshapiro ndo->ndo_eflag ? "" : ", ", 260464562Sgshapiro tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)); 260538032Speter } else { 260638032Speter /* ok they seem to want to know everything - lets fully decode it */ 260738032Speter ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length); 260890792Sgshapiro 260990792Sgshapiro ND_PRINT("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", 261090792Sgshapiro tok2str(isis_pdu_values, 261138032Speter "unknown, type %u", 261238032Speter pdu_type), 261338032Speter fixed_len, 261438032Speter version, 261538032Speter pdu_version, 261638032Speter id_length, 261738032Speter pdu_id_length, 261838032Speter max_area, 261938032Speter pdu_max_area); 262038032Speter 262138032Speter if (ndo->ndo_vflag > 1) { 262298121Sgshapiro if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */ 262338032Speter return (0); /* for optionally debugging the common header */ 262438032Speter } 262538032Speter } 262690792Sgshapiro 262798121Sgshapiro switch (pdu_type) { 262898121Sgshapiro 262998121Sgshapiro case ISIS_PDU_L1_LAN_IIH: 263038032Speter case ISIS_PDU_L2_LAN_IIH: 263138032Speter if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { 263238032Speter ND_PRINT(", bogus fixed header length %u should be %zu", 263338032Speter fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 263490792Sgshapiro return (0); 263590792Sgshapiro } 263690792Sgshapiro ND_TCHECK_SIZE(header_iih_lan); 263790792Sgshapiro if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE) 263890792Sgshapiro goto trunc; 263990792Sgshapiro if (ndo->ndo_vflag == 0) { 264090792Sgshapiro ND_PRINT(", src-id %s", 264190792Sgshapiro isis_print_id(ndo, header_iih_lan->source_id, SYSTEM_ID_LEN)); 264290792Sgshapiro ND_PRINT(", lan-id %s, prio %u", 264390792Sgshapiro isis_print_id(ndo, header_iih_lan->lan_id,NODE_ID_LEN), 264490792Sgshapiro GET_U_1(header_iih_lan->priority)); 264590792Sgshapiro ND_PRINT(", length %u", length); 264690792Sgshapiro return (1); 264790792Sgshapiro } 264890792Sgshapiro pdu_len=GET_BE_U_2(header_iih_lan->pdu_len); 264990792Sgshapiro if (packet_len>pdu_len) { 265090792Sgshapiro packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 265138032Speter length=pdu_len; 265264562Sgshapiro } 265364562Sgshapiro 265438032Speter ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]", 265564562Sgshapiro isis_print_id(ndo, header_iih_lan->source_id,SYSTEM_ID_LEN), 265664562Sgshapiro GET_BE_U_2(header_iih_lan->holding_time), 265764562Sgshapiro tok2str(isis_iih_circuit_type_values, 265864562Sgshapiro "unknown circuit type 0x%02x", 265938032Speter GET_U_1(header_iih_lan->circuit_type))); 266064562Sgshapiro 266164562Sgshapiro ND_PRINT("\n\t lan-id: %s, Priority: %u, PDU length: %u", 266238032Speter isis_print_id(ndo, header_iih_lan->lan_id, NODE_ID_LEN), 266338032Speter GET_U_1(header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, 266438032Speter pdu_len); 266590792Sgshapiro 266690792Sgshapiro if (ndo->ndo_vflag > 1) { 266738032Speter if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE)) 266838032Speter return (0); 266938032Speter } 267038032Speter 267138032Speter INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 267238032Speter pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 267338032Speter break; 267438032Speter 267590792Sgshapiro case ISIS_PDU_PTP_IIH: 267690792Sgshapiro if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { 267738032Speter ND_PRINT(", bogus fixed header length %u should be %zu", 267838032Speter fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 267938032Speter return (0); 268038032Speter } 268138032Speter ND_TCHECK_SIZE(header_iih_ptp); 268238032Speter if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE) 268338032Speter goto trunc; 268438032Speter if (ndo->ndo_vflag == 0) { 268538032Speter ND_PRINT(", src-id %s", isis_print_id(ndo, header_iih_ptp->source_id, SYSTEM_ID_LEN)); 268638032Speter ND_PRINT(", length %u", length); 268764562Sgshapiro return (1); 268864562Sgshapiro } 268938032Speter pdu_len=GET_BE_U_2(header_iih_ptp->pdu_len); 269038032Speter if (packet_len>pdu_len) { 269194334Sgshapiro packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 269238032Speter length=pdu_len; 269338032Speter } 269494334Sgshapiro 269538032Speter ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]", 269638032Speter isis_print_id(ndo, header_iih_ptp->source_id,SYSTEM_ID_LEN), 269764562Sgshapiro GET_BE_U_2(header_iih_ptp->holding_time), 269864562Sgshapiro tok2str(isis_iih_circuit_type_values, 269964562Sgshapiro "unknown circuit type 0x%02x", 270038032Speter GET_U_1(header_iih_ptp->circuit_type))); 270138032Speter 270264562Sgshapiro ND_PRINT("\n\t circuit-id: 0x%02x, PDU length: %u", 270338032Speter GET_U_1(header_iih_ptp->circuit_id), 270438032Speter pdu_len); 270538032Speter 270638032Speter if (ndo->ndo_vflag > 1) { 270738032Speter if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE)) 270838032Speter return (0); 270938032Speter } 271038032Speter INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 271138032Speter pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 271238032Speter break; 271390792Sgshapiro 271490792Sgshapiro case ISIS_PDU_L1_LSP: 271590792Sgshapiro case ISIS_PDU_L2_LSP: 271690792Sgshapiro if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { 271790792Sgshapiro ND_PRINT(", bogus fixed header length %u should be %zu", 271890792Sgshapiro fixed_len, ISIS_LSP_HEADER_SIZE); 271990792Sgshapiro return (0); 272090792Sgshapiro } 272190792Sgshapiro ND_TCHECK_SIZE(header_lsp); 272290792Sgshapiro if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE) 272390792Sgshapiro goto trunc; 272490792Sgshapiro if (ndo->ndo_vflag == 0) { 272590792Sgshapiro ND_PRINT(", lsp-id %s, seq 0x%08x, lifetime %5us", 272690792Sgshapiro isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN), 272790792Sgshapiro GET_BE_U_4(header_lsp->sequence_number), 272890792Sgshapiro GET_BE_U_2(header_lsp->remaining_lifetime)); 272990792Sgshapiro ND_PRINT(", length %u", length); 273090792Sgshapiro return (1); 273190792Sgshapiro } 273238032Speter pdu_len=GET_BE_U_2(header_lsp->pdu_len); 273338032Speter if (packet_len>pdu_len) { 273438032Speter packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 273538032Speter length=pdu_len; 273638032Speter } 273738032Speter 273838032Speter ND_PRINT("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", 273938032Speter isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN), 274038032Speter GET_BE_U_4(header_lsp->sequence_number), 274138032Speter GET_BE_U_2(header_lsp->remaining_lifetime), 274238032Speter GET_BE_U_2(header_lsp->checksum)); 274338032Speter 274438032Speter osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id, 274590792Sgshapiro GET_BE_U_2(header_lsp->checksum), 274690792Sgshapiro 12, length-12); 274790792Sgshapiro 274838032Speter ND_PRINT(", PDU length: %u, Flags: [ %s", 274938032Speter pdu_len, 275038032Speter ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); 275190792Sgshapiro 275238032Speter if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { 275364562Sgshapiro ND_PRINT("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); 275464562Sgshapiro ND_PRINT("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); 275538032Speter ND_PRINT("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); 275638032Speter ND_PRINT("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); 275738032Speter ND_PRINT("ATT bit set, "); 275864562Sgshapiro } 275964562Sgshapiro ND_PRINT("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); 276090792Sgshapiro ND_PRINT("%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)", 276190792Sgshapiro ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); 276290792Sgshapiro 276364562Sgshapiro if (ndo->ndo_vflag > 1) { 276438032Speter if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE)) 276564562Sgshapiro return (0); 276664562Sgshapiro } 276764562Sgshapiro 276890792Sgshapiro INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 276964562Sgshapiro pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 277064562Sgshapiro break; 277164562Sgshapiro 277238032Speter case ISIS_PDU_L1_CSNP: 277338032Speter case ISIS_PDU_L2_CSNP: 277438032Speter if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { 277538032Speter ND_PRINT(", bogus fixed header length %u should be %zu", 277638032Speter fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 277738032Speter return (0); 277838032Speter } 277938032Speter ND_TCHECK_SIZE(header_csnp); 278038032Speter if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE) 278138032Speter goto trunc; 278238032Speter if (ndo->ndo_vflag == 0) { 278338032Speter ND_PRINT(", src-id %s", isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN)); 278490792Sgshapiro ND_PRINT(", length %u", length); 278590792Sgshapiro return (1); 278690792Sgshapiro } 278790792Sgshapiro pdu_len=GET_BE_U_2(header_csnp->pdu_len); 278890792Sgshapiro if (packet_len>pdu_len) { 278990792Sgshapiro packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 279090792Sgshapiro length=pdu_len; 279171345Sgshapiro } 279290792Sgshapiro 279364562Sgshapiro ND_PRINT("\n\t source-id: %s, PDU length: %u", 279471345Sgshapiro isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN), 279564562Sgshapiro pdu_len); 279671345Sgshapiro ND_PRINT("\n\t start lsp-id: %s", 279771345Sgshapiro isis_print_id(ndo, header_csnp->start_lsp_id, LSP_ID_LEN)); 279871345Sgshapiro ND_PRINT("\n\t end lsp-id: %s", 279938032Speter isis_print_id(ndo, header_csnp->end_lsp_id, LSP_ID_LEN)); 280090792Sgshapiro 280190792Sgshapiro if (ndo->ndo_vflag > 1) { 280290792Sgshapiro if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE)) 280390792Sgshapiro return (0); 280490792Sgshapiro } 280590792Sgshapiro 280690792Sgshapiro INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 280790792Sgshapiro pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 280890792Sgshapiro break; 280990792Sgshapiro 281090792Sgshapiro case ISIS_PDU_L1_PSNP: 281190792Sgshapiro case ISIS_PDU_L2_PSNP: 281290792Sgshapiro if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { 281390792Sgshapiro ND_PRINT("- bogus fixed header length %u should be %zu", 281490792Sgshapiro fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 281590792Sgshapiro return (0); 281690792Sgshapiro } 281790792Sgshapiro ND_TCHECK_SIZE(header_psnp); 281890792Sgshapiro if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE) 281990792Sgshapiro goto trunc; 282090792Sgshapiro if (ndo->ndo_vflag == 0) { 282190792Sgshapiro ND_PRINT(", src-id %s", isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN)); 282290792Sgshapiro ND_PRINT(", length %u", length); 282390792Sgshapiro return (1); 282471345Sgshapiro } 282590792Sgshapiro pdu_len=GET_BE_U_2(header_psnp->pdu_len); 282690792Sgshapiro if (packet_len>pdu_len) { 282790792Sgshapiro packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 282864562Sgshapiro length=pdu_len; 282990792Sgshapiro } 283090792Sgshapiro 283190792Sgshapiro ND_PRINT("\n\t source-id: %s, PDU length: %u", 283290792Sgshapiro isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN), 283390792Sgshapiro pdu_len); 283490792Sgshapiro 283590792Sgshapiro if (ndo->ndo_vflag > 1) { 283690792Sgshapiro if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE)) 283790792Sgshapiro return (0); 283890792Sgshapiro } 283990792Sgshapiro 284090792Sgshapiro INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 284190792Sgshapiro pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 284290792Sgshapiro break; 284390792Sgshapiro 284490792Sgshapiro default: 284590792Sgshapiro if (ndo->ndo_vflag == 0) { 284690792Sgshapiro ND_PRINT(", length %u", length); 284790792Sgshapiro return (1); 284890792Sgshapiro } 284990792Sgshapiro (void)print_unknown_data(ndo, pptr, "\n\t ", length); 285090792Sgshapiro return (0); 285190792Sgshapiro } 285290792Sgshapiro 285390792Sgshapiro /* 285490792Sgshapiro * Now print the TLV's. 285590792Sgshapiro */ 285690792Sgshapiro 285790792Sgshapiro while (packet_len > 0) { 285890792Sgshapiro ND_TCHECK_2(pptr); 285964562Sgshapiro if (packet_len < 2) 286064562Sgshapiro goto trunc; 286164562Sgshapiro tlv_type = GET_U_1(pptr); 286271345Sgshapiro tlv_len = GET_U_1(pptr + 1); 286371345Sgshapiro pptr += 2; 286464562Sgshapiro packet_len -= 2; 286590792Sgshapiro tlen = tlv_len; /* copy temporary len & pointer to packet data */ 286690792Sgshapiro tptr = pptr; 286790792Sgshapiro 286890792Sgshapiro /* first lets see if we know the TLVs name*/ 286990792Sgshapiro ND_PRINT("\n\t %s TLV #%u, length: %u", 287090792Sgshapiro tok2str(isis_tlv_values, 287190792Sgshapiro "unknown", 287290792Sgshapiro tlv_type), 287390792Sgshapiro tlv_type, 287490792Sgshapiro tlv_len); 287590792Sgshapiro 287690792Sgshapiro if (packet_len < tlv_len) 287790792Sgshapiro goto trunc; 287890792Sgshapiro 287990792Sgshapiro /* now check if we have a decoder otherwise do a hexdump at the end*/ 288090792Sgshapiro switch (tlv_type) { 288190792Sgshapiro case ISIS_TLV_AREA_ADDR: 288290792Sgshapiro while (tlen != 0) { 288390792Sgshapiro alen = GET_U_1(tptr); 288490792Sgshapiro tptr++; 288590792Sgshapiro tlen--; 288690792Sgshapiro if (tlen < alen) 288790792Sgshapiro goto tlv_trunc; 288890792Sgshapiro ND_PRINT("\n\t Area address (length: %u): %s", 288990792Sgshapiro alen, 289090792Sgshapiro GET_ISONSAP_STRING(tptr, alen)); 289190792Sgshapiro tptr += alen; 289290792Sgshapiro tlen -= alen; 289390792Sgshapiro } 289464562Sgshapiro break; 289564562Sgshapiro case ISIS_TLV_ISNEIGH: 289671345Sgshapiro while (tlen != 0) { 289771345Sgshapiro if (tlen < MAC_ADDR_LEN) 289864562Sgshapiro goto tlv_trunc; 289964562Sgshapiro ND_TCHECK_LEN(tptr, MAC_ADDR_LEN); 290064562Sgshapiro ND_PRINT("\n\t SNPA: %s", isis_print_id(ndo, tptr, MAC_ADDR_LEN)); 290164562Sgshapiro tlen -= MAC_ADDR_LEN; 290264562Sgshapiro tptr += MAC_ADDR_LEN; 290371345Sgshapiro } 290464562Sgshapiro break; 290564562Sgshapiro 290664562Sgshapiro case ISIS_TLV_INSTANCE_ID: 290790792Sgshapiro if (tlen < 4) 290890792Sgshapiro goto tlv_trunc; 290966494Sgshapiro num_vals = (tlen-2)/2; 291064562Sgshapiro ND_PRINT("\n\t Instance ID: %u, ITIDs(%u)%s ", 291164562Sgshapiro GET_BE_U_2(tptr), num_vals, 291290792Sgshapiro num_vals ? ":" : ""); 291364562Sgshapiro tptr += 2; 291490792Sgshapiro tlen -= 2; 291590792Sgshapiro for (i=0; i < num_vals; i++) { 2916102528Sgshapiro ND_PRINT("%u", GET_BE_U_2(tptr)); 2917102528Sgshapiro if (i < (num_vals - 1)) { 291864562Sgshapiro ND_PRINT(", "); 291990792Sgshapiro } 292064562Sgshapiro tptr += 2; 292164562Sgshapiro tlen -= 2; 292264562Sgshapiro } 292364562Sgshapiro break; 292464562Sgshapiro 292564562Sgshapiro case ISIS_TLV_PADDING: 292664562Sgshapiro break; 292764562Sgshapiro 292864562Sgshapiro case ISIS_TLV_MT_IS_REACH: 292964562Sgshapiro mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); 293064562Sgshapiro if (mt_len == 0) /* did something go wrong ? */ 293164562Sgshapiro goto trunc; 293264562Sgshapiro tptr+=mt_len; 293364562Sgshapiro tlen-=mt_len; 293464562Sgshapiro while (tlen != 0) { 293564562Sgshapiro ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); 293664562Sgshapiro if (ext_is_len == 0) /* did something go wrong ? */ 293764562Sgshapiro goto trunc; 293864562Sgshapiro if (tlen < ext_is_len) { 293964562Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); 294064562Sgshapiro nd_print_invalid(ndo); 294190792Sgshapiro break; 294264562Sgshapiro } 294364562Sgshapiro tlen-=(uint8_t)ext_is_len; 294464562Sgshapiro tptr+=(uint8_t)ext_is_len; 294564562Sgshapiro } 294664562Sgshapiro break; 294764562Sgshapiro 294864562Sgshapiro case ISIS_TLV_IS_ALIAS_ID: 294964562Sgshapiro while (tlen != 0) { 295064562Sgshapiro ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); 295164562Sgshapiro if (ext_is_len == 0) /* did something go wrong ? */ 295264562Sgshapiro goto trunc; 295364562Sgshapiro if (tlen < ext_is_len) { 295464562Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); 295564562Sgshapiro nd_print_invalid(ndo); 295664562Sgshapiro break; 295764562Sgshapiro } 295864562Sgshapiro tlen-=(uint8_t)ext_is_len; 295964562Sgshapiro tptr+=(uint8_t)ext_is_len; 296064562Sgshapiro } 296164562Sgshapiro break; 296264562Sgshapiro 296390792Sgshapiro case ISIS_TLV_EXT_IS_REACH: 296490792Sgshapiro while (tlen != 0) { 296564562Sgshapiro ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen); 296664562Sgshapiro if (ext_is_len == 0) /* did something go wrong ? */ 296764562Sgshapiro goto trunc; 296890792Sgshapiro if (tlen < ext_is_len) { 296990792Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len); 297064562Sgshapiro nd_print_invalid(ndo); 297190792Sgshapiro break; 297290792Sgshapiro } 297364562Sgshapiro tlen-=(uint8_t)ext_is_len; 297464562Sgshapiro tptr+=(uint8_t)ext_is_len; 297564562Sgshapiro } 297664562Sgshapiro break; 297764562Sgshapiro case ISIS_TLV_IS_REACH: 297864562Sgshapiro if (tlen < 1) 297964562Sgshapiro goto tlv_trunc; 298064562Sgshapiro ND_PRINT("\n\t %s", 298164562Sgshapiro tok2str(isis_is_reach_virtual_values, 298290792Sgshapiro "bogus virtual flag 0x%02x", 298364562Sgshapiro GET_U_1(tptr))); 298490792Sgshapiro tptr++; 2985102528Sgshapiro tlen--; 2986102528Sgshapiro tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; 298764562Sgshapiro while (tlen != 0) { 298864562Sgshapiro if (tlen < sizeof(struct isis_tlv_is_reach)) 298964562Sgshapiro goto tlv_trunc; 299064562Sgshapiro ND_TCHECK_SIZE(tlv_is_reach); 299164562Sgshapiro ND_PRINT("\n\t IS Neighbor: %s", 299264562Sgshapiro isis_print_id(ndo, tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); 299364562Sgshapiro isis_print_metric_block(ndo, &tlv_is_reach->isis_metric_block); 299464562Sgshapiro tlen -= sizeof(struct isis_tlv_is_reach); 299564562Sgshapiro tlv_is_reach++; 299690792Sgshapiro } 299790792Sgshapiro break; 299864562Sgshapiro 299964562Sgshapiro case ISIS_TLV_ESNEIGH: 300064562Sgshapiro tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; 300164562Sgshapiro while (tlen != 0) { 300290792Sgshapiro if (tlen < sizeof(struct isis_tlv_es_reach)) 300390792Sgshapiro goto tlv_trunc; 300464562Sgshapiro ND_TCHECK_SIZE(tlv_es_reach); 300564562Sgshapiro ND_PRINT("\n\t ES Neighbor: %s", 300664562Sgshapiro isis_print_id(ndo, tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN)); 300764562Sgshapiro isis_print_metric_block(ndo, &tlv_es_reach->isis_metric_block); 300864562Sgshapiro tlen -= sizeof(struct isis_tlv_es_reach); 300964562Sgshapiro tlv_es_reach++; 301064562Sgshapiro } 301164562Sgshapiro break; 301264562Sgshapiro 301364562Sgshapiro /* those two TLVs share the same format */ 301490792Sgshapiro case ISIS_TLV_INT_IP_REACH: 301590792Sgshapiro case ISIS_TLV_EXT_IP_REACH: 301664562Sgshapiro if (!isis_print_tlv_ip_reach(ndo, pptr, "\n\t ", tlv_len)) 301764562Sgshapiro return (1); 301864562Sgshapiro break; 301964562Sgshapiro 302064562Sgshapiro case ISIS_TLV_EXTD_IP_REACH: 302164562Sgshapiro while (tlen != 0) { 302264562Sgshapiro ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET); 302364562Sgshapiro if (ext_ip_len == 0) /* did something go wrong ? */ 302464562Sgshapiro goto trunc; 302564562Sgshapiro if (tlen < ext_ip_len) { 302664562Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); 302771345Sgshapiro nd_print_invalid(ndo); 302871345Sgshapiro break; 302971345Sgshapiro } 303064562Sgshapiro tlen-=(uint8_t)ext_ip_len; 303164562Sgshapiro tptr+=(uint8_t)ext_ip_len; 303264562Sgshapiro } 303390792Sgshapiro break; 303464562Sgshapiro 303564562Sgshapiro case ISIS_TLV_MT_IP_REACH: 303664562Sgshapiro mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); 303764562Sgshapiro if (mt_len == 0) { /* did something go wrong ? */ 303864562Sgshapiro goto trunc; 303990792Sgshapiro } 304090792Sgshapiro tptr+=mt_len; 304190792Sgshapiro tlen-=mt_len; 304264562Sgshapiro 304364562Sgshapiro while (tlen != 0) { 304464562Sgshapiro ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET); 304571345Sgshapiro if (ext_ip_len == 0) /* did something go wrong ? */ 304671345Sgshapiro goto trunc; 304764562Sgshapiro if (tlen < ext_ip_len) { 304871345Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); 304964562Sgshapiro nd_print_invalid(ndo); 305064562Sgshapiro break; 305164562Sgshapiro } 305264562Sgshapiro tlen-=(uint8_t)ext_ip_len; 305364562Sgshapiro tptr+=(uint8_t)ext_ip_len; 305464562Sgshapiro } 305564562Sgshapiro break; 305664562Sgshapiro 305764562Sgshapiro case ISIS_TLV_IP6_REACH: 305890792Sgshapiro while (tlen != 0) { 305964562Sgshapiro ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6); 306090792Sgshapiro if (ext_ip_len == 0) /* did something go wrong ? */ 306190792Sgshapiro goto trunc; 306264562Sgshapiro if (tlen < ext_ip_len) { 306364562Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); 306490792Sgshapiro nd_print_invalid(ndo); 306564562Sgshapiro break; 306690792Sgshapiro } 306764562Sgshapiro tlen-=(uint8_t)ext_ip_len; 306898121Sgshapiro tptr+=(uint8_t)ext_ip_len; 306998121Sgshapiro } 307098121Sgshapiro break; 307164562Sgshapiro 307298121Sgshapiro case ISIS_TLV_MT_IP6_REACH: 307390792Sgshapiro mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); 307490792Sgshapiro if (mt_len == 0) { /* did something go wrong ? */ 307564562Sgshapiro goto trunc; 307664562Sgshapiro } 307790792Sgshapiro tptr+=mt_len; 307864562Sgshapiro tlen-=mt_len; 307990792Sgshapiro 308090792Sgshapiro while (tlen != 0) { 308177349Sgshapiro ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6); 308264562Sgshapiro if (ext_ip_len == 0) /* did something go wrong ? */ 308390792Sgshapiro goto trunc; 308464562Sgshapiro if (tlen < ext_ip_len) { 308564562Sgshapiro ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len); 308690792Sgshapiro nd_print_invalid(ndo); 308764562Sgshapiro break; 308864562Sgshapiro } 308964562Sgshapiro tlen-=(uint8_t)ext_ip_len; 309090792Sgshapiro tptr+=(uint8_t)ext_ip_len; 309190792Sgshapiro } 309290792Sgshapiro break; 309364562Sgshapiro 309490792Sgshapiro case ISIS_TLV_IP6ADDR: 309590792Sgshapiro while (tlen != 0) { 309690792Sgshapiro if (tlen < sizeof(nd_ipv6)) 309764562Sgshapiro goto tlv_trunc; 309864562Sgshapiro ND_PRINT("\n\t IPv6 interface address: %s", 309964562Sgshapiro GET_IP6ADDR_STRING(tptr)); 310090792Sgshapiro 310190792Sgshapiro tptr += sizeof(nd_ipv6); 310264562Sgshapiro tlen -= sizeof(nd_ipv6); 310364562Sgshapiro } 310490792Sgshapiro break; 310564562Sgshapiro case ISIS_TLV_AUTH: 310664562Sgshapiro if (tlen < 1) 310764562Sgshapiro goto tlv_trunc; 310864562Sgshapiro auth_type = GET_U_1(tptr); 310964562Sgshapiro tptr++; 311090792Sgshapiro tlen--; 311190792Sgshapiro 311290792Sgshapiro ND_PRINT("\n\t %s: ", 311390792Sgshapiro tok2str(isis_subtlv_auth_values, 311490792Sgshapiro "unknown Authentication type 0x%02x", 311590792Sgshapiro auth_type)); 311690792Sgshapiro 311790792Sgshapiro switch (auth_type) { 311890792Sgshapiro case ISIS_SUBTLV_AUTH_SIMPLE: 311990792Sgshapiro nd_printjnp(ndo, tptr, tlen); 312090792Sgshapiro break; 312190792Sgshapiro case ISIS_SUBTLV_AUTH_MD5: 312290792Sgshapiro for(i=0;i<tlen;i++) { 312390792Sgshapiro ND_PRINT("%02x", GET_U_1(tptr + i)); 312490792Sgshapiro } 312590792Sgshapiro if (tlen != ISIS_SUBTLV_AUTH_MD5_LEN) 312690792Sgshapiro ND_PRINT(", (invalid subTLV) "); 312790792Sgshapiro 312890792Sgshapiro sigcheck = signature_verify(ndo, optr, length, tptr, 312990792Sgshapiro isis_clear_checksum_lifetime, 313090792Sgshapiro header_lsp); 313190792Sgshapiro ND_PRINT(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); 313264562Sgshapiro 313364562Sgshapiro break; 313438032Speter case ISIS_SUBTLV_AUTH_GENERIC: 313538032Speter if (tlen < 2) 313664562Sgshapiro goto tlv_trunc; 313738032Speter key_id = GET_BE_U_2(tptr); 313838032Speter ND_PRINT("%u, password: ", key_id); 313938032Speter tptr += 2; 314038032Speter tlen -= 2; 314138032Speter for(i=0;i<tlen;i++) { 314238032Speter ND_PRINT("%02x", GET_U_1(tptr + i)); 314338032Speter } 314438032Speter break; 314538032Speter case ISIS_SUBTLV_AUTH_PRIVATE: 314638032Speter default: 314738032Speter if (!print_unknown_data(ndo, tptr, "\n\t\t ", tlen)) 314838032Speter return(0); 314938032Speter break; 315090792Sgshapiro } 315190792Sgshapiro break; 315238032Speter 315338032Speter case ISIS_TLV_PTP_ADJ: 315438032Speter tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr; 315538032Speter if(tlen>=1) { 315690792Sgshapiro ND_PRINT("\n\t Adjacency State: %s (%u)", 315738032Speter tok2str(isis_ptp_adjancey_values, "unknown", GET_U_1(tptr)), 315838032Speter GET_U_1(tptr)); 315938032Speter tlen--; 316064562Sgshapiro } 316138032Speter if(tlen>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { 316238032Speter ND_PRINT("\n\t Extended Local circuit-ID: 0x%08x", 316338032Speter GET_BE_U_4(tlv_ptp_adj->extd_local_circuit_id)); 316490792Sgshapiro tlen-=sizeof(tlv_ptp_adj->extd_local_circuit_id); 316590792Sgshapiro } 316638032Speter if(tlen>=SYSTEM_ID_LEN) { 316738032Speter ND_TCHECK_LEN(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN); 316890792Sgshapiro ND_PRINT("\n\t Neighbor System-ID: %s", 316990792Sgshapiro isis_print_id(ndo, tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)); 317090792Sgshapiro tlen-=SYSTEM_ID_LEN; 317190792Sgshapiro } 317290792Sgshapiro if(tlen>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { 317390792Sgshapiro ND_PRINT("\n\t Neighbor Extended Local circuit-ID: 0x%08x", 317490792Sgshapiro GET_BE_U_4(tlv_ptp_adj->neighbor_extd_local_circuit_id)); 317590792Sgshapiro } 317690792Sgshapiro break; 317790792Sgshapiro 317890792Sgshapiro case ISIS_TLV_PROTOCOLS: 317990792Sgshapiro ND_PRINT("\n\t NLPID(s): "); 318090792Sgshapiro while (tlen != 0) { 318190792Sgshapiro ND_PRINT("%s (0x%02x)", 318290792Sgshapiro tok2str(nlpid_values, 318390792Sgshapiro "unknown", 318490792Sgshapiro GET_U_1(tptr)), 318590792Sgshapiro GET_U_1(tptr)); 318690792Sgshapiro if (tlen>1) /* further NPLIDs ? - put comma */ 318790792Sgshapiro ND_PRINT(", "); 318890792Sgshapiro tptr++; 318990792Sgshapiro tlen--; 319090792Sgshapiro } 319190792Sgshapiro break; 319290792Sgshapiro 319390792Sgshapiro case ISIS_TLV_MT_PORT_CAP: 319490792Sgshapiro { 319590792Sgshapiro if (tlen < 2) 319690792Sgshapiro goto tlv_trunc; 319790792Sgshapiro 319890792Sgshapiro ND_PRINT("\n\t RES: %u, MTID(s): %u", 319938032Speter (GET_BE_U_2(tptr) >> 12), 320038032Speter (GET_BE_U_2(tptr) & 0x0fff)); 320138032Speter 320238032Speter tptr += 2; 320338032Speter tlen -= 2; 320473188Sgshapiro 320538032Speter if (tlen) 320638032Speter isis_print_mt_port_cap_subtlv(ndo, tptr, tlen); 320738032Speter 320864562Sgshapiro break; 320990792Sgshapiro } 321090792Sgshapiro 321190792Sgshapiro case ISIS_TLV_MT_CAPABILITY: 321238032Speter if (tlen < 2) 321338032Speter goto tlv_trunc; 321464562Sgshapiro 321538032Speter ND_PRINT("\n\t O: %u, RES: %u, MTID(s): %u", 321638032Speter (GET_BE_U_2(tptr) >> 15) & 0x01, 321738032Speter (GET_BE_U_2(tptr) >> 12) & 0x07, 321838032Speter GET_BE_U_2(tptr) & 0x0fff); 321938032Speter 322038032Speter tptr += 2; 322138032Speter tlen -= 2; 322238032Speter 322338032Speter if (tlen) 322438032Speter isis_print_mt_capability_subtlv(ndo, tptr, tlen); 322538032Speter 322638032Speter break; 322743730Speter 322838032Speter case ISIS_TLV_TE_ROUTER_ID: 322938032Speter if (tlen < sizeof(nd_ipv4)) 323038032Speter goto tlv_trunc; 323138032Speter ND_PRINT("\n\t Traffic Engineering Router ID: %s", GET_IPADDR_STRING(pptr)); 323290792Sgshapiro break; 323373188Sgshapiro 323473188Sgshapiro case ISIS_TLV_IPADDR: 323573188Sgshapiro while (tlen != 0) { 323673188Sgshapiro if (tlen < sizeof(nd_ipv4)) 323773188Sgshapiro goto tlv_trunc; 323873188Sgshapiro ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); 323990792Sgshapiro tptr += sizeof(nd_ipv4); 324090792Sgshapiro tlen -= sizeof(nd_ipv4); 324190792Sgshapiro } 324273188Sgshapiro break; 324338032Speter 324438032Speter case ISIS_TLV_HOSTNAME: 324538032Speter ND_PRINT("\n\t Hostname: "); 324638032Speter nd_printjnp(ndo, tptr, tlen); 324738032Speter break; 324838032Speter 324938032Speter case ISIS_TLV_SHARED_RISK_GROUP: 325090792Sgshapiro if (tlen < NODE_ID_LEN) 325138032Speter break; 325238032Speter ND_TCHECK_LEN(tptr, NODE_ID_LEN); 325338032Speter ND_PRINT("\n\t IS Neighbor: %s", isis_print_id(ndo, tptr, NODE_ID_LEN)); 325438032Speter tptr+=NODE_ID_LEN; 325590792Sgshapiro tlen-=NODE_ID_LEN; 325690792Sgshapiro 325790792Sgshapiro if (tlen < 1) 325838032Speter break; 325938032Speter ND_PRINT(", Flags: [%s]", 326038032Speter ISIS_MASK_TLV_SHARED_RISK_GROUP(GET_U_1(tptr)) ? "numbered" : "unnumbered"); 326190792Sgshapiro tptr++; 326290792Sgshapiro tlen--; 326390792Sgshapiro 326490792Sgshapiro if (tlen < sizeof(nd_ipv4)) 326590792Sgshapiro break; 326690792Sgshapiro ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); 326764562Sgshapiro tptr+=sizeof(nd_ipv4); 326838032Speter tlen-=sizeof(nd_ipv4); 326938032Speter 327090792Sgshapiro if (tlen < sizeof(nd_ipv4)) 327138032Speter break; 327264562Sgshapiro ND_PRINT("\n\t IPv4 neighbor address: %s", GET_IPADDR_STRING(tptr)); 327390792Sgshapiro tptr+=sizeof(nd_ipv4); 327490792Sgshapiro tlen-=sizeof(nd_ipv4); 327590792Sgshapiro 327664562Sgshapiro while (tlen != 0) { 327764562Sgshapiro if (tlen < 4) 3278102528Sgshapiro goto tlv_trunc; 3279102528Sgshapiro ND_PRINT("\n\t Link-ID: 0x%08x", GET_BE_U_4(tptr)); 328064562Sgshapiro tptr+=4; 328138032Speter tlen-=4; 328290792Sgshapiro } 328390792Sgshapiro break; 328490792Sgshapiro 328590792Sgshapiro case ISIS_TLV_LSP: 328690792Sgshapiro tlv_lsp = (const struct isis_tlv_lsp *)tptr; 328790792Sgshapiro while (tlen != 0) { 328890792Sgshapiro if (tlen < sizeof(struct isis_tlv_lsp)) 328990792Sgshapiro goto tlv_trunc; 329064562Sgshapiro ND_TCHECK_1(tlv_lsp->lsp_id + LSP_ID_LEN - 1); 329138032Speter ND_PRINT("\n\t lsp-id: %s", 329264562Sgshapiro isis_print_id(ndo, tlv_lsp->lsp_id, LSP_ID_LEN)); 329364562Sgshapiro ND_PRINT(", seq: 0x%08x", 329490792Sgshapiro GET_BE_U_4(tlv_lsp->sequence_number)); 329590792Sgshapiro ND_PRINT(", lifetime: %5ds", 329690792Sgshapiro GET_BE_U_2(tlv_lsp->remaining_lifetime)); 329790792Sgshapiro ND_PRINT(", chksum: 0x%04x", GET_BE_U_2(tlv_lsp->checksum)); 329864562Sgshapiro tlen-=sizeof(struct isis_tlv_lsp); 329990792Sgshapiro tlv_lsp++; 330090792Sgshapiro } 330190792Sgshapiro break; 330290792Sgshapiro 330390792Sgshapiro case ISIS_TLV_CHECKSUM: 330490792Sgshapiro if (tlen < ISIS_TLV_CHECKSUM_MINLEN) 330590792Sgshapiro break; 330690792Sgshapiro ND_TCHECK_LEN(tptr, ISIS_TLV_CHECKSUM_MINLEN); 330790792Sgshapiro ND_PRINT("\n\t checksum: 0x%04x ", GET_BE_U_2(tptr)); 330890792Sgshapiro /* do not attempt to verify the checksum if it is zero 330990792Sgshapiro * most likely a HMAC-MD5 TLV is also present and 331090792Sgshapiro * to avoid conflicts the checksum TLV is zeroed. 331190792Sgshapiro * see rfc3358 for details 331290792Sgshapiro */ 331390792Sgshapiro osi_print_cksum(ndo, optr, GET_BE_U_2(tptr), (int)(tptr-optr), 331464562Sgshapiro length); 331590792Sgshapiro break; 331690792Sgshapiro 331738032Speter case ISIS_TLV_POI: 331890792Sgshapiro if (tlen < 1) 331998841Sgshapiro goto tlv_trunc; 332090792Sgshapiro num_system_ids = GET_U_1(tptr); 332190792Sgshapiro tptr++; 332290792Sgshapiro tlen--; 332338032Speter if (num_system_ids == 0) { 332438032Speter /* Not valid */ 332538032Speter ND_PRINT(" No system IDs supplied"); 332690792Sgshapiro } else { 332790792Sgshapiro if (tlen < SYSTEM_ID_LEN) 332890792Sgshapiro goto tlv_trunc; 332990792Sgshapiro ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); 333090792Sgshapiro ND_PRINT("\n\t Purge Originator System-ID: %s", 333190792Sgshapiro isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); 333238032Speter tptr += SYSTEM_ID_LEN; 333338032Speter tlen -= SYSTEM_ID_LEN; 333438032Speter 333538032Speter if (num_system_ids > 1) { 333638032Speter if (tlen < SYSTEM_ID_LEN) 333738032Speter goto tlv_trunc; 333838032Speter ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); 333938032Speter ND_TCHECK_LEN(tptr, 2 * SYSTEM_ID_LEN + 1); 334038032Speter ND_PRINT("\n\t Received from System-ID: %s", 334190792Sgshapiro isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); 334238032Speter } 334338032Speter } 334464562Sgshapiro break; 334538032Speter 334638032Speter case ISIS_TLV_MT_SUPPORTED: 334738032Speter while (tlen != 0) { 334838032Speter /* length can only be a multiple of 2, otherwise there is 334938032Speter something broken -> so decode down until length is 1 */ 335038032Speter if (tlen!=1) { 335138032Speter mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen); 335238032Speter if (mt_len == 0) /* did something go wrong ? */ 335364562Sgshapiro goto trunc; 335438032Speter tptr+=mt_len; 335538032Speter tlen-=mt_len; 335638032Speter } else { 335738032Speter ND_PRINT("\n\t invalid MT-ID"); 335838032Speter break; 335938032Speter } 336038032Speter } 336138032Speter break; 336238032Speter 336338032Speter case ISIS_TLV_RESTART_SIGNALING: 336438032Speter /* first attempt to decode the flags */ 336538032Speter if (tlen < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) 336638032Speter break; 336738032Speter ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN); 336838032Speter ND_PRINT("\n\t Flags [%s]", 336938032Speter bittok2str(isis_restart_flag_values, "none", GET_U_1(tptr))); 337090792Sgshapiro tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; 337190792Sgshapiro tlen-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; 337238032Speter 337338032Speter /* is there anything other than the flags field? */ 337438032Speter if (tlen == 0) 337538032Speter break; 337638032Speter 337738032Speter if (tlen < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) 337838032Speter break; 337964562Sgshapiro ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN); 338038032Speter 338138032Speter ND_PRINT(", Remaining holding time %us", GET_BE_U_2(tptr)); 338238032Speter tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; 338338032Speter tlen-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; 338438032Speter 338538032Speter /* is there an additional sysid field present ?*/ 338638032Speter if (tlen == SYSTEM_ID_LEN) { 338738032Speter ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); 338838032Speter ND_PRINT(", for %s", isis_print_id(ndo, tptr,SYSTEM_ID_LEN)); 338990792Sgshapiro } 339090792Sgshapiro break; 339190792Sgshapiro 339290792Sgshapiro case ISIS_TLV_IDRP_INFO: 339390792Sgshapiro if (tlen < 1) 339438032Speter break; 339538032Speter isis_subtlv_idrp = GET_U_1(tptr); 339638032Speter ND_PRINT("\n\t Inter-Domain Information Type: %s", 339738032Speter tok2str(isis_subtlv_idrp_values, 339890792Sgshapiro "Unknown (0x%02x)", 339964562Sgshapiro isis_subtlv_idrp)); 340090792Sgshapiro tptr++; 340138032Speter tlen--; 340238032Speter switch (isis_subtlv_idrp) { 340338032Speter case ISIS_SUBTLV_IDRP_ASN: 340438032Speter if (tlen < 2) 340538032Speter goto tlv_trunc; 340638032Speter ND_PRINT("AS Number: %u", GET_BE_U_2(tptr)); 340738032Speter break; 340838032Speter case ISIS_SUBTLV_IDRP_LOCAL: 340938032Speter case ISIS_SUBTLV_IDRP_RES: 341038032Speter default: 341138032Speter if (!print_unknown_data(ndo, tptr, "\n\t ", tlen)) 341290792Sgshapiro return(0); 341338032Speter break; 341438032Speter } 341538032Speter break; 341638032Speter 341738032Speter case ISIS_TLV_LSP_BUFFERSIZE: 341864562Sgshapiro if (tlen < 2) 341938032Speter break; 342038032Speter ND_PRINT("\n\t LSP Buffersize: %u", GET_BE_U_2(tptr)); 342164562Sgshapiro break; 342264562Sgshapiro 342364562Sgshapiro case ISIS_TLV_PART_DIS: 342464562Sgshapiro while (tlen != 0) { 342564562Sgshapiro if (tlen < SYSTEM_ID_LEN) 342666494Sgshapiro goto tlv_trunc; 342764562Sgshapiro ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN); 342890792Sgshapiro ND_PRINT("\n\t %s", isis_print_id(ndo, tptr, SYSTEM_ID_LEN)); 342964562Sgshapiro tptr+=SYSTEM_ID_LEN; 343064562Sgshapiro tlen-=SYSTEM_ID_LEN; 343164562Sgshapiro } 343238032Speter break; 343338032Speter 343438032Speter case ISIS_TLV_PREFIX_NEIGH: 343538032Speter if (tlen < sizeof(struct isis_metric_block)) 343638032Speter break; 343790792Sgshapiro ND_TCHECK_LEN(tptr, sizeof(struct isis_metric_block)); 343890792Sgshapiro ND_PRINT("\n\t Metric Block"); 343990792Sgshapiro isis_print_metric_block(ndo, (const struct isis_metric_block *)tptr); 344038032Speter tptr+=sizeof(struct isis_metric_block); 344138032Speter tlen-=sizeof(struct isis_metric_block); 344238032Speter 344338032Speter while (tlen != 0) { 344438032Speter prefix_len=GET_U_1(tptr); /* read out prefix length in semioctets*/ 344538032Speter tptr++; 344690792Sgshapiro tlen--; 344790792Sgshapiro if (prefix_len < 2) { 344890792Sgshapiro ND_PRINT("\n\t\tAddress: prefix length %u < 2", prefix_len); 344938032Speter break; 345090792Sgshapiro } 345190792Sgshapiro if (tlen < prefix_len/2) 345290792Sgshapiro break; 345390792Sgshapiro ND_PRINT("\n\t\tAddress: %s/%u", 345490792Sgshapiro GET_ISONSAP_STRING(tptr, prefix_len / 2), prefix_len * 4); 345590792Sgshapiro tptr+=prefix_len/2; 345690792Sgshapiro tlen-=prefix_len/2; 345790792Sgshapiro } 345890792Sgshapiro break; 345990792Sgshapiro 346090792Sgshapiro case ISIS_TLV_IIH_SEQNR: 346190792Sgshapiro if (tlen < 4) 346290792Sgshapiro break; 346390792Sgshapiro ND_PRINT("\n\t Sequence number: %u", GET_BE_U_4(tptr)); 346490792Sgshapiro break; 346590792Sgshapiro 346690792Sgshapiro case ISIS_TLV_ROUTER_CAPABILITY: 346790792Sgshapiro if (tlen < 5) { 346890792Sgshapiro ND_PRINT(" [object length %u < 5]", tlen); 346990792Sgshapiro nd_print_invalid(ndo); 347090792Sgshapiro break; 347190792Sgshapiro } 347290792Sgshapiro ND_PRINT("\n\t Router-ID %s", GET_IPADDR_STRING(tptr)); 347390792Sgshapiro ND_PRINT(", Flags [%s]", 347490792Sgshapiro bittok2str(isis_tlv_router_capability_flags, "none", GET_U_1(tptr+4))); 347590792Sgshapiro 347690792Sgshapiro /* Optional set of sub-TLV */ 347738032Speter if (tlen > 5) { 347838032Speter isis_print_router_cap_subtlv(ndo, tptr+5, tlen-5); 347938032Speter } 348038032Speter break; 348138032Speter 348238032Speter case ISIS_TLV_VENDOR_PRIVATE: 348338032Speter if (tlen < 3) 348438032Speter break; 348538032Speter vendor_id = GET_BE_U_3(tptr); 348638032Speter ND_PRINT("\n\t Vendor: %s (%u)", 348738032Speter tok2str(oui_values, "Unknown", vendor_id), 348838032Speter vendor_id); 348938032Speter tptr+=3; 349090792Sgshapiro tlen-=3; 349190792Sgshapiro if (tlen != 0) /* hexdump the rest */ 349290792Sgshapiro if (!print_unknown_data(ndo, tptr, "\n\t\t", tlen)) 349390792Sgshapiro return(0); 349438032Speter break; 349538032Speter /* 349638032Speter * FIXME those are the defined TLVs that lack a decoder 349738032Speter * you are welcome to contribute code ;-) 349890792Sgshapiro */ 349990792Sgshapiro 350090792Sgshapiro case ISIS_TLV_DECNET_PHASE4: 350190792Sgshapiro case ISIS_TLV_LUCENT_PRIVATE: 350290792Sgshapiro case ISIS_TLV_IPAUTH: 350390792Sgshapiro case ISIS_TLV_NORTEL_PRIVATE1: 350490792Sgshapiro case ISIS_TLV_NORTEL_PRIVATE2: 350590792Sgshapiro 350690792Sgshapiro default: 350790792Sgshapiro if (ndo->ndo_vflag <= 1) { 350890792Sgshapiro if (!print_unknown_data(ndo, pptr, "\n\t\t", tlv_len)) 350990792Sgshapiro return(0); 351090792Sgshapiro } 351190792Sgshapiro break; 351290792Sgshapiro } 351390792Sgshapirotlv_trunc: 351490792Sgshapiro /* do we want to see an additionally hexdump ? */ 351590792Sgshapiro if (ndo->ndo_vflag> 1) { 351690792Sgshapiro if (!print_unknown_data(ndo, pptr, "\n\t ", tlv_len)) 351790792Sgshapiro return(0); 351890792Sgshapiro } 351990792Sgshapiro 352090792Sgshapiro pptr += tlv_len; 352190792Sgshapiro packet_len -= tlv_len; 352238032Speter } 352390792Sgshapiro 352438032Speter if (packet_len != 0) { 352538032Speter ND_PRINT("\n\t %u straggler bytes", packet_len); 352690792Sgshapiro } 352790792Sgshapiro return (1); 352890792Sgshapiro 352990792Sgshapirotrunc: 353090792Sgshapiro nd_print_trunc(ndo); 353190792Sgshapiro return (1); 353290792Sgshapiro} 353338032Speter 353438032Speterstatic void 353538032Speterosi_print_cksum(netdissect_options *ndo, const uint8_t *pptr, 353638032Speter uint16_t checksum, int checksum_offset, u_int length) 353738032Speter{ 353890792Sgshapiro uint16_t calculated_checksum; 353990792Sgshapiro 354090792Sgshapiro /* do not attempt to verify the checksum if it is zero, 354190792Sgshapiro * if the offset is nonsense, 354290792Sgshapiro * or the base pointer is not sane 354390792Sgshapiro */ 354490792Sgshapiro if (!checksum 354538032Speter || checksum_offset < 0 354638032Speter || !ND_TTEST_2(pptr + checksum_offset) 354738032Speter || (u_int)checksum_offset > length 354838032Speter || !ND_TTEST_LEN(pptr, length)) { 354990792Sgshapiro ND_PRINT(" (unverified)"); 355090792Sgshapiro } else { 355190792Sgshapiro#if 0 355290792Sgshapiro ND_PRINT("\nosi_print_cksum: %p %d %u\n", pptr, checksum_offset, length); 355390792Sgshapiro#endif 355490792Sgshapiro calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); 355538032Speter if (checksum == calculated_checksum) { 355664562Sgshapiro ND_PRINT(" (correct)"); 355738032Speter } else { 355890792Sgshapiro ND_PRINT(" (incorrect should be 0x%04x)", calculated_checksum); 355990792Sgshapiro } 356090792Sgshapiro } 356190792Sgshapiro} 356290792Sgshapiro