print-isoclns.c revision 127675
117680Spst/* 217680Spst * Copyright (c) 1992, 1993, 1994, 1995, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2026183Sfenner * 2117680Spst * Original code by Matt Thomas, Digital Equipment Corporation 2256896Sfenner * 2398527Sfenner * Extensively modified by Hannes Gredler (hannes@juniper.net) for more 2498527Sfenner * complete IS-IS support. 2598527Sfenner * 2656896Sfenner * $FreeBSD: head/contrib/tcpdump/print-isoclns.c 127675 2004-03-31 14:57:24Z bms $ 2717680Spst */ 2817680Spst 2917680Spst#ifndef lint 30127675Sbmsstatic const char rcsid[] _U_ = 31127675Sbms "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.106.2.5 2004/03/24 01:45:26 guy Exp $ (LBL)"; 3217680Spst#endif 3317680Spst 3456896Sfenner#ifdef HAVE_CONFIG_H 3556896Sfenner#include "config.h" 3656896Sfenner#endif 3756896Sfenner 38127675Sbms#include <tcpdump-stdinc.h> 3917680Spst 4017680Spst#include <stdio.h> 4198527Sfenner#include <string.h> 4217680Spst 4317680Spst#include "interface.h" 4417680Spst#include "addrtoname.h" 4517680Spst#include "ethertype.h" 4675118Sfenner#include "ether.h" 4717688Spst#include "extract.h" 48127675Sbms#include "gmpls.h" 4917680Spst 5017688Spst#define NLPID_CLNS 129 /* 0x81 */ 5117688Spst#define NLPID_ESIS 130 /* 0x82 */ 5217688Spst#define NLPID_ISIS 131 /* 0x83 */ 5398527Sfenner#define NLPID_IP6 0x8e 54127675Sbms#define NLPID_IP 0xcc 5517688Spst#define NLPID_NULLNS 0 5617680Spst 57127675Sbms#define IPV4 1 /* AFI value */ 58127675Sbms#define IPV6 2 /* AFI value */ 59127675Sbms 6032149Spst/* 6132149Spst * IS-IS is defined in ISO 10589. Look there for protocol definitions. 6232149Spst */ 6332149Spst 6475118Sfenner#define SYSTEM_ID_LEN ETHER_ADDR_LEN 65127675Sbms#define NODE_ID_LEN SYSTEM_ID_LEN+1 66127675Sbms#define LSP_ID_LEN SYSTEM_ID_LEN+2 67127675Sbms 6832149Spst#define ISIS_VERSION 1 6932149Spst#define PDU_TYPE_MASK 0x1F 7032149Spst#define PRIORITY_MASK 0x7F 7132149Spst 7232149Spst#define L1_LAN_IIH 15 7332149Spst#define L2_LAN_IIH 16 7432149Spst#define PTP_IIH 17 7598527Sfenner#define L1_LSP 18 7698527Sfenner#define L2_LSP 20 7798527Sfenner#define L1_CSNP 24 7898527Sfenner#define L2_CSNP 25 7998527Sfenner#define L1_PSNP 26 8098527Sfenner#define L2_PSNP 27 8132149Spst 82127675Sbmsstatic struct tok isis_pdu_values[] = { 83127675Sbms { L1_LAN_IIH, "L1 Lan IIH"}, 84127675Sbms { L2_LAN_IIH, "L2 Lan IIH"}, 85127675Sbms { PTP_IIH, "p2p IIH"}, 86127675Sbms { L1_LSP, "L1 LSP"}, 87127675Sbms { L2_LSP, "L2 LSP"}, 88127675Sbms { L1_CSNP, "L1 CSNP"}, 89127675Sbms { L2_CSNP, "L2 CSNP"}, 90127675Sbms { L1_PSNP, "L1 PSNP"}, 91127675Sbms { L2_PSNP, "L2 PSNP"}, 92127675Sbms { 0, NULL} 93127675Sbms}; 9498527Sfenner 9532149Spst/* 9632149Spst * A TLV is a tuple of a type, length and a value and is normally used for 9732149Spst * encoding information in all sorts of places. This is an enumeration of 9832149Spst * the well known types. 99127675Sbms * 100127675Sbms * list taken from rfc3359 plus some memory from veterans ;-) 10132149Spst */ 10232149Spst 103127675Sbms#define TLV_AREA_ADDR 1 /* iso10589 */ 104127675Sbms#define TLV_IS_REACH 2 /* iso10589 */ 105127675Sbms#define TLV_ESNEIGH 3 /* iso10589 */ 106127675Sbms#define TLV_PART_DIS 4 /* iso10589 */ 107127675Sbms#define TLV_PREFIX_NEIGH 5 /* iso10589 */ 108127675Sbms#define TLV_ISNEIGH 6 /* iso10589 */ 109127675Sbms#define TLV_ISNEIGH_VARLEN 7 /* iso10589 */ 110127675Sbms#define TLV_PADDING 8 /* iso10589 */ 111127675Sbms#define TLV_LSP 9 /* iso10589 */ 112127675Sbms#define TLV_AUTH 10 /* iso10589, rfc3567 */ 113127675Sbms#define TLV_CHECKSUM 12 /* rfc3358 */ 114127675Sbms#define TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ 115127675Sbms#define TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ 116127675Sbms#define TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ 117127675Sbms#define TLV_DECNET_PHASE4 42 118127675Sbms#define TLV_LUCENT_PRIVATE 66 119127675Sbms#define TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ 120127675Sbms#define TLV_PROTOCOLS 129 /* rfc1195 */ 121127675Sbms#define TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ 122127675Sbms#define TLV_IDRP_INFO 131 /* rfc1195 */ 123127675Sbms#define TLV_IPADDR 132 /* rfc1195 */ 124127675Sbms#define TLV_IPAUTH 133 /* rfc1195 */ 125127675Sbms#define TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ 126127675Sbms#define TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ 127127675Sbms#define TLV_HOSTNAME 137 /* rfc2763 */ 128127675Sbms#define TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ 129127675Sbms#define TLV_NORTEL_PRIVATE1 176 130127675Sbms#define TLV_NORTEL_PRIVATE2 177 131127675Sbms#define TLV_HOLDTIME 198 /* ES-IS */ 132127675Sbms#define TLV_RESTART_SIGNALING 211 /* draft-ietf-isis-restart-01 */ 133127675Sbms#define TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ 134127675Sbms#define TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ 135127675Sbms#define TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ 136127675Sbms#define TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ 137127675Sbms#define TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ 138127675Sbms#define TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ 139127675Sbms#define TLV_PTP_ADJ 240 /* rfc3373 */ 140127675Sbms#define TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ 141127675Sbms#define TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */ 14232149Spst 143127675Sbmsstatic struct tok isis_tlv_values[] = { 144127675Sbms { TLV_AREA_ADDR, "Area address(es)"}, 145127675Sbms { TLV_IS_REACH, "IS Reachability"}, 146127675Sbms { TLV_ESNEIGH, "ES Neighbor(s)"}, 147127675Sbms { TLV_PART_DIS, "Partition DIS"}, 148127675Sbms { TLV_PREFIX_NEIGH, "Prefix Neighbors"}, 149127675Sbms { TLV_ISNEIGH, "IS Neighbor(s)"}, 150127675Sbms { TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, 151127675Sbms { TLV_PADDING, "Padding"}, 152127675Sbms { TLV_LSP, "LSP entries"}, 153127675Sbms { TLV_AUTH, "Authentication"}, 154127675Sbms { TLV_CHECKSUM, "Checksum"}, 155127675Sbms { TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, 156127675Sbms { TLV_EXT_IS_REACH, "Extended IS Reachability"}, 157127675Sbms { TLV_IS_ALIAS_ID, "IS Alias ID"}, 158127675Sbms { TLV_DECNET_PHASE4, "DECnet Phase IV"}, 159127675Sbms { TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, 160127675Sbms { TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, 161127675Sbms { TLV_PROTOCOLS, "Protocols supported"}, 162127675Sbms { TLV_EXT_IP_REACH, "IPv4 External Reachability"}, 163127675Sbms { TLV_IDRP_INFO, "Inter-Domain Information Type"}, 164127675Sbms { TLV_IPADDR, "IPv4 Interface address(es)"}, 165127675Sbms { TLV_IPAUTH, "IPv4 authentication (deprecated)"}, 166127675Sbms { TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, 167127675Sbms { TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, 168127675Sbms { TLV_HOSTNAME, "Hostname"}, 169127675Sbms { TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, 170127675Sbms { TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, 171127675Sbms { TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, 172127675Sbms { TLV_HOLDTIME, "Holdtime"}, 173127675Sbms { TLV_RESTART_SIGNALING, "Restart Signaling"}, 174127675Sbms { TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, 175127675Sbms { TLV_MT_SUPPORTED, "Multi Topology"}, 176127675Sbms { TLV_IP6ADDR, "IPv6 Interface address(es)"}, 177127675Sbms { TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, 178127675Sbms { TLV_IP6_REACH, "IPv6 reachability"}, 179127675Sbms { TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, 180127675Sbms { TLV_PTP_ADJ, "Point-to-point Adjacency State"}, 181127675Sbms { TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, 182127675Sbms { TLV_VENDOR_PRIVATE, "Vendor Private"}, 183127675Sbms { 0, NULL } 184127675Sbms}; 18598527Sfenner 186127675Sbms#define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ 187127675Sbms#define SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* draft-ietf-isis-gmpls-extensions */ 188127675Sbms#define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ 189127675Sbms#define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ 190127675Sbms#define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ 191127675Sbms#define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ 192127675Sbms#define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ 193127675Sbms#define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* draft-ietf-isis-traffic-05 */ 194127675Sbms#define SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ 195127675Sbms#define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* draft-ietf-isis-gmpls-extensions */ 196127675Sbms#define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* draft-ietf-isis-gmpls-extensions */ 19798527Sfenner 198127675Sbmsstatic struct tok isis_ext_is_reach_subtlv_values[] = { 199127675Sbms { SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, 200127675Sbms { SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, 201127675Sbms { SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, 202127675Sbms { SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, 203127675Sbms { SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, 204127675Sbms { SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, 205127675Sbms { SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, 206127675Sbms { SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, 207127675Sbms { SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, 208127675Sbms { SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, 209127675Sbms { SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, 210127675Sbms { 250, "Reserved for cisco specific extensions" }, 211127675Sbms { 251, "Reserved for cisco specific extensions" }, 212127675Sbms { 252, "Reserved for cisco specific extensions" }, 213127675Sbms { 253, "Reserved for cisco specific extensions" }, 214127675Sbms { 254, "Reserved for cisco specific extensions" }, 215127675Sbms { 255, "Reserved for future expansion" }, 216127675Sbms { 0, NULL } 217127675Sbms}; 21898527Sfenner 219127675Sbms#define SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 220127675Sbms#define SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 221127675Sbms 222127675Sbmsstatic struct tok isis_ext_ip_reach_subtlv_values[] = { 223127675Sbms { SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, 224127675Sbms { SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, 225127675Sbms { 0, NULL } 226127675Sbms}; 227127675Sbms 228127675Sbms#define SUBTLV_AUTH_SIMPLE 1 229127675Sbms#define SUBTLV_AUTH_MD5 54 230127675Sbms#define SUBTLV_AUTH_MD5_LEN 16 231127675Sbms#define SUBTLV_AUTH_PRIVATE 255 232127675Sbms 233127675Sbmsstatic struct tok isis_subtlv_auth_values[] = { 234127675Sbms { SUBTLV_AUTH_SIMPLE, "simple text password"}, 235127675Sbms { SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, 236127675Sbms { SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, 237127675Sbms { 0, NULL } 238127675Sbms}; 239127675Sbms 240127675Sbms#define SUBTLV_IDRP_RES 0 241127675Sbms#define SUBTLV_IDRP_LOCAL 1 242127675Sbms#define SUBTLV_IDRP_ASN 2 243127675Sbms 244127675Sbmsstatic struct tok isis_subtlv_idrp_values[] = { 245127675Sbms { SUBTLV_IDRP_RES, "Reserved"}, 246127675Sbms { SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, 247127675Sbms { SUBTLV_IDRP_ASN, "AS Number Tag"}, 248127675Sbms { 0, NULL} 249127675Sbms}; 250127675Sbms 251127675Sbms#define ISIS_8BIT_MASK(x) ((x)&0xff) 252127675Sbms 25398527Sfenner#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) 25498527Sfenner#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) 25598527Sfenner#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) 25698527Sfenner#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) 25798527Sfenner#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) 25898527Sfenner#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) 25998527Sfenner#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) 26098527Sfenner#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) 26198527Sfenner 262127675Sbms#define ISIS_MASK_MTID(x) ((x)&0x0fff) 263127675Sbms#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) 26498527Sfenner 265127675Sbmsstatic struct tok isis_mt_flag_values[] = { 266127675Sbms { 0x4000, "sub-TLVs present"}, 267127675Sbms { 0x8000, "ATT bit set"}, 268127675Sbms { 0, NULL} 269127675Sbms}; 27098527Sfenner 271127675Sbms#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) 272127675Sbms#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) 27398527Sfenner 274127675Sbms#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) 275127675Sbms#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) 276127675Sbms 27798527Sfenner#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) 27898527Sfenner#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) 27998527Sfenner#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) 28098527Sfenner#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) 28198527Sfenner 282127675Sbms#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) 283127675Sbms 284127675Sbmsstatic struct tok isis_mt_values[] = { 285127675Sbms { 0, "IPv4 unicast"}, 286127675Sbms { 1, "In-Band Management"}, 287127675Sbms { 2, "IPv6 unicast"}, 288127675Sbms { 3, "Multicast"}, 289127675Sbms { 4095, "Development, Experimental or Proprietary"}, 290127675Sbms { 0, NULL } 291127675Sbms}; 292127675Sbms 293127675Sbmsstatic struct tok isis_iih_circuit_type_values[] = { 294127675Sbms { 1, "Level 1 only"}, 295127675Sbms { 2, "Level 2 only"}, 296127675Sbms { 3, "Level 1, Level 2"}, 297127675Sbms { 0, NULL} 298127675Sbms}; 299127675Sbms 30098527Sfenner#define ISIS_LSP_TYPE_UNUSED0 0 30198527Sfenner#define ISIS_LSP_TYPE_LEVEL_1 1 30298527Sfenner#define ISIS_LSP_TYPE_UNUSED2 2 30398527Sfenner#define ISIS_LSP_TYPE_LEVEL_2 3 30498527Sfenner 30598527Sfennerstatic struct tok isis_lsp_istype_values[] = { 306127675Sbms { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, 307127675Sbms { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, 308127675Sbms { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, 309127675Sbms { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"}, 310127675Sbms { 0, NULL } 31198527Sfenner}; 31298527Sfenner 313127675Sbmsstatic struct tok osi_nlpid_values[] = { 314127675Sbms { NLPID_CLNS, "CLNS"}, 315127675Sbms { NLPID_IP, "IPv4"}, 316127675Sbms { NLPID_IP6, "IPv6"}, 317127675Sbms { 0, NULL } 31898527Sfenner}; 31998527Sfenner 32032149Spst/* 32132149Spst * Katz's point to point adjacency TLV uses codes to tell us the state of 32232149Spst * the remote adjacency. Enumerate them. 32332149Spst */ 32432149Spst 32532149Spst#define ISIS_PTP_ADJ_UP 0 32632149Spst#define ISIS_PTP_ADJ_INIT 1 32732149Spst#define ISIS_PTP_ADJ_DOWN 2 32832149Spst 32917680Spst 33098527Sfennerstatic struct tok isis_ptp_adjancey_values[] = { 331127675Sbms { ISIS_PTP_ADJ_UP, "Up" }, 332127675Sbms { ISIS_PTP_ADJ_INIT, "Initializing" }, 333127675Sbms { ISIS_PTP_ADJ_DOWN, "Down" }, 334127675Sbms { 0, NULL} 33532149Spst}; 33632149Spst 33798527Sfennerstruct isis_tlv_ptp_adj { 338127675Sbms u_int8_t adjacency_state; 339127675Sbms u_int8_t extd_local_circuit_id[4]; 340127675Sbms u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; 341127675Sbms u_int8_t neighbor_extd_local_circuit_id[4]; 34232149Spst}; 34332149Spst 344127675Sbmsstatic int osi_cksum(const u_int8_t *, u_int); 345127675Sbmsstatic void esis_print(const u_int8_t *, u_int); 346127675Sbmsstatic int isis_print(const u_int8_t *, u_int); 347127675Sbms 348127675Sbmsstruct isis_metric_block { 349127675Sbms u_int8_t metric_default; 350127675Sbms u_int8_t metric_delay; 351127675Sbms u_int8_t metric_expense; 352127675Sbms u_int8_t metric_error; 35398527Sfenner}; 35498527Sfenner 35598527Sfennerstruct isis_tlv_is_reach { 356127675Sbms struct isis_metric_block isis_metric_block; 357127675Sbms u_int8_t neighbor_nodeid[NODE_ID_LEN]; 35898527Sfenner}; 35998527Sfenner 360127675Sbmsstruct isis_tlv_es_reach { 361127675Sbms struct isis_metric_block isis_metric_block; 362127675Sbms u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; 363127675Sbms}; 36498527Sfenner 365127675Sbmsstruct isis_tlv_ip_reach { 366127675Sbms struct isis_metric_block isis_metric_block; 367127675Sbms u_int8_t prefix[4]; 368127675Sbms u_int8_t mask[4]; 369127675Sbms}; 370127675Sbms 371127675Sbmsstatic struct tok isis_is_reach_virtual_values[] = { 372127675Sbms { 0, "IsNotVirtual"}, 373127675Sbms { 1, "IsVirtual"}, 374127675Sbms { 0, NULL } 375127675Sbms}; 376127675Sbms 377127675Sbmsstatic struct tok isis_restart_flag_values[] = { 378127675Sbms { 0x1, "Restart Request"}, 379127675Sbms { 0x2, "Restart Acknowledgement"}, 380127675Sbms { 0, NULL } 381127675Sbms}; 382127675Sbms 38332149Spststruct isis_common_header { 384127675Sbms u_int8_t nlpid; 385127675Sbms u_int8_t fixed_len; 386127675Sbms u_int8_t version; /* Protocol version */ 387127675Sbms u_int8_t id_length; 388127675Sbms u_int8_t pdu_type; /* 3 MSbits are reserved */ 389127675Sbms u_int8_t pdu_version; /* Packet format version */ 390127675Sbms u_int8_t reserved; 391127675Sbms u_int8_t max_area; 39232149Spst}; 39332149Spst 39498527Sfennerstruct isis_iih_lan_header { 395127675Sbms u_int8_t circuit_type; 396127675Sbms u_int8_t source_id[SYSTEM_ID_LEN]; 397127675Sbms u_int8_t holding_time[2]; 398127675Sbms u_int8_t pdu_len[2]; 399127675Sbms u_int8_t priority; 400127675Sbms u_int8_t lan_id[NODE_ID_LEN]; 40132149Spst}; 40298527Sfenner 40398527Sfennerstruct isis_iih_ptp_header { 404127675Sbms u_int8_t circuit_type; 405127675Sbms u_int8_t source_id[SYSTEM_ID_LEN]; 406127675Sbms u_int8_t holding_time[2]; 407127675Sbms u_int8_t pdu_len[2]; 408127675Sbms u_int8_t circuit_id; 40932149Spst}; 41032149Spst 41198527Sfennerstruct isis_lsp_header { 412127675Sbms u_int8_t pdu_len[2]; 413127675Sbms u_int8_t remaining_lifetime[2]; 414127675Sbms u_int8_t lsp_id[LSP_ID_LEN]; 415127675Sbms u_int8_t sequence_number[4]; 416127675Sbms u_int8_t checksum[2]; 417127675Sbms u_int8_t typeblock; 41832149Spst}; 41932149Spst 42098527Sfennerstruct isis_csnp_header { 421127675Sbms u_int8_t pdu_len[2]; 422127675Sbms u_int8_t source_id[NODE_ID_LEN]; 423127675Sbms u_int8_t start_lsp_id[LSP_ID_LEN]; 424127675Sbms u_int8_t end_lsp_id[LSP_ID_LEN]; 42598527Sfenner}; 42632149Spst 42798527Sfennerstruct isis_psnp_header { 428127675Sbms u_int8_t pdu_len[2]; 429127675Sbms u_int8_t source_id[NODE_ID_LEN]; 43098527Sfenner}; 43132149Spst 43298527Sfennerstruct isis_tlv_lsp { 433127675Sbms u_int8_t remaining_lifetime[2]; 434127675Sbms u_int8_t lsp_id[LSP_ID_LEN]; 435127675Sbms u_int8_t sequence_number[4]; 436127675Sbms u_int8_t checksum[2]; 43798527Sfenner}; 438127675Sbms 439127675Sbmsstatic char * 440127675Sbmsprint_nsap(register const u_int8_t *pptr, register int nsap_length) 441127675Sbms{ 442127675Sbms int nsap_idx; 443127675Sbms static char nsap_ascii_output[sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")]; 444127675Sbms char *junk_buf = nsap_ascii_output; 445127675Sbms 446127675Sbms if (nsap_length < 1 || nsap_length > 20) { 447127675Sbms snprintf(nsap_ascii_output, sizeof(nsap_ascii_output), 448127675Sbms "illegal length"); 449127675Sbms return (nsap_ascii_output); 450127675Sbms } 451127675Sbms 452127675Sbms for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { 453127675Sbms if (!TTEST2(*pptr, 1)) 454127675Sbms return (0); 455127675Sbms snprintf(junk_buf, 456127675Sbms sizeof(nsap_ascii_output) - (junk_buf - nsap_ascii_output), 457127675Sbms "%02x", *pptr++); 458127675Sbms junk_buf += strlen(junk_buf); 459127675Sbms if (((nsap_idx & 1) == 0) && 460127675Sbms (nsap_idx + 1 < nsap_length)) { 461127675Sbms *junk_buf++ = '.'; 462127675Sbms } 463127675Sbms } 464127675Sbms *(junk_buf) = '\0'; 465127675Sbms return (nsap_ascii_output); 466127675Sbms} 467127675Sbms 46898527Sfenner#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) 46998527Sfenner#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) 47098527Sfenner#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) 47198527Sfenner#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) 47298527Sfenner#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) 47398527Sfenner#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) 47432149Spst 475127675Sbmsvoid isoclns_print(const u_int8_t *p, u_int length, u_int caplen) 47617680Spst{ 47798527Sfenner const struct isis_common_header *header; 478127675Sbms 47998527Sfenner header = (const struct isis_common_header *)p; 48032149Spst 481127675Sbms printf("%sOSI", caplen < 1 ? "|" : ""); 48217680Spst 483127675Sbms if (caplen < 1) /* enough bytes on the wire ? */ 484127675Sbms return; 485127675Sbms 48617680Spst switch (*p) { 48717680Spst 48817688Spst case NLPID_CLNS: 489127675Sbms (void)printf(", CLNS, length %u", length); 49017680Spst break; 49117680Spst 49217688Spst case NLPID_ESIS: 49317680Spst esis_print(p, length); 49417680Spst return; 49517680Spst 49617688Spst case NLPID_ISIS: 49717751Spst if (!isis_print(p, length)) 498127675Sbms print_unknown_data(p,"\n\t",caplen); 49917680Spst break; 50017680Spst 50117688Spst case NLPID_NULLNS: 502127675Sbms (void)printf(", ISO NULLNS, length: %u", length); 50317680Spst break; 50417680Spst 50517680Spst default: 506127675Sbms (void)printf(", Unknown NLPID 0x%02x, length: %u", p[0], length); 50717680Spst if (caplen > 1) 508127675Sbms print_unknown_data(p,"\n\t",caplen); 50917680Spst break; 51017680Spst } 51117680Spst} 51217680Spst 51317680Spst#define ESIS_REDIRECT 6 51417680Spst#define ESIS_ESH 2 51517680Spst#define ESIS_ISH 4 51617680Spst 517127675Sbmsstatic struct tok esis_values[] = { 518127675Sbms { ESIS_REDIRECT, "redirect"}, 519127675Sbms { ESIS_ESH, "ESH"}, 520127675Sbms { ESIS_ISH, "ISH"}, 521127675Sbms { 0, NULL } 522127675Sbms}; 523127675Sbms 52417680Spststruct esis_hdr { 525127675Sbms u_int8_t version; 526127675Sbms u_int8_t reserved; 527127675Sbms u_int8_t type; 528127675Sbms u_int8_t tmo[2]; 529127675Sbms u_int8_t cksum[2]; 53017680Spst}; 53117680Spst 53217680Spststatic void 533127675Sbmsesis_print(const u_int8_t *p, u_int length) 53417680Spst{ 535127675Sbms const u_int8_t *ep; 53698527Sfenner u_int li; 53798527Sfenner const struct esis_hdr *eh; 53817680Spst 53998527Sfenner if (length <= 2) { 54017680Spst if (qflag) 54117680Spst printf(" bad pkt!"); 54217680Spst else 54317680Spst printf(" no header at all!"); 54417680Spst return; 54517680Spst } 54698527Sfenner li = p[1]; 54798527Sfenner eh = (const struct esis_hdr *) &p[2]; 54817680Spst ep = p + li; 54917680Spst if (li > length) { 55017680Spst if (qflag) 55117680Spst printf(" bad pkt!"); 55217680Spst else 55317680Spst printf(" LI(%d) > PDU size (%d)!", li, length); 55417680Spst return; 55517680Spst } 55617680Spst if (li < sizeof(struct esis_hdr) + 2) { 55717680Spst if (qflag) 55817680Spst printf(" bad pkt!"); 55917680Spst else { 56017680Spst printf(" too short for esis header %d:", li); 56139300Sfenner while (--length != 0) 56217680Spst printf("%02X", *p++); 56317680Spst } 56417680Spst return; 56517680Spst } 56617680Spst 567127675Sbms printf(", ES-IS, %s, length %u", 568127675Sbms tok2str(esis_values,"unknown type: %u",eh->type & 0x1f), 569127675Sbms length); 57017680Spst 571127675Sbms if(vflag < 1) 572127675Sbms return; 57317680Spst 574127675Sbms if (vflag && osi_cksum(p, li)) { 575127675Sbms printf(" bad cksum (got 0x%02x%02x)", 57617751Spst eh->cksum[1], eh->cksum[0]); 57717751Spst default_print(p, length); 57817680Spst return; 57917680Spst } 58017680Spst if (eh->version != 1) { 58117680Spst printf(" unsupported version %d", eh->version); 58217680Spst return; 58317680Spst } 58417680Spst p += sizeof(*eh) + 2; 58517680Spst li -= sizeof(*eh) + 2; /* protoid * li */ 58617680Spst 58717680Spst switch (eh->type & 0x1f) { 58817680Spst case ESIS_REDIRECT: { 589127675Sbms const u_int8_t *dst, *snpa, *is; 59017680Spst 59117680Spst dst = p; p += *p + 1; 59217680Spst if (p > snapend) 59317680Spst return; 594127675Sbms printf("\n\t\t %s", isonsap_string(dst)); 59517680Spst snpa = p; p += *p + 1; 59617680Spst is = p; p += *p + 1; 59717680Spst if (p > snapend) 59817680Spst return; 59917680Spst if (p > ep) { 60017680Spst printf(" [bad li]"); 60117680Spst return; 60217680Spst } 60317680Spst if (is[0] == 0) 60417680Spst printf(" > %s", etheraddr_string(&snpa[1])); 60517680Spst else 60617680Spst printf(" > %s", isonsap_string(is)); 60717680Spst li = ep - p; 60817680Spst break; 60917680Spst } 610127675Sbms 61117680Spst case ESIS_ESH: 61217680Spst break; 613127675Sbms 61417680Spst case ESIS_ISH: { 615127675Sbms const u_int8_t *is; 61617680Spst 61717680Spst is = p; p += *p + 1; 61817680Spst if (p > ep) { 61917680Spst printf(" [bad li]"); 62017680Spst return; 62117680Spst } 62217680Spst if (p > snapend) 62317680Spst return; 62417751Spst if (!qflag) 625127675Sbms printf("\n\tNET: %s", print_nsap(is+1,*is)); 62617680Spst li = ep - p; 62717680Spst break; 62817680Spst } 62917680Spst 63017680Spst default: 631127675Sbms if (vflag <= 1) { 632127675Sbms if (p < snapend) 633127675Sbms print_unknown_data(p,"\n\t ",snapend-p); 634127675Sbms } 635127675Sbms return; 63617680Spst } 637127675Sbms 638127675Sbms /* hexdump - FIXME ? */ 639127675Sbms if (vflag > 1) { 640127675Sbms if (p < snapend) 641127675Sbms print_unknown_data(p,"\n\t ",snapend-p); 642127675Sbms } 64317680Spst if (vflag) 64417680Spst while (p < ep && li) { 64598527Sfenner u_int op, opli; 646127675Sbms const u_int8_t *q; 64717680Spst 64817680Spst if (snapend - p < 2) 64917680Spst return; 65017680Spst if (li < 2) { 651127675Sbms printf(", bad opts/li"); 65217680Spst return; 65317680Spst } 65417680Spst op = *p++; 65517680Spst opli = *p++; 65617680Spst li -= 2; 65717680Spst if (opli > li) { 658127675Sbms printf(", opt (%d) too long", op); 65917680Spst return; 66017680Spst } 66117680Spst li -= opli; 66217680Spst q = p; 66317680Spst p += opli; 664127675Sbms 66517680Spst if (snapend < p) 66617680Spst return; 667127675Sbms 668127675Sbms if (op == TLV_HOLDTIME && opli == 2) { 669127675Sbms printf("\n\tholdtime: %us", EXTRACT_16BITS(q)); 67017680Spst continue; 67117680Spst } 672127675Sbms 673127675Sbms if (op == TLV_PROTOCOLS && opli >= 1) { 674127675Sbms printf("\n\t%s (length: %u): %s", 675127675Sbms tok2str(isis_tlv_values, "unknown", op), 676127675Sbms opli, 677127675Sbms tok2str(osi_nlpid_values,"Unknown 0x%02x",*q)); 678127675Sbms continue; 679127675Sbms } 680127675Sbms 681127675Sbms print_unknown_data(q,"\n\t ",opli); 68217680Spst } 68317680Spst} 68417680Spst 685127675Sbms/* shared routine for printing system, node and lsp-ids */ 686127675Sbmsstatic char * 687127675Sbmsisis_print_id(const u_int8_t *cp, int id_len) 68898527Sfenner{ 689127675Sbms int i; 690127675Sbms static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; 691127675Sbms char *pos = id; 69217688Spst 693127675Sbms for (i = 1; i <= SYSTEM_ID_LEN; i++) { 694127675Sbms snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); 695127675Sbms pos += strlen(pos); 696127675Sbms if (i == 2 || i == 4) 697127675Sbms *pos++ = '.'; 69898527Sfenner } 699127675Sbms if (id_len >= NODE_ID_LEN) { 700127675Sbms snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); 701127675Sbms pos += strlen(pos); 702127675Sbms } 703127675Sbms if (id_len == LSP_ID_LEN) 704127675Sbms snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); 705127675Sbms return (id); 70698527Sfenner} 70798527Sfenner 708127675Sbms/* print the 4-byte metric block which is common found in the old-style TLVs */ 70998527Sfennerstatic int 710127675Sbmsisis_print_metric_block (const struct isis_metric_block *isis_metric_block) 71198527Sfenner{ 712127675Sbms printf(", Default Metric: %d, %s", 713127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), 714127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); 715127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) 716127675Sbms printf("\n\t\t Delay Metric: %d, %s", 717127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), 718127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); 719127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) 720127675Sbms printf("\n\t\t Expense Metric: %d, %s", 721127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), 722127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); 723127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) 724127675Sbms printf("\n\t\t Error Metric: %d, %s", 725127675Sbms ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), 726127675Sbms ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); 72798527Sfenner 728127675Sbms return(1); /* everything is ok */ 72998527Sfenner} 73098527Sfenner 73198527Sfennerstatic int 732127675Sbmsisis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length) 73398527Sfenner{ 734127675Sbms int prefix_len; 735127675Sbms const struct isis_tlv_ip_reach *tlv_ip_reach; 73698527Sfenner 737127675Sbms tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; 738127675Sbms 739127675Sbms while (length > 0) { 740127675Sbms if ((size_t)length < sizeof(*tlv_ip_reach)) { 741127675Sbms printf("short IPv4 Reachability (%d vs %lu)", 742127675Sbms length, 743127675Sbms (unsigned long)sizeof(*tlv_ip_reach)); 74498527Sfenner return (0); 74598527Sfenner } 746127675Sbms 747127675Sbms if (!TTEST(*tlv_ip_reach)) 748127675Sbms return (0); 749127675Sbms 750127675Sbms prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); 751127675Sbms 752127675Sbms if (prefix_len == -1) 753127675Sbms printf("%sIPv4 prefix: %s mask %s", 754127675Sbms ident, 755127675Sbms ipaddr_string((tlv_ip_reach->prefix)), 756127675Sbms ipaddr_string((tlv_ip_reach->mask))); 757127675Sbms else 758127675Sbms printf("%sIPv4 prefix: %15s/%u", 759127675Sbms ident, 760127675Sbms ipaddr_string((tlv_ip_reach->prefix)), 761127675Sbms prefix_len); 762127675Sbms 763127675Sbms printf(", Distribution: %s, Metric: %u, %s", 764127675Sbms ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", 765127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), 766127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); 767127675Sbms 768127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) 769127675Sbms printf("%s Delay Metric: %u, %s", 770127675Sbms ident, 771127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), 772127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); 773127675Sbms 774127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) 775127675Sbms printf("%s Expense Metric: %u, %s", 776127675Sbms ident, 777127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), 778127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); 779127675Sbms 780127675Sbms if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) 781127675Sbms printf("%s Error Metric: %u, %s", 782127675Sbms ident, 783127675Sbms ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), 784127675Sbms ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); 785127675Sbms 786127675Sbms length -= sizeof(struct isis_tlv_ip_reach); 787127675Sbms tlv_ip_reach++; 78898527Sfenner } 78998527Sfenner return (1); 79098527Sfenner} 79198527Sfenner 792127675Sbms/* 793127675Sbms * this is the common IP-REACH subTLV decoder it is called 794127675Sbms * from various EXTD-IP REACH TLVs (135,235,236,237) 795127675Sbms */ 79698527Sfenner 797127675Sbmsstatic int 798127675Sbmsisis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { 799127675Sbms 800127675Sbms /* first lets see if we know the subTLVs name*/ 801127675Sbms printf("%s%s subTLV #%u, length: %u", 802127675Sbms ident, 803127675Sbms tok2str(isis_ext_ip_reach_subtlv_values, 804127675Sbms "unknown", 805127675Sbms subt), 806127675Sbms subt, 807127675Sbms subl); 808127675Sbms 809127675Sbms if (!TTEST2(*tptr,subl)) 810127675Sbms goto trunctlv; 811127675Sbms 812127675Sbms switch(subt) { 813127675Sbms case SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: 814127675Sbms while (subl >= 4) { 815127675Sbms printf(", 0x%08x (=%u)", 816127675Sbms EXTRACT_32BITS(tptr), 817127675Sbms EXTRACT_32BITS(tptr)); 818127675Sbms tptr+=4; 819127675Sbms subl-=4; 82017688Spst } 821127675Sbms break; 822127675Sbms case SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: 823127675Sbms while (subl >= 8) { 824127675Sbms printf(", 0x%08x%08x", 825127675Sbms EXTRACT_32BITS(tptr), 826127675Sbms EXTRACT_32BITS(tptr+4)); 827127675Sbms tptr+=8; 828127675Sbms subl-=8; 829127675Sbms } 830127675Sbms break; 831127675Sbms default: 832127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 833127675Sbms subl)) 834127675Sbms return(0); 835127675Sbms break; 836127675Sbms } 837127675Sbms return(1); 838127675Sbms 839127675Sbmstrunctlv: 840127675Sbms printf("%spacket exceeded snapshot",ident); 841127675Sbms return(0); 84298527Sfenner} 84317688Spst 844127675Sbms/* 845127675Sbms * this is the common IS-REACH subTLV decoder it is called 846127675Sbms * from isis_print_ext_is_reach() 847127675Sbms */ 848127675Sbms 84998527Sfennerstatic int 850127675Sbmsisis_print_is_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { 85198527Sfenner 852127675Sbms int priority_level; 853127675Sbms union { /* int to float conversion buffer for several subTLVs */ 854127675Sbms float f; 855127675Sbms u_int32_t i; 856127675Sbms } bw; 85798527Sfenner 858127675Sbms /* first lets see if we know the subTLVs name*/ 859127675Sbms printf("%s%s subTLV #%u, length: %u", 860127675Sbms ident, 861127675Sbms tok2str(isis_ext_is_reach_subtlv_values, 862127675Sbms "unknown", 863127675Sbms subt), 864127675Sbms subt, 865127675Sbms subl); 86698527Sfenner 867127675Sbms if (!TTEST2(*tptr,subl)) 868127675Sbms goto trunctlv; 86998527Sfenner 870127675Sbms switch(subt) { 871127675Sbms case SUBTLV_EXT_IS_REACH_ADMIN_GROUP: 872127675Sbms case SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: 873127675Sbms case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: 874127675Sbms if (subl >= 4) { 875127675Sbms printf(", 0x%08x", EXTRACT_32BITS(tptr)); 876127675Sbms if (subl == 8) /* draft-ietf-isis-gmpls-extensions */ 877127675Sbms printf(", 0x%08x", EXTRACT_32BITS(tptr+4)); 878127675Sbms } 879127675Sbms break; 880127675Sbms case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: 881127675Sbms case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: 882127675Sbms if (subl >= 4) 883127675Sbms printf(", %s", ipaddr_string(tptr)); 884127675Sbms break; 885127675Sbms case SUBTLV_EXT_IS_REACH_MAX_LINK_BW : 886127675Sbms case SUBTLV_EXT_IS_REACH_RESERVABLE_BW: 887127675Sbms if (subl >= 4) { 888127675Sbms bw.i = EXTRACT_32BITS(tptr); 889127675Sbms printf(", %.3f Mbps", bw.f*8/1000000 ); 890127675Sbms } 891127675Sbms break; 892127675Sbms case SUBTLV_EXT_IS_REACH_UNRESERVED_BW : 893127675Sbms if (subl >= 32) { 894127675Sbms for (priority_level = 0; priority_level < 8; priority_level++) { 895127675Sbms bw.i = EXTRACT_32BITS(tptr); 896127675Sbms printf("%s priority level %d: %.3f Mbps", 897127675Sbms ident, 898127675Sbms priority_level, 899127675Sbms bw.f*8/1000000 ); 900127675Sbms tptr+=4; 901127675Sbms } 902127675Sbms } 903127675Sbms break; 904127675Sbms case SUBTLV_EXT_IS_REACH_TE_METRIC: 905127675Sbms if (subl >= 3) 906127675Sbms printf(", %u", EXTRACT_24BITS(tptr)); 907127675Sbms break; 908127675Sbms case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: 909127675Sbms if (subl >= 2) { 910127675Sbms printf(", %s, Priority %u", 911127675Sbms bittok2str(gmpls_link_prot_values, "none", *tptr), 912127675Sbms *(tptr+1)); 913127675Sbms } 914127675Sbms break; 915127675Sbms case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: 916127675Sbms if (subl >= 36) { 917127675Sbms printf("%s Interface Switching Capability:%s", 918127675Sbms ident, 919127675Sbms tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); 920127675Sbms printf(", LSP Encoding: %s", 921127675Sbms tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); 922127675Sbms tptr+=4; 923127675Sbms printf("%s Max LSP Bandwidth:",ident); 924127675Sbms for (priority_level = 0; priority_level < 8; priority_level++) { 925127675Sbms bw.i = EXTRACT_32BITS(tptr); 926127675Sbms printf("%s priority level %d: %.3f Mbps", 927127675Sbms ident, 928127675Sbms priority_level, 929127675Sbms bw.f*8/1000000 ); 930127675Sbms tptr+=4; 931127675Sbms } 932127675Sbms subl-=36; 933127675Sbms /* there is some optional stuff left to decode but this is as of yet 934127675Sbms not specified so just lets hexdump what is left */ 935127675Sbms if(subl>0){ 936127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 937127675Sbms subl-36)) 938127675Sbms return(0); 939127675Sbms } 940127675Sbms } 941127675Sbms break; 942127675Sbms default: 943127675Sbms if(!print_unknown_data(tptr,"\n\t\t ", 944127675Sbms subl)) 945127675Sbms return(0); 946127675Sbms break; 947127675Sbms } 948127675Sbms return(1); 94998527Sfenner 950127675Sbmstrunctlv: 951127675Sbms printf("%spacket exceeded snapshot",ident); 952127675Sbms return(0); 953127675Sbms} 95498527Sfenner 95598527Sfenner 956127675Sbms/* 957127675Sbms * this is the common IS-REACH decoder it is called 958127675Sbms * from various EXTD-IS REACH style TLVs (22,24,222) 959127675Sbms */ 96098527Sfenner 961127675Sbmsstatic int 962127675Sbmsisis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) { 96398527Sfenner 964127675Sbms char ident_buffer[20]; 965127675Sbms int subtlv_type,subtlv_len,subtlv_sum_len; 966127675Sbms int proc_bytes = 0; /* how many bytes did we process ? */ 967127675Sbms 968127675Sbms if (!TTEST2(*tptr, NODE_ID_LEN)) 969127675Sbms return(0); 97098527Sfenner 971127675Sbms printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)); 972127675Sbms tptr+=(NODE_ID_LEN); 97398527Sfenner 974127675Sbms if (tlv_type != TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ 975127675Sbms if (!TTEST2(*tptr, 3)) /* and is therefore skipped */ 976127675Sbms return(0); 977127675Sbms printf(", Metric: %d",EXTRACT_24BITS(tptr)); 978127675Sbms tptr+=3; 979127675Sbms } 980127675Sbms 981127675Sbms if (!TTEST2(*tptr, 1)) 982127675Sbms return(0); 983127675Sbms subtlv_sum_len=*(tptr++); /* read out subTLV length */ 984127675Sbms proc_bytes=NODE_ID_LEN+3+1; 985127675Sbms printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); 986127675Sbms if (subtlv_sum_len) { 987127675Sbms printf(" (%u)",subtlv_sum_len); 988127675Sbms while (subtlv_sum_len>0) { 989127675Sbms if (!TTEST2(*tptr,2)) 990127675Sbms return(0); 991127675Sbms subtlv_type=*(tptr++); 992127675Sbms subtlv_len=*(tptr++); 993127675Sbms /* prepend the ident string */ 994127675Sbms snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 995127675Sbms if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer)) 996127675Sbms return(0); 997127675Sbms tptr+=subtlv_len; 998127675Sbms subtlv_sum_len-=(subtlv_len+2); 999127675Sbms proc_bytes+=(subtlv_len+2); 1000127675Sbms } 1001127675Sbms } 1002127675Sbms return(proc_bytes); 100317688Spst} 100417688Spst 100517688Spst/* 1006127675Sbms * this is the common Multi Topology ID decoder 1007127675Sbms * it is called from various MT-TLVs (222,229,235,237) 1008127675Sbms */ 1009127675Sbms 1010127675Sbmsstatic int 1011127675Sbmsisis_print_mtid (const u_int8_t *tptr,const char *ident) { 1012127675Sbms 1013127675Sbms if (!TTEST2(*tptr, 2)) 1014127675Sbms return(0); 1015127675Sbms 1016127675Sbms printf("%s%s", 1017127675Sbms ident, 1018127675Sbms tok2str(isis_mt_values, 1019127675Sbms "Reserved for IETF Consensus", 1020127675Sbms ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))); 1021127675Sbms 1022127675Sbms printf(" Topology (0x%03x), Flags: [%s]", 1023127675Sbms ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), 1024127675Sbms bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))); 1025127675Sbms 1026127675Sbms return(2); 1027127675Sbms} 1028127675Sbms 1029127675Sbms/* 1030127675Sbms * this is the common extended IP reach decoder 1031127675Sbms * it is called from TLVs (135,235,236,237) 1032127675Sbms * we process the TLV and optional subTLVs and return 1033127675Sbms * the amount of processed bytes 1034127675Sbms */ 1035127675Sbms 1036127675Sbmsstatic int 1037127675Sbmsisis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) { 1038127675Sbms 1039127675Sbms char ident_buffer[20]; 1040127675Sbms u_int8_t prefix[16]; /* shared copy buffer for IPv4 and IPv6 prefixes */ 1041127675Sbms u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; 1042127675Sbms 1043127675Sbms if (!TTEST2(*tptr, 4)) 1044127675Sbms return (0); 1045127675Sbms metric = EXTRACT_32BITS(tptr); 1046127675Sbms processed=4; 1047127675Sbms tptr+=4; 1048127675Sbms 1049127675Sbms if (afi == IPV4) { 1050127675Sbms if (!TTEST2(*tptr, 1)) /* fetch status byte */ 1051127675Sbms return (0); 1052127675Sbms status_byte=*(tptr++); 1053127675Sbms bit_length = status_byte&0x3f; 1054127675Sbms processed++; 1055127675Sbms#ifdef INET6 1056127675Sbms } else if (afi == IPV6) { 1057127675Sbms if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ 1058127675Sbms return (0); 1059127675Sbms status_byte=*(tptr++); 1060127675Sbms bit_length=*(tptr++); 1061127675Sbms processed+=2; 1062127675Sbms#endif 1063127675Sbms } else 1064127675Sbms return (0); /* somebody is fooling us */ 1065127675Sbms 1066127675Sbms byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ 1067127675Sbms 1068127675Sbms if (!TTEST2(*tptr, byte_length)) 1069127675Sbms return (0); 1070127675Sbms memset(prefix, 0, 16); /* clear the copy buffer */ 1071127675Sbms memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ 1072127675Sbms tptr+=byte_length; 1073127675Sbms processed+=byte_length; 1074127675Sbms 1075127675Sbms if (afi == IPV4) 1076127675Sbms printf("%sIPv4 prefix: %15s/%u", 1077127675Sbms ident, 1078127675Sbms ipaddr_string(prefix), 1079127675Sbms bit_length); 1080127675Sbms#ifdef INET6 1081127675Sbms if (afi == IPV6) 1082127675Sbms printf("%sIPv6 prefix: %s/%u", 1083127675Sbms ident, 1084127675Sbms ip6addr_string(prefix), 1085127675Sbms bit_length); 1086127675Sbms#endif 1087127675Sbms 1088127675Sbms printf(", Distribution: %s, Metric: %u", 1089127675Sbms ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", 1090127675Sbms metric); 1091127675Sbms 1092127675Sbms if (afi == IPV4 && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) 1093127675Sbms printf(", sub-TLVs present"); 1094127675Sbms#ifdef INET6 1095127675Sbms if (afi == IPV6) 1096127675Sbms printf(", %s%s", 1097127675Sbms ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", 1098127675Sbms ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); 1099127675Sbms#endif 1100127675Sbms 1101127675Sbms if ((ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte) && afi == IPV4) || 1102127675Sbms (ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) && afi == IPV6)) { 1103127675Sbms /* assume that one prefix can hold more 1104127675Sbms than one subTLV - therefore the first byte must reflect 1105127675Sbms the aggregate bytecount of the subTLVs for this prefix 1106127675Sbms */ 1107127675Sbms if (!TTEST2(*tptr, 1)) 1108127675Sbms return (0); 1109127675Sbms sublen=*(tptr++); 1110127675Sbms processed+=sublen+1; 1111127675Sbms printf(" (%u)",sublen); /* print out subTLV length */ 1112127675Sbms 1113127675Sbms while (sublen>0) { 1114127675Sbms if (!TTEST2(*tptr,2)) 1115127675Sbms return (0); 1116127675Sbms subtlvtype=*(tptr++); 1117127675Sbms subtlvlen=*(tptr++); 1118127675Sbms /* prepend the ident string */ 1119127675Sbms snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); 1120127675Sbms if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer)) 1121127675Sbms return(0); 1122127675Sbms tptr+=subtlvlen; 1123127675Sbms sublen-=(subtlvlen+2); 1124127675Sbms } 1125127675Sbms } 1126127675Sbms return (processed); 1127127675Sbms} 1128127675Sbms 1129127675Sbms/* 113017688Spst * isis_print 113117688Spst * Decode IS-IS packets. Return 0 on error. 113217688Spst */ 113317688Spst 1134127675Sbmsstatic int isis_print (const u_int8_t *p, u_int length) 113517688Spst{ 113698527Sfenner const struct isis_common_header *header; 113717688Spst 113898527Sfenner const struct isis_iih_lan_header *header_iih_lan; 113998527Sfenner const struct isis_iih_ptp_header *header_iih_ptp; 114098527Sfenner const struct isis_lsp_header *header_lsp; 114198527Sfenner const struct isis_csnp_header *header_csnp; 114298527Sfenner const struct isis_psnp_header *header_psnp; 114317688Spst 114498527Sfenner const struct isis_tlv_lsp *tlv_lsp; 114598527Sfenner const struct isis_tlv_ptp_adj *tlv_ptp_adj; 114698527Sfenner const struct isis_tlv_is_reach *tlv_is_reach; 1147127675Sbms const struct isis_tlv_es_reach *tlv_es_reach; 114898527Sfenner 1149127675Sbms u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; 1150127675Sbms u_int8_t ext_is_len, ext_ip_len, mt_len; 1151127675Sbms const u_int8_t *optr, *pptr, *tptr; 115298527Sfenner u_short packet_len,pdu_len; 1153127675Sbms u_int i; 115498527Sfenner 115598527Sfenner packet_len=length; 1156127675Sbms optr = p; /* initialize the _o_riginal pointer to the packet start - 1157127675Sbms need it for parsing the checksum TLV */ 1158127675Sbms header = (const struct isis_common_header *)p; 115998527Sfenner TCHECK(*header); 1160127675Sbms pptr = p+(ISIS_COMMON_HEADER_SIZE); 116198527Sfenner header_iih_lan = (const struct isis_iih_lan_header *)pptr; 116298527Sfenner header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; 116398527Sfenner header_lsp = (const struct isis_lsp_header *)pptr; 116498527Sfenner header_csnp = (const struct isis_csnp_header *)pptr; 116598527Sfenner header_psnp = (const struct isis_psnp_header *)pptr; 1166127675Sbms 116717688Spst /* 116817688Spst * Sanity checking of the header. 116917688Spst */ 117017688Spst 117117688Spst if (header->version != ISIS_VERSION) { 117298527Sfenner printf(", version %d packet not supported", header->version); 117398527Sfenner return (0); 117417688Spst } 117517688Spst 117617688Spst if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) { 117798527Sfenner printf(", system ID length of %d is not supported", 117817688Spst header->id_length); 117998527Sfenner return (0); 118017688Spst } 1181127675Sbms 1182127675Sbms if (header->pdu_version != ISIS_VERSION) { 1183127675Sbms printf(", version %d packet not supported", header->pdu_version); 118498527Sfenner return (0); 118517688Spst } 118617688Spst 118798527Sfenner max_area = header->max_area; 118817688Spst switch(max_area) { 118917688Spst case 0: 1190127675Sbms max_area = 3; /* silly shit */ 119117688Spst break; 119217688Spst case 255: 119398527Sfenner printf(", bad packet -- 255 areas"); 119498527Sfenner return (0); 119517688Spst default: 119617688Spst break; 119717688Spst } 119817688Spst 1199127675Sbms id_length = header->id_length; 1200127675Sbms switch(id_length) { 1201127675Sbms case 0: 1202127675Sbms id_length = 6; /* silly shit again */ 1203127675Sbms break; 1204127675Sbms case 1: /* 1-8 are valid sys-ID lenghts */ 1205127675Sbms case 2: 1206127675Sbms case 3: 1207127675Sbms case 4: 1208127675Sbms case 5: 1209127675Sbms case 6: 1210127675Sbms case 7: 1211127675Sbms case 8: 1212127675Sbms break; 1213127675Sbms case 255: 1214127675Sbms id_length = 0; /* entirely useless */ 1215127675Sbms break; 1216127675Sbms default: 1217127675Sbms break; 1218127675Sbms } 1219127675Sbms 1220127675Sbms /* toss any non 6-byte sys-ID len PDUs */ 1221127675Sbms if (id_length != 6 ) { 1222127675Sbms printf(", bad packet -- illegal sys-ID length (%u)", id_length); 1223127675Sbms return (0); 1224127675Sbms } 1225127675Sbms 1226127675Sbms pdu_type=header->pdu_type; 1227127675Sbms 1228127675Sbms /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ 1229127675Sbms if (vflag < 1) { 1230127675Sbms printf(", IS-IS, %s", 1231127675Sbms tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type)); 1232127675Sbms 1233127675Sbms switch (pdu_type) { 1234127675Sbms 1235127675Sbms case L1_LAN_IIH: 1236127675Sbms case L2_LAN_IIH: 1237127675Sbms printf(", src-id %s", 1238127675Sbms isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN)); 1239127675Sbms printf(", lan-id %s, prio %u", 1240127675Sbms isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), 1241127675Sbms header_iih_lan->priority); 1242127675Sbms break; 1243127675Sbms case PTP_IIH: 1244127675Sbms printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN)); 1245127675Sbms break; 1246127675Sbms case L1_LSP: 1247127675Sbms case L2_LSP: 1248127675Sbms printf(", lsp-id %s, seq 0x%08x, lifetime %5us", 1249127675Sbms isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), 1250127675Sbms EXTRACT_32BITS(header_lsp->sequence_number), 1251127675Sbms EXTRACT_16BITS(header_lsp->remaining_lifetime)); 1252127675Sbms break; 1253127675Sbms case L1_CSNP: 1254127675Sbms case L2_CSNP: 1255127675Sbms printf(", src-id %s", isis_print_id(header_csnp->source_id,SYSTEM_ID_LEN)); 1256127675Sbms break; 1257127675Sbms case L1_PSNP: 1258127675Sbms case L2_PSNP: 1259127675Sbms printf(", src-id %s", isis_print_id(header_psnp->source_id,SYSTEM_ID_LEN)); 1260127675Sbms break; 1261127675Sbms 1262127675Sbms } 1263127675Sbms printf(", length %u", length); 1264127675Sbms 1265127675Sbms return(1); 1266127675Sbms } 1267127675Sbms 1268127675Sbms /* ok they seem to want to know everything - lets fully decode it */ 1269127675Sbms printf(", IS-IS, length: %u",length); 1270127675Sbms 1271127675Sbms printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", 1272127675Sbms tok2str(isis_pdu_values, 1273127675Sbms "unknown, type %u", 1274127675Sbms pdu_type), 127598527Sfenner header->fixed_len, 1276127675Sbms header->version, 1277127675Sbms header->pdu_version, 1278127675Sbms id_length, 1279127675Sbms header->id_length, 128098527Sfenner max_area, 128198527Sfenner header->max_area); 1282127675Sbms 1283127675Sbms if (vflag > 1) { 1284127675Sbms if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */ 1285127675Sbms return(0); /* for optionally debugging the common header */ 1286127675Sbms } 1287127675Sbms 128898527Sfenner switch (pdu_type) { 128998527Sfenner 1290127675Sbms case L1_LAN_IIH: 129198527Sfenner case L2_LAN_IIH: 129298527Sfenner if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { 129398527Sfenner printf(", bogus fixed header length %u should be %lu", 129498527Sfenner header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); 129598527Sfenner return (0); 129617688Spst } 129798527Sfenner 129898527Sfenner pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); 129998527Sfenner if (packet_len>pdu_len) { 1300127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1301127675Sbms length=pdu_len; 130298527Sfenner } 130398527Sfenner 130498527Sfenner TCHECK(*header_iih_lan); 1305127675Sbms printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", 1306127675Sbms isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), 1307127675Sbms EXTRACT_16BITS(header_iih_lan->holding_time), 1308127675Sbms tok2str(isis_iih_circuit_type_values, 1309127675Sbms "unknown circuit type 0x%02x", 1310127675Sbms header_iih_lan->circuit_type)); 131198527Sfenner 1312127675Sbms printf("\n\t lan-id: %s, Priority: %u, PDU length: %u", 1313127675Sbms isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), 1314127675Sbms (header_iih_lan->priority) & PRIORITY_MASK, 1315127675Sbms pdu_len); 131698527Sfenner 1317127675Sbms if (vflag > 1) { 1318127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE)) 1319127675Sbms return(0); 1320127675Sbms } 132198527Sfenner 132298527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 132398527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); 132417688Spst break; 132598527Sfenner 132698527Sfenner case PTP_IIH: 132798527Sfenner if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { 132898527Sfenner printf(", bogus fixed header length %u should be %lu", 132998527Sfenner header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); 133098527Sfenner return (0); 133117688Spst } 1332127675Sbms 133398527Sfenner pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); 133498527Sfenner if (packet_len>pdu_len) { 1335127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1336127675Sbms length=pdu_len; 133798527Sfenner } 1338127675Sbms 133998527Sfenner TCHECK(*header_iih_ptp); 1340127675Sbms printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", 1341127675Sbms isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), 1342127675Sbms EXTRACT_16BITS(header_iih_ptp->holding_time), 1343127675Sbms tok2str(isis_iih_circuit_type_values, 1344127675Sbms "unknown circuit type 0x%02x", 1345127675Sbms header_iih_ptp->circuit_type)); 134698527Sfenner 1347127675Sbms printf("\n\t circuit-id: 0x%02x, PDU length: %u", 1348127675Sbms header_iih_ptp->circuit_id, 1349127675Sbms pdu_len); 135098527Sfenner 1351127675Sbms if (vflag > 1) { 1352127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE)) 1353127675Sbms return(0); 1354127675Sbms } 135598527Sfenner 135698527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 135798527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); 135817688Spst break; 135998527Sfenner 136098527Sfenner case L1_LSP: 136198527Sfenner case L2_LSP: 136298527Sfenner if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { 136398527Sfenner printf(", bogus fixed header length %u should be %lu", 136498527Sfenner header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); 136598527Sfenner return (0); 136698527Sfenner } 1367127675Sbms 136898527Sfenner pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); 136998527Sfenner if (packet_len>pdu_len) { 1370127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1371127675Sbms length=pdu_len; 137298527Sfenner } 137398527Sfenner 137498527Sfenner TCHECK(*header_lsp); 1375127675Sbms printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", 1376127675Sbms isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), 1377127675Sbms EXTRACT_32BITS(header_lsp->sequence_number), 1378127675Sbms EXTRACT_16BITS(header_lsp->remaining_lifetime), 1379127675Sbms EXTRACT_16BITS(header_lsp->checksum)); 138098527Sfenner 1381127675Sbms /* if this is a purge do not attempt to verify the checksum */ 1382127675Sbms if ( EXTRACT_16BITS(header_lsp->remaining_lifetime) == 0 && 1383127675Sbms EXTRACT_16BITS(header_lsp->checksum) == 0) 1384127675Sbms printf(" (purged)"); 1385127675Sbms else 1386127675Sbms /* verify the checksum - 1387127675Sbms * checking starts at the lsp-id field at byte position [12] 1388127675Sbms * hence the length needs to be reduced by 12 bytes */ 1389127675Sbms printf(" (%s)", (osi_cksum((u_int8_t *)header_lsp->lsp_id, length-12)) ? "incorrect" : "correct"); 1390127675Sbms 1391127675Sbms printf(", PDU length: %u, Flags: [ %s", 1392127675Sbms pdu_len, 1393127675Sbms ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); 1394127675Sbms 139598527Sfenner if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { 139698527Sfenner printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); 139798527Sfenner printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); 139898527Sfenner printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); 139998527Sfenner printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); 140098527Sfenner printf("ATT bit set, "); 140198527Sfenner } 140298527Sfenner printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); 1403127675Sbms printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); 140498527Sfenner 1405127675Sbms if (vflag > 1) { 1406127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE)) 1407127675Sbms return(0); 1408127675Sbms } 1409127675Sbms 141098527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 141198527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); 141217688Spst break; 141398527Sfenner 141498527Sfenner case L1_CSNP: 141598527Sfenner case L2_CSNP: 141698527Sfenner if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { 141798527Sfenner printf(", bogus fixed header length %u should be %lu", 141898527Sfenner header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); 141998527Sfenner return (0); 142098527Sfenner } 1421127675Sbms 142298527Sfenner pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); 142398527Sfenner if (packet_len>pdu_len) { 1424127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1425127675Sbms length=pdu_len; 142698527Sfenner } 142717688Spst 142898527Sfenner TCHECK(*header_csnp); 1429127675Sbms printf("\n\t source-id: %s, PDU length: %u", 1430127675Sbms isis_print_id(header_csnp->source_id, NODE_ID_LEN), 1431127675Sbms pdu_len); 1432127675Sbms printf("\n\t start lsp-id: %s", 1433127675Sbms isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)); 1434127675Sbms printf("\n\t end lsp-id: %s", 1435127675Sbms isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)); 143617688Spst 1437127675Sbms if (vflag > 1) { 1438127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE)) 1439127675Sbms return(0); 1440127675Sbms } 1441127675Sbms 144298527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 144398527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); 144498527Sfenner break; 144517688Spst 144698527Sfenner case L1_PSNP: 144798527Sfenner case L2_PSNP: 144898527Sfenner if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { 144998527Sfenner printf("- bogus fixed header length %u should be %lu", 145098527Sfenner header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); 145198527Sfenner return (0); 145298527Sfenner } 145398527Sfenner 145498527Sfenner pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); 145598527Sfenner if (packet_len>pdu_len) { 1456127675Sbms packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ 1457127675Sbms length=pdu_len; 145898527Sfenner } 145998527Sfenner 146098527Sfenner TCHECK(*header_psnp); 1461127675Sbms printf("\n\t source-id: %s, PDU length: %u", 1462127675Sbms isis_print_id(header_psnp->source_id, NODE_ID_LEN), 1463127675Sbms pdu_len); 1464127675Sbms 1465127675Sbms if (vflag > 1) { 1466127675Sbms if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE)) 1467127675Sbms return(0); 1468127675Sbms } 1469127675Sbms 147098527Sfenner packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 147198527Sfenner pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); 147217688Spst break; 147317688Spst 147498527Sfenner default: 1475127675Sbms if(!print_unknown_data(pptr,"\n\t ",length)) 1476127675Sbms return(0); 1477127675Sbms return (0); 147817688Spst } 147917688Spst 148017688Spst /* 148117688Spst * Now print the TLV's. 148217688Spst */ 1483127675Sbms 148417688Spst while (packet_len >= 2) { 148598527Sfenner if (pptr == snapend) { 148698527Sfenner return (1); 148798527Sfenner } 148898527Sfenner 148998527Sfenner if (!TTEST2(*pptr, 2)) { 1490127675Sbms printf("\n\t\t packet exceeded snapshot (%ld) bytes", 1491127675Sbms (long)(pptr-snapend)); 149298527Sfenner return (1); 149317688Spst } 1494127675Sbms tlv_type = *pptr++; 1495127675Sbms tlv_len = *pptr++; 1496127675Sbms tmp =tlv_len; /* copy temporary len & pointer to packet data */ 1497127675Sbms tptr = pptr; 149817688Spst packet_len -= 2; 1499127675Sbms if (tlv_len > packet_len) { 150017688Spst break; 150117688Spst } 150217688Spst 1503127675Sbms /* first lets see if we know the TLVs name*/ 1504127675Sbms printf("\n\t %s TLV #%u, length: %u", 1505127675Sbms tok2str(isis_tlv_values, 1506127675Sbms "unknown", 1507127675Sbms tlv_type), 1508127675Sbms tlv_type, 1509127675Sbms tlv_len); 1510127675Sbms 1511127675Sbms /* now check if we have a decoder otherwise do a hexdump at the end*/ 1512127675Sbms switch (tlv_type) { 151317688Spst case TLV_AREA_ADDR: 151498527Sfenner if (!TTEST2(*tptr, 1)) 151598527Sfenner goto trunctlv; 151617688Spst alen = *tptr++; 151717688Spst while (tmp && alen < tmp) { 1518127675Sbms printf("\n\t Area address (length: %u): %s", 1519127675Sbms alen, 1520127675Sbms print_nsap(tptr, alen)); 152117688Spst tptr += alen; 152217688Spst tmp -= alen + 1; 152398527Sfenner if (tmp==0) /* if this is the last area address do not attemt a boundary check */ 1524127675Sbms break; 152598527Sfenner if (!TTEST2(*tptr, 1)) 152698527Sfenner goto trunctlv; 152717688Spst alen = *tptr++; 152817688Spst } 152917688Spst break; 153017688Spst case TLV_ISNEIGH: 153175118Sfenner while (tmp >= ETHER_ADDR_LEN) { 1532127675Sbms if (!TTEST2(*tptr, ETHER_ADDR_LEN)) 1533127675Sbms goto trunctlv; 1534127675Sbms printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN)); 1535127675Sbms tmp -= ETHER_ADDR_LEN; 1536127675Sbms tptr += ETHER_ADDR_LEN; 153717688Spst } 153817688Spst break; 153998527Sfenner 1540127675Sbms case TLV_ISNEIGH_VARLEN: 1541127675Sbms if (!TTEST2(*tptr, 1)) 1542127675Sbms goto trunctlv; 1543127675Sbms lan_alen = *tptr++; /* LAN adress length */ 1544127675Sbms tmp --; 1545127675Sbms printf("\n\t LAN address length %u bytes ",lan_alen); 1546127675Sbms while (tmp >= lan_alen) { 1547127675Sbms if (!TTEST2(*tptr, lan_alen)) 1548127675Sbms goto trunctlv; 1549127675Sbms printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen)); 1550127675Sbms tmp -= lan_alen; 1551127675Sbms tptr +=lan_alen; 1552127675Sbms } 1553127675Sbms break; 1554127675Sbms 155517688Spst case TLV_PADDING: 155617688Spst break; 155798527Sfenner 155898527Sfenner case TLV_MT_IS_REACH: 1559127675Sbms while (tmp >= 2+NODE_ID_LEN+3+1) { 1560127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 1561127675Sbms if (mt_len == 0) /* did something go wrong ? */ 1562127675Sbms goto trunctlv; 1563127675Sbms tptr+=mt_len; 1564127675Sbms tmp-=mt_len; 156598527Sfenner 1566127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 1567127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 156898527Sfenner goto trunctlv; 1569127675Sbms 1570127675Sbms tmp-=ext_is_len; 1571127675Sbms tptr+=ext_is_len; 157298527Sfenner } 157398527Sfenner break; 157498527Sfenner 1575127675Sbms case TLV_IS_ALIAS_ID: 1576127675Sbms while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ 1577127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 1578127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 1579127675Sbms goto trunctlv; 1580127675Sbms tmp-=ext_is_len; 1581127675Sbms tptr+=ext_is_len; 1582127675Sbms } 1583127675Sbms break; 1584127675Sbms 158598527Sfenner case TLV_EXT_IS_REACH: 1586127675Sbms while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ 1587127675Sbms ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); 1588127675Sbms if (ext_is_len == 0) /* did something go wrong ? */ 1589127675Sbms goto trunctlv; 1590127675Sbms tmp-=ext_is_len; 1591127675Sbms tptr+=ext_is_len; 159298527Sfenner } 159398527Sfenner break; 159498527Sfenner case TLV_IS_REACH: 159598527Sfenner if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ 1596127675Sbms goto trunctlv; 1597127675Sbms printf("\n\t %s", 1598127675Sbms tok2str(isis_is_reach_virtual_values, 1599127675Sbms "bogus virtual flag 0x%02x", 1600127675Sbms *tptr++)); 160198527Sfenner tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; 160298527Sfenner while (tmp >= sizeof(struct isis_tlv_is_reach)) { 160398527Sfenner if (!TTEST(*tlv_is_reach)) 160498527Sfenner goto trunctlv; 1605127675Sbms printf("\n\t IS Neighbor: %s", 1606127675Sbms isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); 1607127675Sbms isis_print_metric_block(&tlv_is_reach->isis_metric_block); 160898527Sfenner tmp -= sizeof(struct isis_tlv_is_reach); 160998527Sfenner tlv_is_reach++; 161098527Sfenner } 161198527Sfenner break; 161298527Sfenner 1613127675Sbms case TLV_ESNEIGH: 1614127675Sbms tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; 1615127675Sbms while (tmp >= sizeof(struct isis_tlv_es_reach)) { 1616127675Sbms if (!TTEST(*tlv_es_reach)) 1617127675Sbms goto trunctlv; 1618127675Sbms printf("\n\t ES Neighbor: %s", 1619127675Sbms isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN)); 1620127675Sbms isis_print_metric_block(&tlv_es_reach->isis_metric_block); 1621127675Sbms tmp -= sizeof(struct isis_tlv_es_reach); 1622127675Sbms tlv_es_reach++; 1623127675Sbms } 1624127675Sbms break; 1625127675Sbms 1626127675Sbms /* those two TLVs share the same format */ 1627127675Sbms case TLV_INT_IP_REACH: 1628127675Sbms case TLV_EXT_IP_REACH: 1629127675Sbms if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len)) 163098527Sfenner return (1); 163117688Spst break; 163298527Sfenner 1633127675Sbms case TLV_EXTD_IP_REACH: 1634127675Sbms while (tmp>0) { 1635127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); 1636127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 1637127675Sbms goto trunctlv; 1638127675Sbms tptr+=ext_ip_len; 1639127675Sbms tmp-=ext_ip_len; 1640127675Sbms } 164198527Sfenner break; 164298527Sfenner 1643127675Sbms case TLV_MT_IP_REACH: 1644127675Sbms while (tmp>0) { 1645127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 1646127675Sbms if (mt_len == 0) /* did something go wrong ? */ 1647127675Sbms goto trunctlv; 1648127675Sbms tptr+=mt_len; 1649127675Sbms tmp-=mt_len; 165098527Sfenner 1651127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); 1652127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 1653127675Sbms goto trunctlv; 1654127675Sbms tptr+=ext_ip_len; 1655127675Sbms tmp-=ext_ip_len; 165698527Sfenner } 165798527Sfenner break; 165898527Sfenner 165998527Sfenner#ifdef INET6 166098527Sfenner case TLV_IP6_REACH: 1661127675Sbms while (tmp>0) { 1662127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); 1663127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 1664127675Sbms goto trunctlv; 1665127675Sbms tptr+=ext_ip_len; 1666127675Sbms tmp-=ext_ip_len; 1667127675Sbms } 1668127675Sbms break; 166998527Sfenner 1670127675Sbms case TLV_MT_IP6_REACH: 1671127675Sbms while (tmp>0) { 1672127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 1673127675Sbms if (mt_len == 0) /* did something go wrong ? */ 1674127675Sbms goto trunctlv; 1675127675Sbms tptr+=mt_len; 1676127675Sbms tmp-=mt_len; 167798527Sfenner 1678127675Sbms ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); 1679127675Sbms if (ext_ip_len == 0) /* did something go wrong ? */ 1680127675Sbms goto trunctlv; 1681127675Sbms tptr+=ext_ip_len; 1682127675Sbms tmp-=ext_ip_len; 168398527Sfenner } 168498527Sfenner break; 168598527Sfenner 168698527Sfenner case TLV_IP6ADDR: 1687127675Sbms while (tmp>0) { 168898527Sfenner if (!TTEST2(*tptr, 16)) 168998527Sfenner goto trunctlv; 169098527Sfenner 1691127675Sbms printf("\n\t IPv6 interface address: %s", 169298527Sfenner ip6addr_string(tptr)); 169398527Sfenner 169498527Sfenner tptr += 16; 1695127675Sbms tmp -= 16; 169698527Sfenner } 169798527Sfenner break; 169898527Sfenner#endif 169998527Sfenner case TLV_AUTH: 1700127675Sbms if (!TTEST2(*tptr, 1)) 170198527Sfenner goto trunctlv; 1702127675Sbms 1703127675Sbms printf("\n\t %s: ", 1704127675Sbms tok2str(isis_subtlv_auth_values, 1705127675Sbms "unknown Authentication type 0x%02x", 1706127675Sbms *tptr)); 1707127675Sbms 1708127675Sbms switch (*tptr) { 1709127675Sbms case SUBTLV_AUTH_SIMPLE: 1710127675Sbms for(i=1;i<tlv_len;i++) { 1711127675Sbms if (!TTEST2(*(tptr+i), 1)) 171298527Sfenner goto trunctlv; 1713127675Sbms printf("%c",*(tptr+i)); 171498527Sfenner } 1715127675Sbms break; 1716127675Sbms case SUBTLV_AUTH_MD5: 1717127675Sbms for(i=1;i<tlv_len;i++) { 1718127675Sbms if (!TTEST2(*(tptr+i), 1)) 171998527Sfenner goto trunctlv; 1720127675Sbms printf("%02x",*(tptr+i)); 172198527Sfenner } 1722127675Sbms if (tlv_len != SUBTLV_AUTH_MD5_LEN+1) 1723127675Sbms printf(", (malformed subTLV) "); 1724127675Sbms break; 1725127675Sbms case SUBTLV_AUTH_PRIVATE: 1726127675Sbms default: 1727127675Sbms if(!print_unknown_data(tptr+1,"\n\t\t ",tlv_len-1)) 1728127675Sbms return(0); 1729127675Sbms break; 173098527Sfenner } 173198527Sfenner break; 173298527Sfenner 173332149Spst case TLV_PTP_ADJ: 1734127675Sbms tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr; 1735127675Sbms if(tmp>=1) { 1736127675Sbms if (!TTEST2(*tptr, 1)) 173798527Sfenner goto trunctlv; 1738127675Sbms printf("\n\t Adjacency State: %s (%u)", 1739127675Sbms tok2str(isis_ptp_adjancey_values, "unknown", *tptr), 1740127675Sbms *tptr); 1741127675Sbms tmp--; 174298527Sfenner } 1743127675Sbms if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { 1744127675Sbms if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id, 1745127675Sbms sizeof(tlv_ptp_adj->extd_local_circuit_id))) 174698527Sfenner goto trunctlv; 1747127675Sbms printf("\n\t Extended Local circuit-ID: 0x%08x", 1748127675Sbms EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)); 1749127675Sbms tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); 175098527Sfenner } 1751127675Sbms if(tmp>=SYSTEM_ID_LEN) { 1752127675Sbms if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) 175398527Sfenner goto trunctlv; 1754127675Sbms printf("\n\t Neighbor System-ID: %s", 1755127675Sbms isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN)); 1756127675Sbms tmp-=SYSTEM_ID_LEN; 175798527Sfenner } 1758127675Sbms if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { 1759127675Sbms if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, 1760127675Sbms sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) 176198527Sfenner goto trunctlv; 1762127675Sbms printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x", 1763127675Sbms EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)); 176498527Sfenner } 176532149Spst break; 176698527Sfenner 176732149Spst case TLV_PROTOCOLS: 1768127675Sbms printf("\n\t NLPID(s): "); 1769127675Sbms while (tmp>0) { 1770127675Sbms if (!TTEST2(*(tptr), 1)) 177198527Sfenner goto trunctlv; 1772127675Sbms printf("%s (0x%02x)", 1773127675Sbms tok2str(osi_nlpid_values, 1774127675Sbms "unknown", 1775127675Sbms *tptr), 1776127675Sbms *tptr); 1777127675Sbms if (tmp>1) /* further NPLIDs ? - put comma */ 177898527Sfenner printf(", "); 1779127675Sbms tptr++; 1780127675Sbms tmp--; 178198527Sfenner } 178232149Spst break; 178398527Sfenner 178498527Sfenner case TLV_TE_ROUTER_ID: 178598527Sfenner if (!TTEST2(*pptr, 4)) 178698527Sfenner goto trunctlv; 1787127675Sbms printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr)); 178898527Sfenner break; 178998527Sfenner 179032149Spst case TLV_IPADDR: 1791127675Sbms while (tmp>0) { 179298527Sfenner if (!TTEST2(*tptr, 4)) 179398527Sfenner goto trunctlv; 1794127675Sbms printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); 179598527Sfenner tptr += 4; 1796127675Sbms tmp -= 4; 179798527Sfenner } 179832149Spst break; 179998527Sfenner 180098527Sfenner case TLV_HOSTNAME: 1801127675Sbms printf("\n\t Hostname: "); 1802127675Sbms while (tmp>0) { 1803127675Sbms if (!TTEST2(*tptr, 1)) 180498527Sfenner goto trunctlv; 1805127675Sbms printf("%c",*tptr++); 1806127675Sbms tmp--; 180798527Sfenner } 180898527Sfenner break; 180998527Sfenner 1810127675Sbms case TLV_SHARED_RISK_GROUP: 1811127675Sbms if (!TTEST2(*tptr, NODE_ID_LEN)) 1812127675Sbms goto trunctlv; 1813127675Sbms printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)); 1814127675Sbms tptr+=(NODE_ID_LEN); 1815127675Sbms tmp-=(NODE_ID_LEN); 1816127675Sbms 1817127675Sbms if (!TTEST2(*tptr, 1)) 1818127675Sbms goto trunctlv; 1819127675Sbms printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"); 1820127675Sbms tmp--; 1821127675Sbms 1822127675Sbms if (!TTEST2(*tptr,4)) 1823127675Sbms goto trunctlv; 1824127675Sbms printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); 1825127675Sbms tptr+=4; 1826127675Sbms tmp-=4; 1827127675Sbms 1828127675Sbms if (!TTEST2(*tptr,4)) 1829127675Sbms goto trunctlv; 1830127675Sbms printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr)); 1831127675Sbms tptr+=4; 1832127675Sbms tmp-=4; 1833127675Sbms 1834127675Sbms while (tmp>0) { 1835127675Sbms if (!TTEST2(*tptr, 4)) 1836127675Sbms goto trunctlv; 1837127675Sbms printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)); 1838127675Sbms tptr+=4; 1839127675Sbms tmp-=4; 1840127675Sbms } 1841127675Sbms break; 1842127675Sbms 1843127675Sbms case TLV_LSP: 1844127675Sbms tlv_lsp = (const struct isis_tlv_lsp *)tptr; 1845127675Sbms while(tmp>0) { 1846127675Sbms if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) 184798527Sfenner goto trunctlv; 1848127675Sbms printf("\n\t lsp-id: %s", 1849127675Sbms isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)); 185098527Sfenner if (!TTEST2(tlv_lsp->sequence_number, 4)) 185198527Sfenner goto trunctlv; 1852127675Sbms printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); 185398527Sfenner if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) 185498527Sfenner goto trunctlv; 1855127675Sbms printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); 185698527Sfenner if (!TTEST2(tlv_lsp->checksum, 2)) 185798527Sfenner goto trunctlv; 1858127675Sbms printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); 1859127675Sbms tmp-=sizeof(struct isis_tlv_lsp); 186098527Sfenner tlv_lsp++; 186198527Sfenner } 186298527Sfenner break; 186398527Sfenner 186498527Sfenner case TLV_CHECKSUM: 1865127675Sbms if (!TTEST2(*tptr, 2)) 186698527Sfenner goto trunctlv; 1867127675Sbms printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)); 1868127675Sbms /* do not attempt to verify the checksum if it is zero 1869127675Sbms * most likely a HMAC-MD5 TLV is also present and 1870127675Sbms * to avoid conflicts the checksum TLV is zeroed. 1871127675Sbms * see rfc3358 for details 1872127675Sbms */ 1873127675Sbms if (EXTRACT_16BITS(tptr) == 0) 1874127675Sbms printf("(unverified)"); 1875127675Sbms else printf("(%s)", osi_cksum(optr, length) ? "incorrect" : "correct"); 187698527Sfenner break; 187798527Sfenner 187898527Sfenner case TLV_MT_SUPPORTED: 1879127675Sbms while (tmp>1) { 1880127675Sbms /* length can only be a multiple of 2, otherwise there is 188198527Sfenner something broken -> so decode down until length is 1 */ 1882127675Sbms if (tmp!=1) { 1883127675Sbms mt_len = isis_print_mtid(tptr, "\n\t "); 1884127675Sbms if (mt_len == 0) /* did something go wrong ? */ 1885127675Sbms goto trunctlv; 1886127675Sbms tptr+=mt_len; 1887127675Sbms tmp-=mt_len; 188898527Sfenner } else { 1889127675Sbms printf("\n\t malformed MT-ID"); 189098527Sfenner break; 189198527Sfenner } 189298527Sfenner } 189398527Sfenner break; 189498527Sfenner 189598527Sfenner case TLV_RESTART_SIGNALING: 1896127675Sbms if (!TTEST2(*tptr, 3)) 1897127675Sbms goto trunctlv; 1898127675Sbms printf("\n\t Flags [%s], Remaining holding time %us", 1899127675Sbms bittok2str(isis_restart_flag_values, "none", *tptr), 1900127675Sbms EXTRACT_16BITS(tptr+1)); 1901127675Sbms tptr+=3; 190298527Sfenner break; 190398527Sfenner 1904127675Sbms case TLV_IDRP_INFO: 1905127675Sbms if (!TTEST2(*tptr, 1)) 1906127675Sbms goto trunctlv; 1907127675Sbms printf("\n\t Inter-Domain Information Type: %s", 1908127675Sbms tok2str(isis_subtlv_idrp_values, 1909127675Sbms "Unknown (0x%02x)", 1910127675Sbms *tptr)); 1911127675Sbms switch (*tptr++) { 1912127675Sbms case SUBTLV_IDRP_ASN: 1913127675Sbms if (!TTEST2(*tptr, 2)) /* fetch AS number */ 1914127675Sbms goto trunctlv; 1915127675Sbms printf("AS Number: %u",EXTRACT_16BITS(tptr)); 1916127675Sbms break; 1917127675Sbms case SUBTLV_IDRP_LOCAL: 1918127675Sbms case SUBTLV_IDRP_RES: 1919127675Sbms default: 1920127675Sbms if(!print_unknown_data(tptr,"\n\t ",tlv_len-1)) 1921127675Sbms return(0); 1922127675Sbms break; 1923127675Sbms } 1924127675Sbms break; 1925127675Sbms 1926127675Sbms case TLV_LSP_BUFFERSIZE: 1927127675Sbms if (!TTEST2(*tptr, 2)) 1928127675Sbms goto trunctlv; 1929127675Sbms printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr)); 1930127675Sbms break; 1931127675Sbms 1932127675Sbms case TLV_PART_DIS: 1933127675Sbms while (tmp >= SYSTEM_ID_LEN) { 1934127675Sbms if (!TTEST2(*tptr, SYSTEM_ID_LEN)) 1935127675Sbms goto trunctlv; 1936127675Sbms printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN)); 1937127675Sbms tptr+=SYSTEM_ID_LEN; 1938127675Sbms tmp-=SYSTEM_ID_LEN; 1939127675Sbms } 1940127675Sbms break; 1941127675Sbms 1942127675Sbms case TLV_PREFIX_NEIGH: 1943127675Sbms if (!TTEST2(*tptr, sizeof(struct isis_metric_block))) 1944127675Sbms goto trunctlv; 1945127675Sbms printf("\n\t Metric Block"); 1946127675Sbms isis_print_metric_block((const struct isis_metric_block *)tptr); 1947127675Sbms tptr+=sizeof(struct isis_metric_block); 1948127675Sbms tmp-=sizeof(struct isis_metric_block); 1949127675Sbms 1950127675Sbms while(tmp>0) { 1951127675Sbms if (!TTEST2(*tptr, 1)) 1952127675Sbms goto trunctlv; 1953127675Sbms prefix_len=*tptr++; /* read out prefix length in semioctets*/ 1954127675Sbms tmp--; 1955127675Sbms if (!TTEST2(*tptr, prefix_len/2)) 1956127675Sbms goto trunctlv; 1957127675Sbms printf("\n\t\tAddress: %s/%u", 1958127675Sbms print_nsap(tptr,prefix_len/2), 1959127675Sbms prefix_len*4); 1960127675Sbms tptr+=prefix_len/2; 1961127675Sbms tmp-=prefix_len/2; 1962127675Sbms } 1963127675Sbms break; 1964127675Sbms 1965127675Sbms case TLV_IIH_SEQNR: 1966127675Sbms if (!TTEST2(*tptr, 4)) /* check if four bytes are on the wire */ 1967127675Sbms goto trunctlv; 1968127675Sbms printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) ); 1969127675Sbms break; 1970127675Sbms 1971127675Sbms case TLV_VENDOR_PRIVATE: 1972127675Sbms if (!TTEST2(*tptr, 3)) /* check if enough byte for a full oui */ 1973127675Sbms goto trunctlv; 1974127675Sbms printf("\n\t Vendor OUI Code: 0x%06x", EXTRACT_24BITS(tptr) ); 1975127675Sbms tptr+=3; 1976127675Sbms tmp-=3; 1977127675Sbms if (tmp > 0) /* hexdump the rest */ 1978127675Sbms if(!print_unknown_data(tptr,"\n\t\t",tmp)) 1979127675Sbms return(0); 1980127675Sbms break; 1981127675Sbms /* 1982127675Sbms * FIXME those are the defined TLVs that lack a decoder 1983127675Sbms * you are welcome to contribute code ;-) 1984127675Sbms */ 1985127675Sbms 1986127675Sbms case TLV_DECNET_PHASE4: 1987127675Sbms case TLV_LUCENT_PRIVATE: 1988127675Sbms case TLV_IPAUTH: 1989127675Sbms case TLV_NORTEL_PRIVATE1: 1990127675Sbms case TLV_NORTEL_PRIVATE2: 1991127675Sbms 199217688Spst default: 1993127675Sbms if (vflag <= 1) { 1994127675Sbms if(!print_unknown_data(pptr,"\n\t\t",tlv_len)) 1995127675Sbms return(0); 1996127675Sbms } 199717688Spst break; 199817688Spst } 1999127675Sbms /* do we want to see an additionally hexdump ? */ 2000127675Sbms if (vflag> 1) { 2001127675Sbms if(!print_unknown_data(pptr,"\n\t ",tlv_len)) 2002127675Sbms return(0); 2003127675Sbms } 200417688Spst 2005127675Sbms pptr += tlv_len; 2006127675Sbms packet_len -= tlv_len; 200717688Spst } 200817688Spst 200917688Spst if (packet_len != 0) { 2010127675Sbms printf("\n\t %u straggler bytes", packet_len); 201117688Spst } 201298527Sfenner return (1); 201398527Sfenner 2014127675Sbms trunc: 201598527Sfenner fputs("[|isis]", stdout); 201698527Sfenner return (1); 201798527Sfenner 2018127675Sbms trunctlv: 2019127675Sbms printf("\n\t\t packet exceeded snapshot"); 202017688Spst return(1); 202117688Spst} 202217688Spst 202317751Spst/* 202417751Spst * Verify the checksum. See 8473-1, Appendix C, section C.4. 202517751Spst */ 202617751Spst 202717688Spststatic int 2028127675Sbmsosi_cksum(const u_int8_t *tptr, u_int len) 202917680Spst{ 203017680Spst int32_t c0 = 0, c1 = 0; 203117680Spst 203239300Sfenner while ((int)--len >= 0) { 2033127675Sbms c0 += *tptr++; 203417751Spst c0 %= 255; 203517680Spst c1 += c0; 203617680Spst c1 %= 255; 203717680Spst } 203817751Spst return (c0 | c1); 203917680Spst} 2040