141c99275SPeter Avalos /*
241c99275SPeter Avalos * Copyright (c) 1992, 1993, 1994, 1995, 1996
341c99275SPeter Avalos * The Regents of the University of California. All rights reserved.
441c99275SPeter Avalos *
541c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos * modification, are permitted provided that: (1) source code distributions
741c99275SPeter Avalos * retain the above copyright notice and this paragraph in its entirety, (2)
841c99275SPeter Avalos * distributions including binary code include the above copyright notice and
941c99275SPeter Avalos * this paragraph in its entirety in the documentation or other materials
1041c99275SPeter Avalos * provided with the distribution, and (3) all advertising materials mentioning
1141c99275SPeter Avalos * features or use of this software display the following acknowledgement:
1241c99275SPeter Avalos * ``This product includes software developed by the University of California,
1341c99275SPeter Avalos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1441c99275SPeter Avalos * the University nor the names of its contributors may be used to endorse
1541c99275SPeter Avalos * or promote products derived from this software without specific prior
1641c99275SPeter Avalos * written permission.
1741c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1841c99275SPeter Avalos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1941c99275SPeter Avalos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2041c99275SPeter Avalos *
2141c99275SPeter Avalos * Original code by Matt Thomas, Digital Equipment Corporation
2241c99275SPeter Avalos *
23411677aeSAaron LI * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
2441c99275SPeter Avalos * complete IS-IS & CLNP support.
2541c99275SPeter Avalos */
2641c99275SPeter Avalos
27411677aeSAaron LI /* \summary: ISO CLNS, ESIS, and ISIS printer */
2841c99275SPeter Avalos
29*ed775ee7SAntonio Huete Jimenez /*
30*ed775ee7SAntonio Huete Jimenez * specification:
31*ed775ee7SAntonio Huete Jimenez *
32*ed775ee7SAntonio Huete Jimenez * CLNP: ISO 8473 (respective ITU version is at https://www.itu.int/rec/T-REC-X.233/en/)
33*ed775ee7SAntonio Huete Jimenez * ES-IS: ISO 9542
34*ed775ee7SAntonio Huete Jimenez * IS-IS: ISO 10589
35*ed775ee7SAntonio Huete Jimenez */
36*ed775ee7SAntonio Huete Jimenez
3741c99275SPeter Avalos #ifdef HAVE_CONFIG_H
38*ed775ee7SAntonio Huete Jimenez #include <config.h>
3941c99275SPeter Avalos #endif
4041c99275SPeter Avalos
41*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
4241c99275SPeter Avalos
4341c99275SPeter Avalos #include <string.h>
4441c99275SPeter Avalos
45411677aeSAaron LI #include "netdissect.h"
4641c99275SPeter Avalos #include "addrtoname.h"
4741c99275SPeter Avalos #include "nlpid.h"
4841c99275SPeter Avalos #include "extract.h"
4941c99275SPeter Avalos #include "gmpls.h"
5041c99275SPeter Avalos #include "oui.h"
5127bfbee1SPeter Avalos #include "signature.h"
5241c99275SPeter Avalos
53411677aeSAaron LI
5441c99275SPeter Avalos /*
5541c99275SPeter Avalos * IS-IS is defined in ISO 10589. Look there for protocol definitions.
5641c99275SPeter Avalos */
5741c99275SPeter Avalos
58*ed775ee7SAntonio Huete Jimenez #define SYSTEM_ID_LEN MAC_ADDR_LEN
59*ed775ee7SAntonio Huete Jimenez #define NODE_ID_LEN (SYSTEM_ID_LEN+1)
60*ed775ee7SAntonio Huete Jimenez #define LSP_ID_LEN (SYSTEM_ID_LEN+2)
6141c99275SPeter Avalos
6241c99275SPeter Avalos #define ISIS_VERSION 1
6341c99275SPeter Avalos #define ESIS_VERSION 1
6441c99275SPeter Avalos #define CLNP_VERSION 1
6541c99275SPeter Avalos
6641c99275SPeter Avalos #define ISIS_PDU_TYPE_MASK 0x1F
6741c99275SPeter Avalos #define ESIS_PDU_TYPE_MASK 0x1F
6841c99275SPeter Avalos #define CLNP_PDU_TYPE_MASK 0x1F
6941c99275SPeter Avalos #define CLNP_FLAG_MASK 0xE0
7041c99275SPeter Avalos #define ISIS_LAN_PRIORITY_MASK 0x7F
7141c99275SPeter Avalos
7241c99275SPeter Avalos #define ISIS_PDU_L1_LAN_IIH 15
7341c99275SPeter Avalos #define ISIS_PDU_L2_LAN_IIH 16
7441c99275SPeter Avalos #define ISIS_PDU_PTP_IIH 17
7541c99275SPeter Avalos #define ISIS_PDU_L1_LSP 18
7641c99275SPeter Avalos #define ISIS_PDU_L2_LSP 20
7741c99275SPeter Avalos #define ISIS_PDU_L1_CSNP 24
7841c99275SPeter Avalos #define ISIS_PDU_L2_CSNP 25
7941c99275SPeter Avalos #define ISIS_PDU_L1_PSNP 26
8041c99275SPeter Avalos #define ISIS_PDU_L2_PSNP 27
8141c99275SPeter Avalos
82411677aeSAaron LI static const struct tok isis_pdu_values[] = {
8341c99275SPeter Avalos { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"},
8441c99275SPeter Avalos { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"},
8541c99275SPeter Avalos { ISIS_PDU_PTP_IIH, "p2p IIH"},
8641c99275SPeter Avalos { ISIS_PDU_L1_LSP, "L1 LSP"},
8741c99275SPeter Avalos { ISIS_PDU_L2_LSP, "L2 LSP"},
8841c99275SPeter Avalos { ISIS_PDU_L1_CSNP, "L1 CSNP"},
8941c99275SPeter Avalos { ISIS_PDU_L2_CSNP, "L2 CSNP"},
9041c99275SPeter Avalos { ISIS_PDU_L1_PSNP, "L1 PSNP"},
9141c99275SPeter Avalos { ISIS_PDU_L2_PSNP, "L2 PSNP"},
9241c99275SPeter Avalos { 0, NULL}
9341c99275SPeter Avalos };
9441c99275SPeter Avalos
9541c99275SPeter Avalos /*
9641c99275SPeter Avalos * A TLV is a tuple of a type, length and a value and is normally used for
9741c99275SPeter Avalos * encoding information in all sorts of places. This is an enumeration of
9841c99275SPeter Avalos * the well known types.
9941c99275SPeter Avalos *
10041c99275SPeter Avalos * list taken from rfc3359 plus some memory from veterans ;-)
10141c99275SPeter Avalos */
10241c99275SPeter Avalos
10341c99275SPeter Avalos #define ISIS_TLV_AREA_ADDR 1 /* iso10589 */
10441c99275SPeter Avalos #define ISIS_TLV_IS_REACH 2 /* iso10589 */
10541c99275SPeter Avalos #define ISIS_TLV_ESNEIGH 3 /* iso10589 */
10641c99275SPeter Avalos #define ISIS_TLV_PART_DIS 4 /* iso10589 */
10741c99275SPeter Avalos #define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */
10841c99275SPeter Avalos #define ISIS_TLV_ISNEIGH 6 /* iso10589 */
109*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_INSTANCE_ID 7 /* rfc8202 */
11041c99275SPeter Avalos #define ISIS_TLV_PADDING 8 /* iso10589 */
11141c99275SPeter Avalos #define ISIS_TLV_LSP 9 /* iso10589 */
11241c99275SPeter Avalos #define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */
11341c99275SPeter Avalos #define ISIS_TLV_CHECKSUM 12 /* rfc3358 */
11441c99275SPeter Avalos #define ISIS_TLV_CHECKSUM_MINLEN 2
115411677aeSAaron LI #define ISIS_TLV_POI 13 /* rfc6232 */
11641c99275SPeter Avalos #define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */
117*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_EXT_IS_REACH 22 /* rfc5305 */
118*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_IS_ALIAS_ID 24 /* rfc5311 */
11941c99275SPeter Avalos #define ISIS_TLV_DECNET_PHASE4 42
12041c99275SPeter Avalos #define ISIS_TLV_LUCENT_PRIVATE 66
12141c99275SPeter Avalos #define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */
12241c99275SPeter Avalos #define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */
12341c99275SPeter Avalos #define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */
12441c99275SPeter Avalos #define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */
12541c99275SPeter Avalos #define ISIS_TLV_IPADDR 132 /* rfc1195 */
12641c99275SPeter Avalos #define ISIS_TLV_IPAUTH 133 /* rfc1195 */
127*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_TE_ROUTER_ID 134 /* rfc5305 */
128*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_EXTD_IP_REACH 135 /* rfc5305 */
12941c99275SPeter Avalos #define ISIS_TLV_HOSTNAME 137 /* rfc2763 */
13041c99275SPeter Avalos #define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */
131411677aeSAaron LI #define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */
132411677aeSAaron LI #define ISIS_TLV_MT_CAPABILITY 144 /* rfc6329 */
13341c99275SPeter Avalos #define ISIS_TLV_NORTEL_PRIVATE1 176
13441c99275SPeter Avalos #define ISIS_TLV_NORTEL_PRIVATE2 177
13541c99275SPeter Avalos #define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */
13641c99275SPeter Avalos #define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1
13741c99275SPeter Avalos #define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2
13841c99275SPeter Avalos #define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
13941c99275SPeter Avalos #define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
14041c99275SPeter Avalos #define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */
14141c99275SPeter Avalos #define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */
14241c99275SPeter Avalos #define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */
14341c99275SPeter Avalos #define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
14441c99275SPeter Avalos #define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */
14541c99275SPeter Avalos #define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
146*ed775ee7SAntonio Huete Jimenez #define ISIS_TLV_ROUTER_CAPABILITY 242 /* rfc7981 */
14741c99275SPeter Avalos #define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */
14841c99275SPeter Avalos #define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3
14941c99275SPeter Avalos
150411677aeSAaron LI static const struct tok isis_tlv_values[] = {
15141c99275SPeter Avalos { ISIS_TLV_AREA_ADDR, "Area address(es)"},
15241c99275SPeter Avalos { ISIS_TLV_IS_REACH, "IS Reachability"},
15341c99275SPeter Avalos { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"},
15441c99275SPeter Avalos { ISIS_TLV_PART_DIS, "Partition DIS"},
15541c99275SPeter Avalos { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"},
15641c99275SPeter Avalos { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"},
157*ed775ee7SAntonio Huete Jimenez { ISIS_TLV_INSTANCE_ID, "Instance Identifier"},
15841c99275SPeter Avalos { ISIS_TLV_PADDING, "Padding"},
15941c99275SPeter Avalos { ISIS_TLV_LSP, "LSP entries"},
16041c99275SPeter Avalos { ISIS_TLV_AUTH, "Authentication"},
16141c99275SPeter Avalos { ISIS_TLV_CHECKSUM, "Checksum"},
162411677aeSAaron LI { ISIS_TLV_POI, "Purge Originator Identifier"},
16341c99275SPeter Avalos { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"},
16441c99275SPeter Avalos { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"},
16541c99275SPeter Avalos { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"},
16641c99275SPeter Avalos { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"},
16741c99275SPeter Avalos { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"},
16841c99275SPeter Avalos { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"},
16941c99275SPeter Avalos { ISIS_TLV_PROTOCOLS, "Protocols supported"},
17041c99275SPeter Avalos { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"},
17141c99275SPeter Avalos { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"},
17241c99275SPeter Avalos { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"},
17341c99275SPeter Avalos { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"},
17441c99275SPeter Avalos { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"},
17541c99275SPeter Avalos { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"},
17641c99275SPeter Avalos { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"},
177411677aeSAaron LI { ISIS_TLV_MT_PORT_CAP, "Multi-Topology-Aware Port Capability"},
178411677aeSAaron LI { ISIS_TLV_MT_CAPABILITY, "Multi-Topology Capability"},
17941c99275SPeter Avalos { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"},
18041c99275SPeter Avalos { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"},
18141c99275SPeter Avalos { ISIS_TLV_HOSTNAME, "Hostname"},
18241c99275SPeter Avalos { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"},
18341c99275SPeter Avalos { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"},
18441c99275SPeter Avalos { ISIS_TLV_MT_SUPPORTED, "Multi Topology"},
18541c99275SPeter Avalos { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"},
18641c99275SPeter Avalos { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"},
18741c99275SPeter Avalos { ISIS_TLV_IP6_REACH, "IPv6 reachability"},
18841c99275SPeter Avalos { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"},
18941c99275SPeter Avalos { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"},
19041c99275SPeter Avalos { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"},
191*ed775ee7SAntonio Huete Jimenez { ISIS_TLV_ROUTER_CAPABILITY, "IS-IS Router Capability"},
19241c99275SPeter Avalos { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"},
19341c99275SPeter Avalos { 0, NULL }
19441c99275SPeter Avalos };
19541c99275SPeter Avalos
19641c99275SPeter Avalos #define ESIS_OPTION_PROTOCOLS 129
19741c99275SPeter Avalos #define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */
19841c99275SPeter Avalos #define ESIS_OPTION_SECURITY 197 /* iso9542 */
19941c99275SPeter Avalos #define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */
20041c99275SPeter Avalos #define ESIS_OPTION_PRIORITY 205 /* iso9542 */
20141c99275SPeter Avalos #define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */
20241c99275SPeter Avalos #define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */
20341c99275SPeter Avalos
204411677aeSAaron LI static const struct tok esis_option_values[] = {
20541c99275SPeter Avalos { ESIS_OPTION_PROTOCOLS, "Protocols supported"},
20641c99275SPeter Avalos { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" },
20741c99275SPeter Avalos { ESIS_OPTION_SECURITY, "Security" },
20841c99275SPeter Avalos { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" },
20941c99275SPeter Avalos { ESIS_OPTION_PRIORITY, "Priority" },
21041c99275SPeter Avalos { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" },
21141c99275SPeter Avalos { ESIS_OPTION_SNPA_MASK, "SNPA Mask" },
21241c99275SPeter Avalos { 0, NULL }
21341c99275SPeter Avalos };
21441c99275SPeter Avalos
21541c99275SPeter Avalos #define CLNP_OPTION_DISCARD_REASON 193
21641c99275SPeter Avalos #define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */
21741c99275SPeter Avalos #define CLNP_OPTION_SECURITY 197 /* iso8473 */
21841c99275SPeter Avalos #define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */
21941c99275SPeter Avalos #define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */
22041c99275SPeter Avalos #define CLNP_OPTION_PADDING 204 /* iso8473 */
22141c99275SPeter Avalos #define CLNP_OPTION_PRIORITY 205 /* iso8473 */
22241c99275SPeter Avalos
223411677aeSAaron LI static const struct tok clnp_option_values[] = {
22441c99275SPeter Avalos { CLNP_OPTION_DISCARD_REASON, "Discard Reason"},
22541c99275SPeter Avalos { CLNP_OPTION_PRIORITY, "Priority"},
22641c99275SPeter Avalos { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"},
22741c99275SPeter Avalos { CLNP_OPTION_SECURITY, "Security"},
22841c99275SPeter Avalos { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"},
22941c99275SPeter Avalos { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"},
23041c99275SPeter Avalos { CLNP_OPTION_PADDING, "Padding"},
23141c99275SPeter Avalos { 0, NULL }
23241c99275SPeter Avalos };
23341c99275SPeter Avalos
234411677aeSAaron LI static const struct tok clnp_option_rfd_class_values[] = {
23541c99275SPeter Avalos { 0x0, "General"},
23641c99275SPeter Avalos { 0x8, "Address"},
23741c99275SPeter Avalos { 0x9, "Source Routeing"},
23841c99275SPeter Avalos { 0xa, "Lifetime"},
23941c99275SPeter Avalos { 0xb, "PDU Discarded"},
24041c99275SPeter Avalos { 0xc, "Reassembly"},
24141c99275SPeter Avalos { 0, NULL }
24241c99275SPeter Avalos };
24341c99275SPeter Avalos
244411677aeSAaron LI static const struct tok clnp_option_rfd_general_values[] = {
24541c99275SPeter Avalos { 0x0, "Reason not specified"},
24641c99275SPeter Avalos { 0x1, "Protocol procedure error"},
24741c99275SPeter Avalos { 0x2, "Incorrect checksum"},
24841c99275SPeter Avalos { 0x3, "PDU discarded due to congestion"},
24941c99275SPeter Avalos { 0x4, "Header syntax error (cannot be parsed)"},
25041c99275SPeter Avalos { 0x5, "Segmentation needed but not permitted"},
25141c99275SPeter Avalos { 0x6, "Incomplete PDU received"},
25241c99275SPeter Avalos { 0x7, "Duplicate option"},
25341c99275SPeter Avalos { 0, NULL }
25441c99275SPeter Avalos };
25541c99275SPeter Avalos
256411677aeSAaron LI static const struct tok clnp_option_rfd_address_values[] = {
25741c99275SPeter Avalos { 0x0, "Destination address unreachable"},
25841c99275SPeter Avalos { 0x1, "Destination address unknown"},
25941c99275SPeter Avalos { 0, NULL }
26041c99275SPeter Avalos };
26141c99275SPeter Avalos
262411677aeSAaron LI static const struct tok clnp_option_rfd_source_routeing_values[] = {
26341c99275SPeter Avalos { 0x0, "Unspecified source routeing error"},
26441c99275SPeter Avalos { 0x1, "Syntax error in source routeing field"},
26541c99275SPeter Avalos { 0x2, "Unknown address in source routeing field"},
26641c99275SPeter Avalos { 0x3, "Path not acceptable"},
26741c99275SPeter Avalos { 0, NULL }
26841c99275SPeter Avalos };
26941c99275SPeter Avalos
270411677aeSAaron LI static const struct tok clnp_option_rfd_lifetime_values[] = {
27141c99275SPeter Avalos { 0x0, "Lifetime expired while data unit in transit"},
27241c99275SPeter Avalos { 0x1, "Lifetime expired during reassembly"},
27341c99275SPeter Avalos { 0, NULL }
27441c99275SPeter Avalos };
27541c99275SPeter Avalos
276411677aeSAaron LI static const struct tok clnp_option_rfd_pdu_discard_values[] = {
27741c99275SPeter Avalos { 0x0, "Unsupported option not specified"},
27841c99275SPeter Avalos { 0x1, "Unsupported protocol version"},
27941c99275SPeter Avalos { 0x2, "Unsupported security option"},
28041c99275SPeter Avalos { 0x3, "Unsupported source routeing option"},
28141c99275SPeter Avalos { 0x4, "Unsupported recording of route option"},
28241c99275SPeter Avalos { 0, NULL }
28341c99275SPeter Avalos };
28441c99275SPeter Avalos
285411677aeSAaron LI static const struct tok clnp_option_rfd_reassembly_values[] = {
28641c99275SPeter Avalos { 0x0, "Reassembly interference"},
28741c99275SPeter Avalos { 0, NULL }
28841c99275SPeter Avalos };
28941c99275SPeter Avalos
29041c99275SPeter Avalos /* array of 16 error-classes */
291411677aeSAaron LI static const struct tok *clnp_option_rfd_error_class[] = {
29241c99275SPeter Avalos clnp_option_rfd_general_values,
29341c99275SPeter Avalos NULL,
29441c99275SPeter Avalos NULL,
29541c99275SPeter Avalos NULL,
29641c99275SPeter Avalos NULL,
29741c99275SPeter Avalos NULL,
29841c99275SPeter Avalos NULL,
29941c99275SPeter Avalos NULL,
30041c99275SPeter Avalos clnp_option_rfd_address_values,
30141c99275SPeter Avalos clnp_option_rfd_source_routeing_values,
30241c99275SPeter Avalos clnp_option_rfd_lifetime_values,
30341c99275SPeter Avalos clnp_option_rfd_pdu_discard_values,
30441c99275SPeter Avalos clnp_option_rfd_reassembly_values,
30541c99275SPeter Avalos NULL,
30641c99275SPeter Avalos NULL,
30741c99275SPeter Avalos NULL
30841c99275SPeter Avalos };
30941c99275SPeter Avalos
31041c99275SPeter Avalos #define CLNP_OPTION_OPTION_QOS_MASK 0x3f
31141c99275SPeter Avalos #define CLNP_OPTION_SCOPE_MASK 0xc0
31241c99275SPeter Avalos #define CLNP_OPTION_SCOPE_SA_SPEC 0x40
31341c99275SPeter Avalos #define CLNP_OPTION_SCOPE_DA_SPEC 0x80
31441c99275SPeter Avalos #define CLNP_OPTION_SCOPE_GLOBAL 0xc0
31541c99275SPeter Avalos
316411677aeSAaron LI static const struct tok clnp_option_scope_values[] = {
31741c99275SPeter Avalos { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"},
31841c99275SPeter Avalos { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"},
31941c99275SPeter Avalos { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"},
32041c99275SPeter Avalos { 0, NULL }
32141c99275SPeter Avalos };
32241c99275SPeter Avalos
323411677aeSAaron LI static const struct tok clnp_option_sr_rr_values[] = {
32441c99275SPeter Avalos { 0x0, "partial"},
32541c99275SPeter Avalos { 0x1, "complete"},
32641c99275SPeter Avalos { 0, NULL }
32741c99275SPeter Avalos };
32841c99275SPeter Avalos
329411677aeSAaron LI static const struct tok clnp_option_sr_rr_string_values[] = {
33041c99275SPeter Avalos { CLNP_OPTION_SOURCE_ROUTING, "source routing"},
33141c99275SPeter Avalos { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"},
33241c99275SPeter Avalos { 0, NULL }
33341c99275SPeter Avalos };
33441c99275SPeter Avalos
335411677aeSAaron LI static const struct tok clnp_option_qos_global_values[] = {
33641c99275SPeter Avalos { 0x20, "reserved"},
33741c99275SPeter Avalos { 0x10, "sequencing vs. delay"},
33841c99275SPeter Avalos { 0x08, "congested"},
33941c99275SPeter Avalos { 0x04, "delay vs. cost"},
34041c99275SPeter Avalos { 0x02, "error vs. delay"},
34141c99275SPeter Avalos { 0x01, "error vs. cost"},
34241c99275SPeter Avalos { 0, NULL }
34341c99275SPeter Avalos };
34441c99275SPeter Avalos
345*ed775ee7SAntonio Huete Jimenez static const struct tok isis_tlv_router_capability_flags[] = {
346*ed775ee7SAntonio Huete Jimenez { 0x01, "S bit"},
347*ed775ee7SAntonio Huete Jimenez { 0x02, "D bit"},
348*ed775ee7SAntonio Huete Jimenez { 0, NULL }
349*ed775ee7SAntonio Huete Jimenez };
350*ed775ee7SAntonio Huete Jimenez
351*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_ROUTER_CAP_SR 2 /* rfc 8667 */
352*ed775ee7SAntonio Huete Jimenez
353*ed775ee7SAntonio Huete Jimenez static const struct tok isis_router_capability_subtlv_values[] = {
354*ed775ee7SAntonio Huete Jimenez { ISIS_SUBTLV_ROUTER_CAP_SR, "SR-Capabilities"},
355*ed775ee7SAntonio Huete Jimenez { 0, NULL }
356*ed775ee7SAntonio Huete Jimenez };
357*ed775ee7SAntonio Huete Jimenez
358*ed775ee7SAntonio Huete Jimenez static const struct tok isis_router_capability_sr_flags[] = {
359*ed775ee7SAntonio Huete Jimenez { 0x80, "ipv4"},
360*ed775ee7SAntonio Huete Jimenez { 0x40, "ipv6"},
361*ed775ee7SAntonio Huete Jimenez { 0, NULL }
362*ed775ee7SAntonio Huete Jimenez };
363*ed775ee7SAntonio Huete Jimenez
364*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* rfc5305 */
365ea7b4bf5SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */
366*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* rfc5305 */
367*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* rfc5305 */
368*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* rfc5305 */
369*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* rfc5305 */
370*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* rfc5305 */
37141c99275SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */
37241c99275SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */
373*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* rfc5305 */
374ea7b4bf5SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */
375ea7b4bf5SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */
376ea7b4bf5SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */
37741c99275SPeter Avalos #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */
378*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID 32 /* rfc8667 */
37941c99275SPeter Avalos
380411677aeSAaron LI #define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */
381411677aeSAaron LI
382411677aeSAaron LI static const struct tok isis_ext_is_reach_subtlv_values[] = {
38341c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" },
38441c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
38541c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" },
38641c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" },
38741c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" },
38841c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" },
38941c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" },
39041c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" },
39141c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" },
392ea7b4bf5SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" },
39341c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" },
39441c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
39541c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" },
39641c99275SPeter Avalos { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" },
397*ed775ee7SAntonio Huete Jimenez { ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID, "LAN Adjacency Segment Identifier" },
398411677aeSAaron LI { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" },
39941c99275SPeter Avalos { 250, "Reserved for cisco specific extensions" },
40041c99275SPeter Avalos { 251, "Reserved for cisco specific extensions" },
40141c99275SPeter Avalos { 252, "Reserved for cisco specific extensions" },
40241c99275SPeter Avalos { 253, "Reserved for cisco specific extensions" },
40341c99275SPeter Avalos { 254, "Reserved for cisco specific extensions" },
40441c99275SPeter Avalos { 255, "Reserved for future expansion" },
40541c99275SPeter Avalos { 0, NULL }
40641c99275SPeter Avalos };
40741c99275SPeter Avalos
40841c99275SPeter Avalos #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */
40941c99275SPeter Avalos #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */
410*ed775ee7SAntonio Huete Jimenez #define ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID 3 /* rfc8667 */
41141c99275SPeter Avalos #define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */
41241c99275SPeter Avalos
413411677aeSAaron LI static const struct tok isis_ext_ip_reach_subtlv_values[] = {
41441c99275SPeter Avalos { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" },
41541c99275SPeter Avalos { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" },
416*ed775ee7SAntonio Huete Jimenez { ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID, "Prefix SID" },
41741c99275SPeter Avalos { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" },
41841c99275SPeter Avalos { 0, NULL }
41941c99275SPeter Avalos };
42041c99275SPeter Avalos
421*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_R 0x80 /* rfc 8667 */
422*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_N 0x40 /* rfc 8667 */
423*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_P 0x20 /* rfc 8667 */
424*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_E 0x10 /* rfc 8667 */
425*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_V 0x08 /* rfc 8667 */
426*ed775ee7SAntonio Huete Jimenez #define ISIS_PREFIX_SID_FLAG_L 0x04 /* rfc 8667 */
427*ed775ee7SAntonio Huete Jimenez
428*ed775ee7SAntonio Huete Jimenez static const struct tok prefix_sid_flag_values[] = {
429*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_R, "Readvertisement"},
430*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_N, "Node"},
431*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_P, "No-PHP"},
432*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_E, "Explicit NULL"},
433*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_V, "Value"},
434*ed775ee7SAntonio Huete Jimenez { ISIS_PREFIX_SID_FLAG_L, "Local"},
435*ed775ee7SAntonio Huete Jimenez { 0, NULL}
436*ed775ee7SAntonio Huete Jimenez };
437*ed775ee7SAntonio Huete Jimenez
438*ed775ee7SAntonio Huete Jimenez
439*ed775ee7SAntonio Huete Jimenez /* rfc 8667 */
440*ed775ee7SAntonio Huete Jimenez static const struct tok prefix_sid_algo_values[] = {
441*ed775ee7SAntonio Huete Jimenez { 0, "SPF"},
442*ed775ee7SAntonio Huete Jimenez { 1, "strict-SPF"},
443*ed775ee7SAntonio Huete Jimenez { 0, NULL}
444*ed775ee7SAntonio Huete Jimenez };
445*ed775ee7SAntonio Huete Jimenez
446411677aeSAaron LI static const struct tok isis_subtlv_link_attribute_values[] = {
447ea7b4bf5SPeter Avalos { 0x01, "Local Protection Available" },
448ea7b4bf5SPeter Avalos { 0x02, "Link excluded from local protection path" },
449ea7b4bf5SPeter Avalos { 0x04, "Local maintenance required"},
450ea7b4bf5SPeter Avalos { 0, NULL }
451ea7b4bf5SPeter Avalos };
452ea7b4bf5SPeter Avalos
453*ed775ee7SAntonio Huete Jimenez static const struct tok isis_lan_adj_sid_flag_values[] = {
454*ed775ee7SAntonio Huete Jimenez { 0x80, "Address family IPv6" },
455*ed775ee7SAntonio Huete Jimenez { 0x40, "Backup" },
456*ed775ee7SAntonio Huete Jimenez { 0x20, "Value" },
457*ed775ee7SAntonio Huete Jimenez { 0x10, "Local significance" },
458*ed775ee7SAntonio Huete Jimenez { 0x08, "Set of adjacencies" },
459*ed775ee7SAntonio Huete Jimenez { 0x04, "Persistent" },
460*ed775ee7SAntonio Huete Jimenez { 0, NULL }
461*ed775ee7SAntonio Huete Jimenez };
462*ed775ee7SAntonio Huete Jimenez
46341c99275SPeter Avalos #define ISIS_SUBTLV_AUTH_SIMPLE 1
46427bfbee1SPeter Avalos #define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */
46541c99275SPeter Avalos #define ISIS_SUBTLV_AUTH_MD5 54
46641c99275SPeter Avalos #define ISIS_SUBTLV_AUTH_MD5_LEN 16
46741c99275SPeter Avalos #define ISIS_SUBTLV_AUTH_PRIVATE 255
46841c99275SPeter Avalos
469411677aeSAaron LI static const struct tok isis_subtlv_auth_values[] = {
47041c99275SPeter Avalos { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"},
47127bfbee1SPeter Avalos { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"},
47241c99275SPeter Avalos { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"},
47341c99275SPeter Avalos { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"},
47441c99275SPeter Avalos { 0, NULL }
47541c99275SPeter Avalos };
47641c99275SPeter Avalos
47741c99275SPeter Avalos #define ISIS_SUBTLV_IDRP_RES 0
47841c99275SPeter Avalos #define ISIS_SUBTLV_IDRP_LOCAL 1
47941c99275SPeter Avalos #define ISIS_SUBTLV_IDRP_ASN 2
48041c99275SPeter Avalos
481411677aeSAaron LI static const struct tok isis_subtlv_idrp_values[] = {
48241c99275SPeter Avalos { ISIS_SUBTLV_IDRP_RES, "Reserved"},
48341c99275SPeter Avalos { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"},
48441c99275SPeter Avalos { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"},
48541c99275SPeter Avalos { 0, NULL}
48641c99275SPeter Avalos };
48741c99275SPeter Avalos
488411677aeSAaron LI #define ISIS_SUBTLV_SPB_MCID 4
489411677aeSAaron LI #define ISIS_SUBTLV_SPB_DIGEST 5
490411677aeSAaron LI #define ISIS_SUBTLV_SPB_BVID 6
491411677aeSAaron LI
492411677aeSAaron LI #define ISIS_SUBTLV_SPB_INSTANCE 1
493411677aeSAaron LI #define ISIS_SUBTLV_SPBM_SI 3
494411677aeSAaron LI
495411677aeSAaron LI #define ISIS_SPB_MCID_LEN 51
496411677aeSAaron LI #define ISIS_SUBTLV_SPB_MCID_MIN_LEN 102
497411677aeSAaron LI #define ISIS_SUBTLV_SPB_DIGEST_MIN_LEN 33
498411677aeSAaron LI #define ISIS_SUBTLV_SPB_BVID_MIN_LEN 6
499411677aeSAaron LI #define ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN 19
500411677aeSAaron LI #define ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN 8
501411677aeSAaron LI
502411677aeSAaron LI static const struct tok isis_mt_port_cap_subtlv_values[] = {
503411677aeSAaron LI { ISIS_SUBTLV_SPB_MCID, "SPB MCID" },
504411677aeSAaron LI { ISIS_SUBTLV_SPB_DIGEST, "SPB Digest" },
505411677aeSAaron LI { ISIS_SUBTLV_SPB_BVID, "SPB BVID" },
506411677aeSAaron LI { 0, NULL }
507411677aeSAaron LI };
508411677aeSAaron LI
509411677aeSAaron LI static const struct tok isis_mt_capability_subtlv_values[] = {
510411677aeSAaron LI { ISIS_SUBTLV_SPB_INSTANCE, "SPB Instance" },
511411677aeSAaron LI { ISIS_SUBTLV_SPBM_SI, "SPBM Service Identifier and Unicast Address" },
512411677aeSAaron LI { 0, NULL }
513411677aeSAaron LI };
514411677aeSAaron LI
515411677aeSAaron LI struct isis_spb_mcid {
516*ed775ee7SAntonio Huete Jimenez nd_uint8_t format_id;
517*ed775ee7SAntonio Huete Jimenez nd_byte name[32];
518*ed775ee7SAntonio Huete Jimenez nd_uint16_t revision_lvl;
519*ed775ee7SAntonio Huete Jimenez nd_byte digest[16];
520411677aeSAaron LI };
521411677aeSAaron LI
522411677aeSAaron LI struct isis_subtlv_spb_mcid {
523411677aeSAaron LI struct isis_spb_mcid mcid;
524411677aeSAaron LI struct isis_spb_mcid aux_mcid;
525411677aeSAaron LI };
526411677aeSAaron LI
527411677aeSAaron LI struct isis_subtlv_spb_instance {
528*ed775ee7SAntonio Huete Jimenez nd_byte cist_root_id[8];
529*ed775ee7SAntonio Huete Jimenez nd_uint32_t cist_external_root_path_cost;
530*ed775ee7SAntonio Huete Jimenez nd_uint16_t bridge_priority;
531*ed775ee7SAntonio Huete Jimenez nd_uint32_t spsourceid;
532*ed775ee7SAntonio Huete Jimenez nd_uint8_t no_of_trees;
533411677aeSAaron LI };
534411677aeSAaron LI
53541c99275SPeter Avalos #define CLNP_SEGMENT_PART 0x80
53641c99275SPeter Avalos #define CLNP_MORE_SEGMENTS 0x40
53741c99275SPeter Avalos #define CLNP_REQUEST_ER 0x20
53841c99275SPeter Avalos
539411677aeSAaron LI static const struct tok clnp_flag_values[] = {
54041c99275SPeter Avalos { CLNP_SEGMENT_PART, "Segmentation permitted"},
54141c99275SPeter Avalos { CLNP_MORE_SEGMENTS, "more Segments"},
54241c99275SPeter Avalos { CLNP_REQUEST_ER, "request Error Report"},
54341c99275SPeter Avalos { 0, NULL}
54441c99275SPeter Avalos };
54541c99275SPeter Avalos
546*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_OL_BIT(x) (GET_U_1(x)&0x4)
547*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ISTYPE_BITS(x) (GET_U_1(x)&0x3)
548*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_PARTITION_BIT(x) (GET_U_1(x)&0x80)
549*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ATT_BITS(x) (GET_U_1(x)&0x78)
550*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) (GET_U_1(x)&0x40)
551*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) (GET_U_1(x)&0x20)
552*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) (GET_U_1(x)&0x10)
553*ed775ee7SAntonio Huete Jimenez #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) (GET_U_1(x)&0x8)
55441c99275SPeter Avalos
55541c99275SPeter Avalos #define ISIS_MASK_MTID(x) ((x)&0x0fff)
55641c99275SPeter Avalos #define ISIS_MASK_MTFLAGS(x) ((x)&0xf000)
55741c99275SPeter Avalos
558411677aeSAaron LI static const struct tok isis_mt_flag_values[] = {
55927bfbee1SPeter Avalos { 0x4000, "ATT bit set"},
56027bfbee1SPeter Avalos { 0x8000, "Overload bit set"},
56141c99275SPeter Avalos { 0, NULL}
56241c99275SPeter Avalos };
56341c99275SPeter Avalos
56441c99275SPeter Avalos #define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80)
56541c99275SPeter Avalos #define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40)
56641c99275SPeter Avalos
56741c99275SPeter Avalos #define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40)
56841c99275SPeter Avalos #define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20)
56941c99275SPeter Avalos
570*ed775ee7SAntonio Huete Jimenez #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) (GET_U_1(x)&0x80)
571*ed775ee7SAntonio Huete Jimenez #define ISIS_LSP_TLV_METRIC_IE(x) (GET_U_1(x)&0x40)
572*ed775ee7SAntonio Huete Jimenez #define ISIS_LSP_TLV_METRIC_UPDOWN(x) (GET_U_1(x)&0x80)
573*ed775ee7SAntonio Huete Jimenez #define ISIS_LSP_TLV_METRIC_VALUE(x) (GET_U_1(x)&0x3f)
57441c99275SPeter Avalos
57541c99275SPeter Avalos #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
57641c99275SPeter Avalos
577411677aeSAaron LI static const struct tok isis_mt_values[] = {
57841c99275SPeter Avalos { 0, "IPv4 unicast"},
57941c99275SPeter Avalos { 1, "In-Band Management"},
58041c99275SPeter Avalos { 2, "IPv6 unicast"},
58141c99275SPeter Avalos { 3, "Multicast"},
58241c99275SPeter Avalos { 4095, "Development, Experimental or Proprietary"},
58341c99275SPeter Avalos { 0, NULL }
58441c99275SPeter Avalos };
58541c99275SPeter Avalos
586411677aeSAaron LI static const struct tok isis_iih_circuit_type_values[] = {
58741c99275SPeter Avalos { 1, "Level 1 only"},
58841c99275SPeter Avalos { 2, "Level 2 only"},
58941c99275SPeter Avalos { 3, "Level 1, Level 2"},
59041c99275SPeter Avalos { 0, NULL}
59141c99275SPeter Avalos };
59241c99275SPeter Avalos
59341c99275SPeter Avalos #define ISIS_LSP_TYPE_UNUSED0 0
59441c99275SPeter Avalos #define ISIS_LSP_TYPE_LEVEL_1 1
59541c99275SPeter Avalos #define ISIS_LSP_TYPE_UNUSED2 2
59641c99275SPeter Avalos #define ISIS_LSP_TYPE_LEVEL_2 3
59741c99275SPeter Avalos
598411677aeSAaron LI static const struct tok isis_lsp_istype_values[] = {
59941c99275SPeter Avalos { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
60041c99275SPeter Avalos { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
60141c99275SPeter Avalos { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
60241c99275SPeter Avalos { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"},
60341c99275SPeter Avalos { 0, NULL }
60441c99275SPeter Avalos };
60541c99275SPeter Avalos
60641c99275SPeter Avalos /*
60741c99275SPeter Avalos * Katz's point to point adjacency TLV uses codes to tell us the state of
60841c99275SPeter Avalos * the remote adjacency. Enumerate them.
60941c99275SPeter Avalos */
61041c99275SPeter Avalos
61141c99275SPeter Avalos #define ISIS_PTP_ADJ_UP 0
61241c99275SPeter Avalos #define ISIS_PTP_ADJ_INIT 1
61341c99275SPeter Avalos #define ISIS_PTP_ADJ_DOWN 2
61441c99275SPeter Avalos
615411677aeSAaron LI static const struct tok isis_ptp_adjancey_values[] = {
61641c99275SPeter Avalos { ISIS_PTP_ADJ_UP, "Up" },
61741c99275SPeter Avalos { ISIS_PTP_ADJ_INIT, "Initializing" },
61841c99275SPeter Avalos { ISIS_PTP_ADJ_DOWN, "Down" },
61941c99275SPeter Avalos { 0, NULL}
62041c99275SPeter Avalos };
62141c99275SPeter Avalos
62241c99275SPeter Avalos struct isis_tlv_ptp_adj {
623*ed775ee7SAntonio Huete Jimenez nd_uint8_t adjacency_state;
624*ed775ee7SAntonio Huete Jimenez nd_uint32_t extd_local_circuit_id;
625*ed775ee7SAntonio Huete Jimenez nd_byte neighbor_sysid[SYSTEM_ID_LEN];
626*ed775ee7SAntonio Huete Jimenez nd_uint32_t neighbor_extd_local_circuit_id;
62741c99275SPeter Avalos };
62841c99275SPeter Avalos
629411677aeSAaron LI static void osi_print_cksum(netdissect_options *, const uint8_t *pptr,
630411677aeSAaron LI uint16_t checksum, int checksum_offset, u_int length);
631411677aeSAaron LI static int clnp_print(netdissect_options *, const uint8_t *, u_int);
632411677aeSAaron LI static void esis_print(netdissect_options *, const uint8_t *, u_int);
633411677aeSAaron LI static int isis_print(netdissect_options *, const uint8_t *, u_int);
63441c99275SPeter Avalos
63541c99275SPeter Avalos struct isis_metric_block {
636*ed775ee7SAntonio Huete Jimenez nd_uint8_t metric_default;
637*ed775ee7SAntonio Huete Jimenez nd_uint8_t metric_delay;
638*ed775ee7SAntonio Huete Jimenez nd_uint8_t metric_expense;
639*ed775ee7SAntonio Huete Jimenez nd_uint8_t metric_error;
64041c99275SPeter Avalos };
64141c99275SPeter Avalos
64241c99275SPeter Avalos struct isis_tlv_is_reach {
64341c99275SPeter Avalos struct isis_metric_block isis_metric_block;
644*ed775ee7SAntonio Huete Jimenez nd_byte neighbor_nodeid[NODE_ID_LEN];
64541c99275SPeter Avalos };
64641c99275SPeter Avalos
64741c99275SPeter Avalos struct isis_tlv_es_reach {
64841c99275SPeter Avalos struct isis_metric_block isis_metric_block;
649*ed775ee7SAntonio Huete Jimenez nd_byte neighbor_sysid[SYSTEM_ID_LEN];
65041c99275SPeter Avalos };
65141c99275SPeter Avalos
65241c99275SPeter Avalos struct isis_tlv_ip_reach {
65341c99275SPeter Avalos struct isis_metric_block isis_metric_block;
654*ed775ee7SAntonio Huete Jimenez nd_ipv4 prefix;
655*ed775ee7SAntonio Huete Jimenez nd_ipv4 mask;
65641c99275SPeter Avalos };
65741c99275SPeter Avalos
658411677aeSAaron LI static const struct tok isis_is_reach_virtual_values[] = {
65941c99275SPeter Avalos { 0, "IsNotVirtual"},
66041c99275SPeter Avalos { 1, "IsVirtual"},
66141c99275SPeter Avalos { 0, NULL }
66241c99275SPeter Avalos };
66341c99275SPeter Avalos
664411677aeSAaron LI static const struct tok isis_restart_flag_values[] = {
66541c99275SPeter Avalos { 0x1, "Restart Request"},
66641c99275SPeter Avalos { 0x2, "Restart Acknowledgement"},
66741c99275SPeter Avalos { 0x4, "Suppress adjacency advertisement"},
66841c99275SPeter Avalos { 0, NULL }
66941c99275SPeter Avalos };
67041c99275SPeter Avalos
67141c99275SPeter Avalos struct isis_common_header {
672*ed775ee7SAntonio Huete Jimenez nd_uint8_t nlpid;
673*ed775ee7SAntonio Huete Jimenez nd_uint8_t fixed_len;
674*ed775ee7SAntonio Huete Jimenez nd_uint8_t version; /* Protocol version */
675*ed775ee7SAntonio Huete Jimenez nd_uint8_t id_length;
676*ed775ee7SAntonio Huete Jimenez nd_uint8_t pdu_type; /* 3 MSbits are reserved */
677*ed775ee7SAntonio Huete Jimenez nd_uint8_t pdu_version; /* Packet format version */
678*ed775ee7SAntonio Huete Jimenez nd_byte reserved;
679*ed775ee7SAntonio Huete Jimenez nd_uint8_t max_area;
68041c99275SPeter Avalos };
68141c99275SPeter Avalos
68241c99275SPeter Avalos struct isis_iih_lan_header {
683*ed775ee7SAntonio Huete Jimenez nd_uint8_t circuit_type;
684*ed775ee7SAntonio Huete Jimenez nd_byte source_id[SYSTEM_ID_LEN];
685*ed775ee7SAntonio Huete Jimenez nd_uint16_t holding_time;
686*ed775ee7SAntonio Huete Jimenez nd_uint16_t pdu_len;
687*ed775ee7SAntonio Huete Jimenez nd_uint8_t priority;
688*ed775ee7SAntonio Huete Jimenez nd_byte lan_id[NODE_ID_LEN];
68941c99275SPeter Avalos };
69041c99275SPeter Avalos
69141c99275SPeter Avalos struct isis_iih_ptp_header {
692*ed775ee7SAntonio Huete Jimenez nd_uint8_t circuit_type;
693*ed775ee7SAntonio Huete Jimenez nd_byte source_id[SYSTEM_ID_LEN];
694*ed775ee7SAntonio Huete Jimenez nd_uint16_t holding_time;
695*ed775ee7SAntonio Huete Jimenez nd_uint16_t pdu_len;
696*ed775ee7SAntonio Huete Jimenez nd_uint8_t circuit_id;
69741c99275SPeter Avalos };
69841c99275SPeter Avalos
69941c99275SPeter Avalos struct isis_lsp_header {
700*ed775ee7SAntonio Huete Jimenez nd_uint16_t pdu_len;
701*ed775ee7SAntonio Huete Jimenez nd_uint16_t remaining_lifetime;
702*ed775ee7SAntonio Huete Jimenez nd_byte lsp_id[LSP_ID_LEN];
703*ed775ee7SAntonio Huete Jimenez nd_uint32_t sequence_number;
704*ed775ee7SAntonio Huete Jimenez nd_uint16_t checksum;
705*ed775ee7SAntonio Huete Jimenez nd_uint8_t typeblock;
70641c99275SPeter Avalos };
70741c99275SPeter Avalos
70841c99275SPeter Avalos struct isis_csnp_header {
709*ed775ee7SAntonio Huete Jimenez nd_uint16_t pdu_len;
710*ed775ee7SAntonio Huete Jimenez nd_byte source_id[NODE_ID_LEN];
711*ed775ee7SAntonio Huete Jimenez nd_byte start_lsp_id[LSP_ID_LEN];
712*ed775ee7SAntonio Huete Jimenez nd_byte end_lsp_id[LSP_ID_LEN];
71341c99275SPeter Avalos };
71441c99275SPeter Avalos
71541c99275SPeter Avalos struct isis_psnp_header {
716*ed775ee7SAntonio Huete Jimenez nd_uint16_t pdu_len;
717*ed775ee7SAntonio Huete Jimenez nd_byte source_id[NODE_ID_LEN];
71841c99275SPeter Avalos };
71941c99275SPeter Avalos
72041c99275SPeter Avalos struct isis_tlv_lsp {
721*ed775ee7SAntonio Huete Jimenez nd_uint16_t remaining_lifetime;
722*ed775ee7SAntonio Huete Jimenez nd_byte lsp_id[LSP_ID_LEN];
723*ed775ee7SAntonio Huete Jimenez nd_uint32_t sequence_number;
724*ed775ee7SAntonio Huete Jimenez nd_uint16_t checksum;
72541c99275SPeter Avalos };
72641c99275SPeter Avalos
72741c99275SPeter Avalos #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
72841c99275SPeter Avalos #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
72941c99275SPeter Avalos #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
73041c99275SPeter Avalos #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
73141c99275SPeter Avalos #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
73241c99275SPeter Avalos #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
73341c99275SPeter Avalos
734411677aeSAaron LI void
isoclns_print(netdissect_options * ndo,const u_char * p,u_int length)735*ed775ee7SAntonio Huete Jimenez isoclns_print(netdissect_options *ndo, const u_char *p, u_int length)
73641c99275SPeter Avalos {
737*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "isoclns";
73841c99275SPeter Avalos
739411677aeSAaron LI if (ndo->ndo_eflag)
740*ed775ee7SAntonio Huete Jimenez ND_PRINT("OSI NLPID %s (0x%02x): ",
741*ed775ee7SAntonio Huete Jimenez tok2str(nlpid_values, "Unknown", GET_U_1(p)),
742*ed775ee7SAntonio Huete Jimenez GET_U_1(p));
74341c99275SPeter Avalos
744*ed775ee7SAntonio Huete Jimenez switch (GET_U_1(p)) {
74541c99275SPeter Avalos
74641c99275SPeter Avalos case NLPID_CLNP:
747411677aeSAaron LI if (!clnp_print(ndo, p, length))
748411677aeSAaron LI print_unknown_data(ndo, p, "\n\t", length);
74941c99275SPeter Avalos break;
75041c99275SPeter Avalos
75141c99275SPeter Avalos case NLPID_ESIS:
752411677aeSAaron LI esis_print(ndo, p, length);
75341c99275SPeter Avalos return;
75441c99275SPeter Avalos
75541c99275SPeter Avalos case NLPID_ISIS:
756411677aeSAaron LI if (!isis_print(ndo, p, length))
757411677aeSAaron LI print_unknown_data(ndo, p, "\n\t", length);
75841c99275SPeter Avalos break;
75941c99275SPeter Avalos
76041c99275SPeter Avalos case NLPID_NULLNS:
761*ed775ee7SAntonio Huete Jimenez ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length);
76241c99275SPeter Avalos break;
76341c99275SPeter Avalos
76441c99275SPeter Avalos case NLPID_Q933:
765411677aeSAaron LI q933_print(ndo, p + 1, length - 1);
76641c99275SPeter Avalos break;
76741c99275SPeter Avalos
76841c99275SPeter Avalos case NLPID_IP:
769411677aeSAaron LI ip_print(ndo, p + 1, length - 1);
77041c99275SPeter Avalos break;
77141c99275SPeter Avalos
77241c99275SPeter Avalos case NLPID_IP6:
773411677aeSAaron LI ip6_print(ndo, p + 1, length - 1);
77441c99275SPeter Avalos break;
77541c99275SPeter Avalos
77641c99275SPeter Avalos case NLPID_PPP:
777411677aeSAaron LI ppp_print(ndo, p + 1, length - 1);
77841c99275SPeter Avalos break;
77941c99275SPeter Avalos
78041c99275SPeter Avalos default:
781411677aeSAaron LI if (!ndo->ndo_eflag)
782*ed775ee7SAntonio Huete Jimenez ND_PRINT("OSI NLPID 0x%02x unknown", GET_U_1(p));
783*ed775ee7SAntonio Huete Jimenez ND_PRINT("%slength: %u", ndo->ndo_eflag ? "" : ", ", length);
784411677aeSAaron LI if (length > 1)
785411677aeSAaron LI print_unknown_data(ndo, p, "\n\t", length);
78641c99275SPeter Avalos break;
78741c99275SPeter Avalos }
78841c99275SPeter Avalos }
78941c99275SPeter Avalos
79041c99275SPeter Avalos #define CLNP_PDU_ER 1
79141c99275SPeter Avalos #define CLNP_PDU_DT 28
79241c99275SPeter Avalos #define CLNP_PDU_MD 29
79341c99275SPeter Avalos #define CLNP_PDU_ERQ 30
79441c99275SPeter Avalos #define CLNP_PDU_ERP 31
79541c99275SPeter Avalos
796411677aeSAaron LI static const struct tok clnp_pdu_values[] = {
79741c99275SPeter Avalos { CLNP_PDU_ER, "Error Report"},
79841c99275SPeter Avalos { CLNP_PDU_MD, "MD"},
79941c99275SPeter Avalos { CLNP_PDU_DT, "Data"},
80041c99275SPeter Avalos { CLNP_PDU_ERQ, "Echo Request"},
80141c99275SPeter Avalos { CLNP_PDU_ERP, "Echo Response"},
80241c99275SPeter Avalos { 0, NULL }
80341c99275SPeter Avalos };
80441c99275SPeter Avalos
80541c99275SPeter Avalos struct clnp_header_t {
806*ed775ee7SAntonio Huete Jimenez nd_uint8_t nlpid;
807*ed775ee7SAntonio Huete Jimenez nd_uint8_t length_indicator;
808*ed775ee7SAntonio Huete Jimenez nd_uint8_t version;
809*ed775ee7SAntonio Huete Jimenez nd_uint8_t lifetime; /* units of 500ms */
810*ed775ee7SAntonio Huete Jimenez nd_uint8_t type;
811*ed775ee7SAntonio Huete Jimenez nd_uint16_t segment_length;
812*ed775ee7SAntonio Huete Jimenez nd_uint16_t cksum;
81341c99275SPeter Avalos };
81441c99275SPeter Avalos
81541c99275SPeter Avalos struct clnp_segment_header_t {
816*ed775ee7SAntonio Huete Jimenez nd_uint16_t data_unit_id;
817*ed775ee7SAntonio Huete Jimenez nd_uint16_t segment_offset;
818*ed775ee7SAntonio Huete Jimenez nd_uint16_t total_length;
81941c99275SPeter Avalos };
82041c99275SPeter Avalos
82141c99275SPeter Avalos /*
82241c99275SPeter Avalos * clnp_print
82341c99275SPeter Avalos * Decode CLNP packets. Return 0 on error.
82441c99275SPeter Avalos */
82541c99275SPeter Avalos
826411677aeSAaron LI static int
clnp_print(netdissect_options * ndo,const uint8_t * pptr,u_int length)827411677aeSAaron LI clnp_print(netdissect_options *ndo,
828411677aeSAaron LI const uint8_t *pptr, u_int length)
82941c99275SPeter Avalos {
830411677aeSAaron LI const uint8_t *optr,*source_address,*dest_address;
831*ed775ee7SAntonio Huete Jimenez u_int li,li_remaining,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags;
83241c99275SPeter Avalos const struct clnp_header_t *clnp_header;
83341c99275SPeter Avalos const struct clnp_segment_header_t *clnp_segment_header;
834*ed775ee7SAntonio Huete Jimenez uint8_t rfd_error,rfd_error_major,rfd_error_minor;
83541c99275SPeter Avalos
836*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "clnp";
83741c99275SPeter Avalos clnp_header = (const struct clnp_header_t *) pptr;
838*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(clnp_header);
83941c99275SPeter Avalos
840*ed775ee7SAntonio Huete Jimenez li = GET_U_1(clnp_header->length_indicator);
841*ed775ee7SAntonio Huete Jimenez li_remaining = li;
84241c99275SPeter Avalos optr = pptr;
84341c99275SPeter Avalos
844411677aeSAaron LI if (!ndo->ndo_eflag)
845*ed775ee7SAntonio Huete Jimenez nd_print_protocol_caps(ndo);
84641c99275SPeter Avalos
84741c99275SPeter Avalos /*
84841c99275SPeter Avalos * Sanity checking of the header.
84941c99275SPeter Avalos */
85041c99275SPeter Avalos
851*ed775ee7SAntonio Huete Jimenez if (GET_U_1(clnp_header->version) != CLNP_VERSION) {
852*ed775ee7SAntonio Huete Jimenez ND_PRINT("version %u packet not supported",
853*ed775ee7SAntonio Huete Jimenez GET_U_1(clnp_header->version));
854411677aeSAaron LI return (0);
855411677aeSAaron LI }
856411677aeSAaron LI
857411677aeSAaron LI if (li > length) {
858*ed775ee7SAntonio Huete Jimenez ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length);
859411677aeSAaron LI return (0);
860411677aeSAaron LI }
861411677aeSAaron LI
862411677aeSAaron LI if (li < sizeof(struct clnp_header_t)) {
863*ed775ee7SAntonio Huete Jimenez ND_PRINT(" length indicator %u < min PDU size:", li);
864*ed775ee7SAntonio Huete Jimenez while (pptr < ndo->ndo_snapend) {
865*ed775ee7SAntonio Huete Jimenez ND_PRINT("%02X", GET_U_1(pptr));
866*ed775ee7SAntonio Huete Jimenez pptr++;
867*ed775ee7SAntonio Huete Jimenez }
86841c99275SPeter Avalos return (0);
86941c99275SPeter Avalos }
87041c99275SPeter Avalos
87141c99275SPeter Avalos /* FIXME further header sanity checking */
87241c99275SPeter Avalos
873*ed775ee7SAntonio Huete Jimenez clnp_pdu_type = GET_U_1(clnp_header->type) & CLNP_PDU_TYPE_MASK;
874*ed775ee7SAntonio Huete Jimenez clnp_flags = GET_U_1(clnp_header->type) & CLNP_FLAG_MASK;
87541c99275SPeter Avalos
87641c99275SPeter Avalos pptr += sizeof(struct clnp_header_t);
877*ed775ee7SAntonio Huete Jimenez li_remaining -= sizeof(struct clnp_header_t);
878411677aeSAaron LI
879*ed775ee7SAntonio Huete Jimenez if (li_remaining < 1) {
880*ed775ee7SAntonio Huete Jimenez ND_PRINT("li < size of fixed part of CLNP header and addresses");
881411677aeSAaron LI return (0);
882411677aeSAaron LI }
883*ed775ee7SAntonio Huete Jimenez dest_address_length = GET_U_1(pptr);
884411677aeSAaron LI pptr += 1;
885*ed775ee7SAntonio Huete Jimenez li_remaining -= 1;
886*ed775ee7SAntonio Huete Jimenez if (li_remaining < dest_address_length) {
887*ed775ee7SAntonio Huete Jimenez ND_PRINT("li < size of fixed part of CLNP header and addresses");
888411677aeSAaron LI return (0);
889411677aeSAaron LI }
890*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, dest_address_length);
891411677aeSAaron LI dest_address = pptr;
892411677aeSAaron LI pptr += dest_address_length;
893*ed775ee7SAntonio Huete Jimenez li_remaining -= dest_address_length;
89441c99275SPeter Avalos
895*ed775ee7SAntonio Huete Jimenez if (li_remaining < 1) {
896*ed775ee7SAntonio Huete Jimenez ND_PRINT("li < size of fixed part of CLNP header and addresses");
897411677aeSAaron LI return (0);
898411677aeSAaron LI }
899*ed775ee7SAntonio Huete Jimenez source_address_length = GET_U_1(pptr);
900411677aeSAaron LI pptr += 1;
901*ed775ee7SAntonio Huete Jimenez li_remaining -= 1;
902*ed775ee7SAntonio Huete Jimenez if (li_remaining < source_address_length) {
903*ed775ee7SAntonio Huete Jimenez ND_PRINT("li < size of fixed part of CLNP header and addresses");
904411677aeSAaron LI return (0);
905411677aeSAaron LI }
906*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, source_address_length);
907411677aeSAaron LI source_address = pptr;
908411677aeSAaron LI pptr += source_address_length;
909*ed775ee7SAntonio Huete Jimenez li_remaining -= source_address_length;
91041c99275SPeter Avalos
911411677aeSAaron LI if (ndo->ndo_vflag < 1) {
912*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s > %s, %s, length %u",
913411677aeSAaron LI ndo->ndo_eflag ? "" : ", ",
914*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(source_address, source_address_length),
915*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(dest_address, dest_address_length),
91641c99275SPeter Avalos tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type),
917*ed775ee7SAntonio Huete Jimenez length);
91841c99275SPeter Avalos return (1);
91941c99275SPeter Avalos }
920*ed775ee7SAntonio Huete Jimenez ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length);
92141c99275SPeter Avalos
922*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x",
92341c99275SPeter Avalos tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type),
924*ed775ee7SAntonio Huete Jimenez GET_U_1(clnp_header->length_indicator),
925*ed775ee7SAntonio Huete Jimenez GET_U_1(clnp_header->version),
926*ed775ee7SAntonio Huete Jimenez GET_U_1(clnp_header->lifetime)/2,
927*ed775ee7SAntonio Huete Jimenez (GET_U_1(clnp_header->lifetime)%2)*5,
928*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(clnp_header->segment_length),
929*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(clnp_header->cksum));
93041c99275SPeter Avalos
931*ed775ee7SAntonio Huete Jimenez osi_print_cksum(ndo, optr, GET_BE_U_2(clnp_header->cksum), 7,
932*ed775ee7SAntonio Huete Jimenez GET_U_1(clnp_header->length_indicator));
93341c99275SPeter Avalos
934*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\tFlags [%s]",
935*ed775ee7SAntonio Huete Jimenez bittok2str(clnp_flag_values, "none", clnp_flags));
93641c99275SPeter Avalos
937*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\tsource address (length %u): %s\n\tdest address (length %u): %s",
93841c99275SPeter Avalos source_address_length,
939*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(source_address, source_address_length),
94041c99275SPeter Avalos dest_address_length,
941*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(dest_address, dest_address_length));
94241c99275SPeter Avalos
94341c99275SPeter Avalos if (clnp_flags & CLNP_SEGMENT_PART) {
944*ed775ee7SAntonio Huete Jimenez if (li_remaining < sizeof(struct clnp_segment_header_t)) {
945*ed775ee7SAntonio Huete Jimenez ND_PRINT("li < size of fixed part of CLNP header, addresses, and segment part");
946411677aeSAaron LI return (0);
947411677aeSAaron LI }
94841c99275SPeter Avalos clnp_segment_header = (const struct clnp_segment_header_t *) pptr;
949*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(clnp_segment_header);
950*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u",
951*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(clnp_segment_header->data_unit_id),
952*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(clnp_segment_header->segment_offset),
953*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(clnp_segment_header->total_length));
954*ed775ee7SAntonio Huete Jimenez pptr+=sizeof(struct clnp_segment_header_t);
955*ed775ee7SAntonio Huete Jimenez li_remaining-=sizeof(struct clnp_segment_header_t);
95641c99275SPeter Avalos }
95741c99275SPeter Avalos
95841c99275SPeter Avalos /* now walk the options */
959*ed775ee7SAntonio Huete Jimenez while (li_remaining != 0) {
96041c99275SPeter Avalos u_int op, opli;
961411677aeSAaron LI const uint8_t *tptr;
96241c99275SPeter Avalos
963*ed775ee7SAntonio Huete Jimenez if (li_remaining < 2) {
964*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opts/li");
96541c99275SPeter Avalos return (0);
96641c99275SPeter Avalos }
967*ed775ee7SAntonio Huete Jimenez op = GET_U_1(pptr);
968*ed775ee7SAntonio Huete Jimenez opli = GET_U_1(pptr + 1);
969*ed775ee7SAntonio Huete Jimenez pptr += 2;
970*ed775ee7SAntonio Huete Jimenez li_remaining -= 2;
971*ed775ee7SAntonio Huete Jimenez if (opli > li_remaining) {
972*ed775ee7SAntonio Huete Jimenez ND_PRINT(", opt (%u) too long", op);
97341c99275SPeter Avalos return (0);
97441c99275SPeter Avalos }
975*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, opli);
976*ed775ee7SAntonio Huete Jimenez li_remaining -= opli;
97741c99275SPeter Avalos tptr = pptr;
97841c99275SPeter Avalos tlen = opli;
97941c99275SPeter Avalos
980*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s Option #%u, length %u, value: ",
98141c99275SPeter Avalos tok2str(clnp_option_values,"Unknown",op),
98241c99275SPeter Avalos op,
983*ed775ee7SAntonio Huete Jimenez opli);
98441c99275SPeter Avalos
985411677aeSAaron LI /*
986411677aeSAaron LI * We've already checked that the entire option is present
987*ed775ee7SAntonio Huete Jimenez * in the captured packet with the ND_TCHECK_LEN() call.
988*ed775ee7SAntonio Huete Jimenez * Therefore, we don't need to do ND_TCHECK()/ND_TCHECK_LEN()
989411677aeSAaron LI * checks.
990411677aeSAaron LI * We do, however, need to check tlen, to make sure we
991411677aeSAaron LI * don't run past the end of the option.
992411677aeSAaron LI */
99341c99275SPeter Avalos switch (op) {
99441c99275SPeter Avalos
99541c99275SPeter Avalos
99641c99275SPeter Avalos case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */
99741c99275SPeter Avalos case CLNP_OPTION_SOURCE_ROUTING:
998411677aeSAaron LI if (tlen < 2) {
999*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opt len");
1000411677aeSAaron LI return (0);
1001411677aeSAaron LI }
1002*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s %s",
1003*ed775ee7SAntonio Huete Jimenez tok2str(clnp_option_sr_rr_values,"Unknown",GET_U_1(tptr)),
1004*ed775ee7SAntonio Huete Jimenez tok2str(clnp_option_sr_rr_string_values, "Unknown Option %u", op));
1005*ed775ee7SAntonio Huete Jimenez nsap_offset=GET_U_1(tptr + 1);
100641c99275SPeter Avalos if (nsap_offset == 0) {
1007*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Bad NSAP offset (0)");
100841c99275SPeter Avalos break;
100941c99275SPeter Avalos }
101041c99275SPeter Avalos nsap_offset-=1; /* offset to nsap list */
101141c99275SPeter Avalos if (nsap_offset > tlen) {
1012*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Bad NSAP offset (past end of option)");
101341c99275SPeter Avalos break;
101441c99275SPeter Avalos }
101541c99275SPeter Avalos tptr+=nsap_offset;
101641c99275SPeter Avalos tlen-=nsap_offset;
101741c99275SPeter Avalos while (tlen > 0) {
1018*ed775ee7SAntonio Huete Jimenez source_address_length=GET_U_1(tptr);
101941c99275SPeter Avalos if (tlen < source_address_length+1) {
1020*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NSAP address goes past end of option");
102141c99275SPeter Avalos break;
102241c99275SPeter Avalos }
102341c99275SPeter Avalos if (source_address_length > 0) {
102441c99275SPeter Avalos source_address=(tptr+1);
1025*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NSAP address (length %u): %s",
102641c99275SPeter Avalos source_address_length,
1027*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(source_address, source_address_length));
102841c99275SPeter Avalos }
102941c99275SPeter Avalos tlen-=source_address_length+1;
103041c99275SPeter Avalos }
103141c99275SPeter Avalos break;
103241c99275SPeter Avalos
103341c99275SPeter Avalos case CLNP_OPTION_PRIORITY:
1034411677aeSAaron LI if (tlen < 1) {
1035*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opt len");
1036411677aeSAaron LI return (0);
1037411677aeSAaron LI }
1038*ed775ee7SAntonio Huete Jimenez ND_PRINT("0x%1x", GET_U_1(tptr)&0x0f);
103941c99275SPeter Avalos break;
104041c99275SPeter Avalos
104141c99275SPeter Avalos case CLNP_OPTION_QOS_MAINTENANCE:
1042411677aeSAaron LI if (tlen < 1) {
1043*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opt len");
1044411677aeSAaron LI return (0);
1045411677aeSAaron LI }
1046*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Format Code: %s",
1047*ed775ee7SAntonio Huete Jimenez tok2str(clnp_option_scope_values, "Reserved", GET_U_1(tptr) & CLNP_OPTION_SCOPE_MASK));
104841c99275SPeter Avalos
1049*ed775ee7SAntonio Huete Jimenez if ((GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL)
1050*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t QoS Flags [%s]",
105141c99275SPeter Avalos bittok2str(clnp_option_qos_global_values,
105241c99275SPeter Avalos "none",
1053*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr)&CLNP_OPTION_OPTION_QOS_MASK));
105441c99275SPeter Avalos break;
105541c99275SPeter Avalos
105641c99275SPeter Avalos case CLNP_OPTION_SECURITY:
1057411677aeSAaron LI if (tlen < 2) {
1058*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opt len");
1059411677aeSAaron LI return (0);
1060411677aeSAaron LI }
1061*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Format Code: %s, Security-Level %u",
1062*ed775ee7SAntonio Huete Jimenez tok2str(clnp_option_scope_values,"Reserved",GET_U_1(tptr)&CLNP_OPTION_SCOPE_MASK),
1063*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr + 1));
106441c99275SPeter Avalos break;
106541c99275SPeter Avalos
106641c99275SPeter Avalos case CLNP_OPTION_DISCARD_REASON:
1067411677aeSAaron LI if (tlen < 1) {
1068*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opt len");
1069411677aeSAaron LI return (0);
1070411677aeSAaron LI }
1071*ed775ee7SAntonio Huete Jimenez rfd_error = GET_U_1(tptr);
1072*ed775ee7SAntonio Huete Jimenez rfd_error_major = (rfd_error&0xf0) >> 4;
1073*ed775ee7SAntonio Huete Jimenez rfd_error_minor = rfd_error&0x0f;
1074*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Class: %s Error (0x%01x), %s (0x%01x)",
107541c99275SPeter Avalos tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major),
107641c99275SPeter Avalos rfd_error_major,
107741c99275SPeter Avalos tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor),
1078*ed775ee7SAntonio Huete Jimenez rfd_error_minor);
107941c99275SPeter Avalos break;
108041c99275SPeter Avalos
108141c99275SPeter Avalos case CLNP_OPTION_PADDING:
1082*ed775ee7SAntonio Huete Jimenez ND_PRINT("padding data");
108341c99275SPeter Avalos break;
108441c99275SPeter Avalos
108541c99275SPeter Avalos /*
108641c99275SPeter Avalos * FIXME those are the defined Options that lack a decoder
108741c99275SPeter Avalos * you are welcome to contribute code ;-)
108841c99275SPeter Avalos */
108941c99275SPeter Avalos
109041c99275SPeter Avalos default:
1091411677aeSAaron LI print_unknown_data(ndo, tptr, "\n\t ", opli);
109241c99275SPeter Avalos break;
109341c99275SPeter Avalos }
1094411677aeSAaron LI if (ndo->ndo_vflag > 1)
1095411677aeSAaron LI print_unknown_data(ndo, pptr, "\n\t ", opli);
109641c99275SPeter Avalos pptr += opli;
109741c99275SPeter Avalos }
109841c99275SPeter Avalos
109941c99275SPeter Avalos switch (clnp_pdu_type) {
110041c99275SPeter Avalos
110141c99275SPeter Avalos case CLNP_PDU_ER: /* fall through */
110241c99275SPeter Avalos case CLNP_PDU_ERP:
1103*ed775ee7SAntonio Huete Jimenez if (GET_U_1(pptr) == NLPID_CLNP) {
1104*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t-----original packet-----\n\t");
110541c99275SPeter Avalos /* FIXME recursion protection */
1106*ed775ee7SAntonio Huete Jimenez clnp_print(ndo, pptr, length - li);
110741c99275SPeter Avalos break;
110841c99275SPeter Avalos }
110941c99275SPeter Avalos
1110*ed775ee7SAntonio Huete Jimenez /* The cases above break from the switch block if they see and print
1111*ed775ee7SAntonio Huete Jimenez * a CLNP header in the Data part. For an Error Report PDU this is
1112*ed775ee7SAntonio Huete Jimenez * described in Section 7.9.6 of ITU X.233 (1997 E), also known as
1113*ed775ee7SAntonio Huete Jimenez * ISO/IEC 8473-1:1998(E). It is not clear why in this code the same
1114*ed775ee7SAntonio Huete Jimenez * applies to an Echo Response PDU, as the standard does not specify
1115*ed775ee7SAntonio Huete Jimenez * the contents -- could be a proprietary extension or a bug. In either
1116*ed775ee7SAntonio Huete Jimenez * case, if the Data part does not contain a CLNP header, its structure
1117*ed775ee7SAntonio Huete Jimenez * is considered unknown and the decoding falls through to print the
1118*ed775ee7SAntonio Huete Jimenez * contents as-is.
1119*ed775ee7SAntonio Huete Jimenez */
1120*ed775ee7SAntonio Huete Jimenez ND_FALL_THROUGH;
1121*ed775ee7SAntonio Huete Jimenez
112241c99275SPeter Avalos case CLNP_PDU_DT:
112341c99275SPeter Avalos case CLNP_PDU_MD:
112441c99275SPeter Avalos case CLNP_PDU_ERQ:
112541c99275SPeter Avalos
112641c99275SPeter Avalos default:
112741c99275SPeter Avalos /* dump the PDU specific data */
1128*ed775ee7SAntonio Huete Jimenez if (length > ND_BYTES_BETWEEN(pptr, optr)) {
1129*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t undecoded non-header data, length %u", length-li);
1130*ed775ee7SAntonio Huete Jimenez print_unknown_data(ndo, pptr, "\n\t ", length - ND_BYTES_BETWEEN(pptr, optr));
113141c99275SPeter Avalos }
113241c99275SPeter Avalos }
113341c99275SPeter Avalos
113441c99275SPeter Avalos return (1);
113541c99275SPeter Avalos
113641c99275SPeter Avalos trunc:
1137*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
113841c99275SPeter Avalos return (1);
113941c99275SPeter Avalos
114041c99275SPeter Avalos }
114141c99275SPeter Avalos
114241c99275SPeter Avalos
114341c99275SPeter Avalos #define ESIS_PDU_REDIRECT 6
114441c99275SPeter Avalos #define ESIS_PDU_ESH 2
114541c99275SPeter Avalos #define ESIS_PDU_ISH 4
114641c99275SPeter Avalos
1147411677aeSAaron LI static const struct tok esis_pdu_values[] = {
114841c99275SPeter Avalos { ESIS_PDU_REDIRECT, "redirect"},
114941c99275SPeter Avalos { ESIS_PDU_ESH, "ESH"},
115041c99275SPeter Avalos { ESIS_PDU_ISH, "ISH"},
115141c99275SPeter Avalos { 0, NULL }
115241c99275SPeter Avalos };
115341c99275SPeter Avalos
115441c99275SPeter Avalos struct esis_header_t {
1155*ed775ee7SAntonio Huete Jimenez nd_uint8_t nlpid;
1156*ed775ee7SAntonio Huete Jimenez nd_uint8_t length_indicator;
1157*ed775ee7SAntonio Huete Jimenez nd_uint8_t version;
1158*ed775ee7SAntonio Huete Jimenez nd_byte reserved;
1159*ed775ee7SAntonio Huete Jimenez nd_uint8_t type;
1160*ed775ee7SAntonio Huete Jimenez nd_uint16_t holdtime;
1161*ed775ee7SAntonio Huete Jimenez nd_uint16_t cksum;
116241c99275SPeter Avalos };
116341c99275SPeter Avalos
116441c99275SPeter Avalos static void
esis_print(netdissect_options * ndo,const uint8_t * pptr,u_int length)1165411677aeSAaron LI esis_print(netdissect_options *ndo,
1166411677aeSAaron LI const uint8_t *pptr, u_int length)
116741c99275SPeter Avalos {
1168411677aeSAaron LI const uint8_t *optr;
1169*ed775ee7SAntonio Huete Jimenez u_int li, version, esis_pdu_type, source_address_length, source_address_number;
117041c99275SPeter Avalos const struct esis_header_t *esis_header;
117141c99275SPeter Avalos
1172*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "esis";
1173411677aeSAaron LI if (!ndo->ndo_eflag)
1174*ed775ee7SAntonio Huete Jimenez ND_PRINT("ES-IS");
117541c99275SPeter Avalos
117641c99275SPeter Avalos if (length <= 2) {
1177*ed775ee7SAntonio Huete Jimenez ND_PRINT(ndo->ndo_qflag ? "bad pkt!" : "no header at all!");
117841c99275SPeter Avalos return;
117941c99275SPeter Avalos }
118041c99275SPeter Avalos
118141c99275SPeter Avalos esis_header = (const struct esis_header_t *) pptr;
1182*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(esis_header);
1183*ed775ee7SAntonio Huete Jimenez li = GET_U_1(esis_header->length_indicator);
118441c99275SPeter Avalos optr = pptr;
118541c99275SPeter Avalos
118641c99275SPeter Avalos /*
118741c99275SPeter Avalos * Sanity checking of the header.
118841c99275SPeter Avalos */
118941c99275SPeter Avalos
1190*ed775ee7SAntonio Huete Jimenez if (GET_U_1(esis_header->nlpid) != NLPID_ESIS) {
1191*ed775ee7SAntonio Huete Jimenez ND_PRINT(" nlpid 0x%02x packet not supported",
1192*ed775ee7SAntonio Huete Jimenez GET_U_1(esis_header->nlpid));
119341c99275SPeter Avalos return;
119441c99275SPeter Avalos }
119541c99275SPeter Avalos
1196*ed775ee7SAntonio Huete Jimenez version = GET_U_1(esis_header->version);
1197*ed775ee7SAntonio Huete Jimenez if (version != ESIS_VERSION) {
1198*ed775ee7SAntonio Huete Jimenez ND_PRINT(" version %u packet not supported", version);
119941c99275SPeter Avalos return;
120041c99275SPeter Avalos }
120141c99275SPeter Avalos
120241c99275SPeter Avalos if (li > length) {
1203*ed775ee7SAntonio Huete Jimenez ND_PRINT(" length indicator(%u) > PDU size (%u)!", li, length);
120441c99275SPeter Avalos return;
120541c99275SPeter Avalos }
120641c99275SPeter Avalos
120741c99275SPeter Avalos if (li < sizeof(struct esis_header_t) + 2) {
1208*ed775ee7SAntonio Huete Jimenez ND_PRINT(" length indicator %u < min PDU size:", li);
1209*ed775ee7SAntonio Huete Jimenez while (pptr < ndo->ndo_snapend) {
1210*ed775ee7SAntonio Huete Jimenez ND_PRINT("%02X", GET_U_1(pptr));
1211*ed775ee7SAntonio Huete Jimenez pptr++;
1212*ed775ee7SAntonio Huete Jimenez }
121341c99275SPeter Avalos return;
121441c99275SPeter Avalos }
121541c99275SPeter Avalos
1216*ed775ee7SAntonio Huete Jimenez esis_pdu_type = GET_U_1(esis_header->type) & ESIS_PDU_TYPE_MASK;
121741c99275SPeter Avalos
1218411677aeSAaron LI if (ndo->ndo_vflag < 1) {
1219*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s, length %u",
1220411677aeSAaron LI ndo->ndo_eflag ? "" : ", ",
122141c99275SPeter Avalos tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type),
1222*ed775ee7SAntonio Huete Jimenez length);
122341c99275SPeter Avalos return;
122441c99275SPeter Avalos } else
1225*ed775ee7SAntonio Huete Jimenez ND_PRINT("%slength %u\n\t%s (%u)",
1226411677aeSAaron LI ndo->ndo_eflag ? "" : ", ",
122741c99275SPeter Avalos length,
122841c99275SPeter Avalos tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type),
1229*ed775ee7SAntonio Huete Jimenez esis_pdu_type);
123041c99275SPeter Avalos
1231*ed775ee7SAntonio Huete Jimenez ND_PRINT(", v: %u%s", version, version == ESIS_VERSION ? "" : "unsupported" );
1232*ed775ee7SAntonio Huete Jimenez ND_PRINT(", checksum: 0x%04x", GET_BE_U_2(esis_header->cksum));
1233ea7b4bf5SPeter Avalos
1234*ed775ee7SAntonio Huete Jimenez osi_print_cksum(ndo, pptr, GET_BE_U_2(esis_header->cksum), 7,
1235*ed775ee7SAntonio Huete Jimenez li);
123641c99275SPeter Avalos
1237*ed775ee7SAntonio Huete Jimenez ND_PRINT(", holding time: %us, length indicator: %u",
1238*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(esis_header->holdtime), li);
123941c99275SPeter Avalos
1240411677aeSAaron LI if (ndo->ndo_vflag > 1)
1241411677aeSAaron LI print_unknown_data(ndo, optr, "\n\t", sizeof(struct esis_header_t));
124241c99275SPeter Avalos
124341c99275SPeter Avalos pptr += sizeof(struct esis_header_t);
124441c99275SPeter Avalos li -= sizeof(struct esis_header_t);
124541c99275SPeter Avalos
124641c99275SPeter Avalos switch (esis_pdu_type) {
124741c99275SPeter Avalos case ESIS_PDU_REDIRECT: {
1248411677aeSAaron LI const uint8_t *dst, *snpa, *neta;
124941c99275SPeter Avalos u_int dstl, snpal, netal;
125041c99275SPeter Avalos
1251*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
125241c99275SPeter Avalos if (li < 1) {
1253*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
125441c99275SPeter Avalos return;
125541c99275SPeter Avalos }
1256*ed775ee7SAntonio Huete Jimenez dstl = GET_U_1(pptr);
125741c99275SPeter Avalos pptr++;
125841c99275SPeter Avalos li--;
1259*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, dstl);
126041c99275SPeter Avalos if (li < dstl) {
1261*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
126241c99275SPeter Avalos return;
126341c99275SPeter Avalos }
126441c99275SPeter Avalos dst = pptr;
126541c99275SPeter Avalos pptr += dstl;
126641c99275SPeter Avalos li -= dstl;
1267*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s", GET_ISONSAP_STRING(dst, dstl));
126841c99275SPeter Avalos
1269*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
127041c99275SPeter Avalos if (li < 1) {
1271*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
127241c99275SPeter Avalos return;
127341c99275SPeter Avalos }
1274*ed775ee7SAntonio Huete Jimenez snpal = GET_U_1(pptr);
127541c99275SPeter Avalos pptr++;
127641c99275SPeter Avalos li--;
1277*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, snpal);
127841c99275SPeter Avalos if (li < snpal) {
1279*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
128041c99275SPeter Avalos return;
128141c99275SPeter Avalos }
128241c99275SPeter Avalos snpa = pptr;
128341c99275SPeter Avalos pptr += snpal;
128441c99275SPeter Avalos li -= snpal;
1285*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
128641c99275SPeter Avalos if (li < 1) {
1287*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
128841c99275SPeter Avalos return;
128941c99275SPeter Avalos }
1290*ed775ee7SAntonio Huete Jimenez netal = GET_U_1(pptr);
129141c99275SPeter Avalos pptr++;
1292*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, netal);
129341c99275SPeter Avalos if (li < netal) {
1294*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad redirect/li");
129541c99275SPeter Avalos return;
129641c99275SPeter Avalos }
129741c99275SPeter Avalos neta = pptr;
129841c99275SPeter Avalos pptr += netal;
129941c99275SPeter Avalos li -= netal;
130041c99275SPeter Avalos
1301*ed775ee7SAntonio Huete Jimenez if (snpal == MAC_ADDR_LEN)
1302*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t SNPA (length: %u): %s",
1303411677aeSAaron LI snpal,
1304*ed775ee7SAntonio Huete Jimenez GET_ETHERADDR_STRING(snpa));
130541c99275SPeter Avalos else
1306*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t SNPA (length: %u): %s",
1307411677aeSAaron LI snpal,
1308*ed775ee7SAntonio Huete Jimenez GET_LINKADDR_STRING(snpa, LINKADDR_OTHER, snpal));
1309411677aeSAaron LI if (netal != 0)
1310*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NET (length: %u) %s",
1311411677aeSAaron LI netal,
1312*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(neta, netal));
131341c99275SPeter Avalos break;
131441c99275SPeter Avalos }
131541c99275SPeter Avalos
131641c99275SPeter Avalos case ESIS_PDU_ESH:
1317*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
131841c99275SPeter Avalos if (li < 1) {
1319*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad esh/li");
132041c99275SPeter Avalos return;
132141c99275SPeter Avalos }
1322*ed775ee7SAntonio Huete Jimenez source_address_number = GET_U_1(pptr);
132341c99275SPeter Avalos pptr++;
132441c99275SPeter Avalos li--;
132541c99275SPeter Avalos
1326*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Number of Source Addresses: %u", source_address_number);
132741c99275SPeter Avalos
132841c99275SPeter Avalos while (source_address_number > 0) {
1329*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
133041c99275SPeter Avalos if (li < 1) {
1331*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad esh/li");
133241c99275SPeter Avalos return;
133341c99275SPeter Avalos }
1334*ed775ee7SAntonio Huete Jimenez source_address_length = GET_U_1(pptr);
133541c99275SPeter Avalos pptr++;
133641c99275SPeter Avalos li--;
133741c99275SPeter Avalos
1338*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, source_address_length);
133941c99275SPeter Avalos if (li < source_address_length) {
1340*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad esh/li");
134141c99275SPeter Avalos return;
134241c99275SPeter Avalos }
1343*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NET (length: %u): %s",
134441c99275SPeter Avalos source_address_length,
1345*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(pptr, source_address_length));
134641c99275SPeter Avalos pptr += source_address_length;
134741c99275SPeter Avalos li -= source_address_length;
134841c99275SPeter Avalos source_address_number--;
134941c99275SPeter Avalos }
135041c99275SPeter Avalos
135141c99275SPeter Avalos break;
135241c99275SPeter Avalos
135341c99275SPeter Avalos case ESIS_PDU_ISH: {
1354*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(pptr);
135541c99275SPeter Avalos if (li < 1) {
1356*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad ish/li");
135741c99275SPeter Avalos return;
135841c99275SPeter Avalos }
1359*ed775ee7SAntonio Huete Jimenez source_address_length = GET_U_1(pptr);
136041c99275SPeter Avalos pptr++;
136141c99275SPeter Avalos li--;
1362*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(pptr, source_address_length);
136341c99275SPeter Avalos if (li < source_address_length) {
1364*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad ish/li");
136541c99275SPeter Avalos return;
136641c99275SPeter Avalos }
1367*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NET (length: %u): %s", source_address_length, GET_ISONSAP_STRING(pptr, source_address_length));
136841c99275SPeter Avalos pptr += source_address_length;
136941c99275SPeter Avalos li -= source_address_length;
137041c99275SPeter Avalos break;
137141c99275SPeter Avalos }
137241c99275SPeter Avalos
137341c99275SPeter Avalos default:
1374411677aeSAaron LI if (ndo->ndo_vflag <= 1) {
1375*ed775ee7SAntonio Huete Jimenez /*
1376*ed775ee7SAntonio Huete Jimenez * If there's at least one byte to print, print
1377*ed775ee7SAntonio Huete Jimenez * it/them.
1378*ed775ee7SAntonio Huete Jimenez */
1379*ed775ee7SAntonio Huete Jimenez if (ND_TTEST_LEN(pptr, 1))
1380*ed775ee7SAntonio Huete Jimenez print_unknown_data(ndo, pptr, "\n\t ", ND_BYTES_AVAILABLE_AFTER(pptr));
138141c99275SPeter Avalos }
138241c99275SPeter Avalos return;
138341c99275SPeter Avalos }
138441c99275SPeter Avalos
138541c99275SPeter Avalos /* now walk the options */
138627bfbee1SPeter Avalos while (li != 0) {
138741c99275SPeter Avalos u_int op, opli;
1388411677aeSAaron LI const uint8_t *tptr;
138941c99275SPeter Avalos
139041c99275SPeter Avalos if (li < 2) {
1391*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bad opts/li");
139241c99275SPeter Avalos return;
139341c99275SPeter Avalos }
1394*ed775ee7SAntonio Huete Jimenez op = GET_U_1(pptr);
1395*ed775ee7SAntonio Huete Jimenez opli = GET_U_1(pptr + 1);
1396*ed775ee7SAntonio Huete Jimenez pptr += 2;
139741c99275SPeter Avalos li -= 2;
139841c99275SPeter Avalos if (opli > li) {
1399*ed775ee7SAntonio Huete Jimenez ND_PRINT(", opt (%u) too long", op);
140041c99275SPeter Avalos return;
140141c99275SPeter Avalos }
140241c99275SPeter Avalos li -= opli;
140341c99275SPeter Avalos tptr = pptr;
140441c99275SPeter Avalos
1405*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s Option #%u, length %u, value: ",
140641c99275SPeter Avalos tok2str(esis_option_values,"Unknown",op),
140741c99275SPeter Avalos op,
1408*ed775ee7SAntonio Huete Jimenez opli);
140941c99275SPeter Avalos
141041c99275SPeter Avalos switch (op) {
141141c99275SPeter Avalos
141241c99275SPeter Avalos case ESIS_OPTION_ES_CONF_TIME:
141327bfbee1SPeter Avalos if (opli == 2) {
1414*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(pptr);
1415*ed775ee7SAntonio Huete Jimenez ND_PRINT("%us", GET_BE_U_2(tptr));
141627bfbee1SPeter Avalos } else
1417*ed775ee7SAntonio Huete Jimenez ND_PRINT("(bad length)");
141841c99275SPeter Avalos break;
141941c99275SPeter Avalos
142041c99275SPeter Avalos case ESIS_OPTION_PROTOCOLS:
142141c99275SPeter Avalos while (opli>0) {
1422*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s (0x%02x)",
142341c99275SPeter Avalos tok2str(nlpid_values,
142441c99275SPeter Avalos "unknown",
1425*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr)),
1426*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr));
142741c99275SPeter Avalos if (opli>1) /* further NPLIDs ? - put comma */
1428*ed775ee7SAntonio Huete Jimenez ND_PRINT(", ");
142941c99275SPeter Avalos tptr++;
143041c99275SPeter Avalos opli--;
143141c99275SPeter Avalos }
143241c99275SPeter Avalos break;
143341c99275SPeter Avalos
143441c99275SPeter Avalos /*
143541c99275SPeter Avalos * FIXME those are the defined Options that lack a decoder
143641c99275SPeter Avalos * you are welcome to contribute code ;-)
143741c99275SPeter Avalos */
143841c99275SPeter Avalos
143941c99275SPeter Avalos case ESIS_OPTION_QOS_MAINTENANCE:
144041c99275SPeter Avalos case ESIS_OPTION_SECURITY:
144141c99275SPeter Avalos case ESIS_OPTION_PRIORITY:
144241c99275SPeter Avalos case ESIS_OPTION_ADDRESS_MASK:
144341c99275SPeter Avalos case ESIS_OPTION_SNPA_MASK:
144441c99275SPeter Avalos
144541c99275SPeter Avalos default:
1446411677aeSAaron LI print_unknown_data(ndo, tptr, "\n\t ", opli);
144741c99275SPeter Avalos break;
144841c99275SPeter Avalos }
1449411677aeSAaron LI if (ndo->ndo_vflag > 1)
1450411677aeSAaron LI print_unknown_data(ndo, pptr, "\n\t ", opli);
145141c99275SPeter Avalos pptr += opli;
145241c99275SPeter Avalos }
1453*ed775ee7SAntonio Huete Jimenez return;
1454*ed775ee7SAntonio Huete Jimenez
145541c99275SPeter Avalos trunc:
1456*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
1457411677aeSAaron LI }
1458411677aeSAaron LI
1459411677aeSAaron LI static void
isis_print_mcid(netdissect_options * ndo,const struct isis_spb_mcid * mcid)1460411677aeSAaron LI isis_print_mcid(netdissect_options *ndo,
1461411677aeSAaron LI const struct isis_spb_mcid *mcid)
1462411677aeSAaron LI {
1463411677aeSAaron LI int i;
1464411677aeSAaron LI
1465*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(mcid);
1466*ed775ee7SAntonio Huete Jimenez ND_PRINT("ID: %u, Name: ", GET_U_1(mcid->format_id));
1467411677aeSAaron LI
1468*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, mcid->name, sizeof(mcid->name));
1469411677aeSAaron LI
1470*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Lvl: %u", GET_BE_U_2(mcid->revision_lvl));
1471411677aeSAaron LI
1472*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Digest: ");
1473411677aeSAaron LI
1474411677aeSAaron LI for(i=0;i<16;i++)
1475*ed775ee7SAntonio Huete Jimenez ND_PRINT("%.2x ", mcid->digest[i]);
1476*ed775ee7SAntonio Huete Jimenez return;
1477411677aeSAaron LI
1478411677aeSAaron LI trunc:
1479*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
1480411677aeSAaron LI }
1481411677aeSAaron LI
1482411677aeSAaron LI static int
isis_print_mt_port_cap_subtlv(netdissect_options * ndo,const uint8_t * tptr,u_int len)1483411677aeSAaron LI isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
1484*ed775ee7SAntonio Huete Jimenez const uint8_t *tptr, u_int len)
1485411677aeSAaron LI {
1486*ed775ee7SAntonio Huete Jimenez u_int stlv_type, stlv_len;
1487411677aeSAaron LI const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
1488411677aeSAaron LI int i;
1489411677aeSAaron LI
1490411677aeSAaron LI while (len > 2)
1491411677aeSAaron LI {
1492*ed775ee7SAntonio Huete Jimenez stlv_type = GET_U_1(tptr);
1493*ed775ee7SAntonio Huete Jimenez stlv_len = GET_U_1(tptr + 1);
1494411677aeSAaron LI
1495411677aeSAaron LI /* first lets see if we know the subTLVs name*/
1496*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s subTLV #%u, length: %u",
1497411677aeSAaron LI tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type),
1498411677aeSAaron LI stlv_type,
1499*ed775ee7SAntonio Huete Jimenez stlv_len);
1500411677aeSAaron LI
1501*ed775ee7SAntonio Huete Jimenez tptr += 2;
1502411677aeSAaron LI /*len -= TLV_TYPE_LEN_OFFSET;*/
1503*ed775ee7SAntonio Huete Jimenez len -= 2;
1504411677aeSAaron LI
1505411677aeSAaron LI /* Make sure the subTLV fits within the space left */
1506411677aeSAaron LI if (len < stlv_len)
1507*ed775ee7SAntonio Huete Jimenez goto subtlv_too_long;
1508411677aeSAaron LI /* Make sure the entire subTLV is in the captured data */
1509*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, stlv_len);
1510411677aeSAaron LI
1511411677aeSAaron LI switch (stlv_type)
1512411677aeSAaron LI {
1513411677aeSAaron LI case ISIS_SUBTLV_SPB_MCID:
1514411677aeSAaron LI {
1515411677aeSAaron LI if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
1516*ed775ee7SAntonio Huete Jimenez goto subtlv_too_short;
1517411677aeSAaron LI
1518411677aeSAaron LI subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
1519411677aeSAaron LI
1520*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t MCID: ");
1521411677aeSAaron LI isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid));
1522411677aeSAaron LI
1523411677aeSAaron LI /*tptr += SPB_MCID_MIN_LEN;
1524411677aeSAaron LI len -= SPB_MCID_MIN_LEN; */
1525411677aeSAaron LI
1526*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t AUX-MCID: ");
1527411677aeSAaron LI isis_print_mcid(ndo, &(subtlv_spb_mcid->aux_mcid));
1528411677aeSAaron LI
1529411677aeSAaron LI /*tptr += SPB_MCID_MIN_LEN;
1530411677aeSAaron LI len -= SPB_MCID_MIN_LEN; */
1531*ed775ee7SAntonio Huete Jimenez tptr += ISIS_SUBTLV_SPB_MCID_MIN_LEN;
1532*ed775ee7SAntonio Huete Jimenez len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN;
1533*ed775ee7SAntonio Huete Jimenez stlv_len -= ISIS_SUBTLV_SPB_MCID_MIN_LEN;
1534411677aeSAaron LI
1535411677aeSAaron LI break;
1536411677aeSAaron LI }
1537411677aeSAaron LI
1538411677aeSAaron LI case ISIS_SUBTLV_SPB_DIGEST:
1539411677aeSAaron LI {
1540411677aeSAaron LI if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
1541*ed775ee7SAntonio Huete Jimenez goto subtlv_too_short;
1542411677aeSAaron LI
1543*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t RES: %u V: %u A: %u D: %u",
1544*ed775ee7SAntonio Huete Jimenez (GET_U_1(tptr) >> 5),
1545*ed775ee7SAntonio Huete Jimenez ((GET_U_1(tptr) >> 4) & 0x01),
1546*ed775ee7SAntonio Huete Jimenez ((GET_U_1(tptr) >> 2) & 0x03),
1547*ed775ee7SAntonio Huete Jimenez (GET_U_1(tptr) & 0x03));
1548411677aeSAaron LI
1549411677aeSAaron LI tptr++;
1550411677aeSAaron LI
1551*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Digest: ");
1552411677aeSAaron LI
1553411677aeSAaron LI for(i=1;i<=8; i++)
1554411677aeSAaron LI {
1555*ed775ee7SAntonio Huete Jimenez ND_PRINT("%08x ", GET_BE_U_4(tptr));
1556411677aeSAaron LI if (i%4 == 0 && i != 8)
1557*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t ");
1558*ed775ee7SAntonio Huete Jimenez tptr += 4;
1559411677aeSAaron LI }
1560411677aeSAaron LI
1561*ed775ee7SAntonio Huete Jimenez len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
1562*ed775ee7SAntonio Huete Jimenez stlv_len -= ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
1563411677aeSAaron LI
1564411677aeSAaron LI break;
1565411677aeSAaron LI }
1566411677aeSAaron LI
1567411677aeSAaron LI case ISIS_SUBTLV_SPB_BVID:
1568411677aeSAaron LI {
1569*ed775ee7SAntonio Huete Jimenez while (stlv_len != 0)
1570411677aeSAaron LI {
1571*ed775ee7SAntonio Huete Jimenez if (stlv_len < 4)
1572*ed775ee7SAntonio Huete Jimenez goto subtlv_too_short;
1573*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t ECT: %08x",
1574*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tptr));
1575411677aeSAaron LI
1576*ed775ee7SAntonio Huete Jimenez tptr += 4;
1577*ed775ee7SAntonio Huete Jimenez len -= 4;
1578*ed775ee7SAntonio Huete Jimenez stlv_len -= 4;
1579411677aeSAaron LI
1580*ed775ee7SAntonio Huete Jimenez if (stlv_len < 2)
1581*ed775ee7SAntonio Huete Jimenez goto subtlv_too_short;
1582*ed775ee7SAntonio Huete Jimenez ND_PRINT(" BVID: %u, U:%01x M:%01x ",
1583*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 4) ,
1584*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 3) & 0x01,
1585*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 2) & 0x01);
1586411677aeSAaron LI
1587*ed775ee7SAntonio Huete Jimenez tptr += 2;
1588*ed775ee7SAntonio Huete Jimenez len -= 2;
1589*ed775ee7SAntonio Huete Jimenez stlv_len -= 2;
1590411677aeSAaron LI }
1591411677aeSAaron LI
1592411677aeSAaron LI break;
1593411677aeSAaron LI }
1594411677aeSAaron LI
1595411677aeSAaron LI default:
1596411677aeSAaron LI break;
1597411677aeSAaron LI }
1598411677aeSAaron LI tptr += stlv_len;
1599411677aeSAaron LI len -= stlv_len;
1600411677aeSAaron LI }
1601*ed775ee7SAntonio Huete Jimenez return (0);
1602411677aeSAaron LI
1603411677aeSAaron LI trunc:
1604*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
1605*ed775ee7SAntonio Huete Jimenez return (1);
1606*ed775ee7SAntonio Huete Jimenez
1607*ed775ee7SAntonio Huete Jimenez subtlv_too_long:
1608*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (> containing TLV length)");
1609*ed775ee7SAntonio Huete Jimenez return (1);
1610*ed775ee7SAntonio Huete Jimenez
1611*ed775ee7SAntonio Huete Jimenez subtlv_too_short:
1612*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (too short)");
1613411677aeSAaron LI return (1);
1614411677aeSAaron LI }
1615411677aeSAaron LI
1616411677aeSAaron LI static int
isis_print_mt_capability_subtlv(netdissect_options * ndo,const uint8_t * tptr,u_int len)1617411677aeSAaron LI isis_print_mt_capability_subtlv(netdissect_options *ndo,
1618*ed775ee7SAntonio Huete Jimenez const uint8_t *tptr, u_int len)
1619411677aeSAaron LI {
1620*ed775ee7SAntonio Huete Jimenez u_int stlv_type, stlv_len, treecount;
1621411677aeSAaron LI
1622411677aeSAaron LI while (len > 2)
1623411677aeSAaron LI {
1624*ed775ee7SAntonio Huete Jimenez stlv_type = GET_U_1(tptr);
1625*ed775ee7SAntonio Huete Jimenez stlv_len = GET_U_1(tptr + 1);
1626*ed775ee7SAntonio Huete Jimenez tptr += 2;
1627*ed775ee7SAntonio Huete Jimenez len -= 2;
1628411677aeSAaron LI
1629411677aeSAaron LI /* first lets see if we know the subTLVs name*/
1630*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s subTLV #%u, length: %u",
1631411677aeSAaron LI tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type),
1632411677aeSAaron LI stlv_type,
1633*ed775ee7SAntonio Huete Jimenez stlv_len);
1634411677aeSAaron LI
1635411677aeSAaron LI /* Make sure the subTLV fits within the space left */
1636411677aeSAaron LI if (len < stlv_len)
1637*ed775ee7SAntonio Huete Jimenez goto subtlv_too_long;
1638411677aeSAaron LI /* Make sure the entire subTLV is in the captured data */
1639*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, stlv_len);
1640411677aeSAaron LI
1641411677aeSAaron LI switch (stlv_type)
1642411677aeSAaron LI {
1643411677aeSAaron LI case ISIS_SUBTLV_SPB_INSTANCE:
1644411677aeSAaron LI if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
1645*ed775ee7SAntonio Huete Jimenez goto subtlv_too_short;
1646411677aeSAaron LI
1647*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t CIST Root-ID: %08x", GET_BE_U_4(tptr));
1648*ed775ee7SAntonio Huete Jimenez tptr += 4;
1649*ed775ee7SAntonio Huete Jimenez ND_PRINT(" %08x", GET_BE_U_4(tptr));
1650*ed775ee7SAntonio Huete Jimenez tptr += 4;
1651*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Path Cost: %08x", GET_BE_U_4(tptr));
1652*ed775ee7SAntonio Huete Jimenez tptr += 4;
1653*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Prio: %u", GET_BE_U_2(tptr));
1654*ed775ee7SAntonio Huete Jimenez tptr += 2;
1655*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t RES: %u",
1656*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr) >> 5);
1657*ed775ee7SAntonio Huete Jimenez ND_PRINT(", V: %u",
1658*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 4) & 0x0001);
1659*ed775ee7SAntonio Huete Jimenez ND_PRINT(", SPSource-ID: %u",
1660*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(tptr) & 0x000fffff));
1661*ed775ee7SAntonio Huete Jimenez tptr += 4;
1662*ed775ee7SAntonio Huete Jimenez ND_PRINT(", No of Trees: %x", GET_U_1(tptr));
1663411677aeSAaron LI
1664*ed775ee7SAntonio Huete Jimenez treecount = GET_U_1(tptr);
1665*ed775ee7SAntonio Huete Jimenez tptr++;
1666411677aeSAaron LI
1667*ed775ee7SAntonio Huete Jimenez len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
1668*ed775ee7SAntonio Huete Jimenez stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
1669411677aeSAaron LI
1670*ed775ee7SAntonio Huete Jimenez while (treecount)
1671411677aeSAaron LI {
1672411677aeSAaron LI if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
1673411677aeSAaron LI goto trunc;
1674411677aeSAaron LI
1675*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t U:%u, M:%u, A:%u, RES:%u",
1676*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr) >> 7,
1677*ed775ee7SAntonio Huete Jimenez (GET_U_1(tptr) >> 6) & 0x01,
1678*ed775ee7SAntonio Huete Jimenez (GET_U_1(tptr) >> 5) & 0x01,
1679*ed775ee7SAntonio Huete Jimenez (GET_U_1(tptr) & 0x1f));
1680411677aeSAaron LI
1681411677aeSAaron LI tptr++;
1682411677aeSAaron LI
1683*ed775ee7SAntonio Huete Jimenez ND_PRINT(", ECT: %08x", GET_BE_U_4(tptr));
1684411677aeSAaron LI
1685*ed775ee7SAntonio Huete Jimenez tptr += 4;
1686411677aeSAaron LI
1687*ed775ee7SAntonio Huete Jimenez ND_PRINT(", BVID: %u, SPVID: %u",
1688*ed775ee7SAntonio Huete Jimenez (GET_BE_U_3(tptr) >> 12) & 0x000fff,
1689*ed775ee7SAntonio Huete Jimenez GET_BE_U_3(tptr) & 0x000fff);
1690411677aeSAaron LI
1691*ed775ee7SAntonio Huete Jimenez tptr += 3;
1692*ed775ee7SAntonio Huete Jimenez len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
1693*ed775ee7SAntonio Huete Jimenez stlv_len -= ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
1694*ed775ee7SAntonio Huete Jimenez treecount--;
1695411677aeSAaron LI }
1696411677aeSAaron LI
1697411677aeSAaron LI break;
1698411677aeSAaron LI
1699411677aeSAaron LI case ISIS_SUBTLV_SPBM_SI:
1700411677aeSAaron LI if (stlv_len < 8)
1701411677aeSAaron LI goto trunc;
1702411677aeSAaron LI
1703*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t BMAC: %08x", GET_BE_U_4(tptr));
1704*ed775ee7SAntonio Huete Jimenez tptr += 4;
1705*ed775ee7SAntonio Huete Jimenez ND_PRINT("%04x", GET_BE_U_2(tptr));
1706*ed775ee7SAntonio Huete Jimenez tptr += 2;
1707411677aeSAaron LI
1708*ed775ee7SAntonio Huete Jimenez ND_PRINT(", RES: %u, VID: %u", GET_BE_U_2(tptr) >> 12,
1709*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr)) & 0x0fff);
1710411677aeSAaron LI
1711*ed775ee7SAntonio Huete Jimenez tptr += 2;
1712*ed775ee7SAntonio Huete Jimenez len -= 8;
1713*ed775ee7SAntonio Huete Jimenez stlv_len -= 8;
1714411677aeSAaron LI
1715411677aeSAaron LI while (stlv_len >= 4) {
1716*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t T: %u, R: %u, RES: %u, ISID: %u",
1717*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(tptr) >> 31),
1718*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(tptr) >> 30) & 0x01,
1719*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(tptr) >> 24) & 0x03f,
1720*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(tptr)) & 0x0ffffff);
1721411677aeSAaron LI
1722*ed775ee7SAntonio Huete Jimenez tptr += 4;
1723*ed775ee7SAntonio Huete Jimenez len -= 4;
1724*ed775ee7SAntonio Huete Jimenez stlv_len -= 4;
1725411677aeSAaron LI }
1726411677aeSAaron LI
1727411677aeSAaron LI break;
1728411677aeSAaron LI
1729411677aeSAaron LI default:
1730411677aeSAaron LI break;
1731411677aeSAaron LI }
1732411677aeSAaron LI tptr += stlv_len;
1733411677aeSAaron LI len -= stlv_len;
1734411677aeSAaron LI }
1735*ed775ee7SAntonio Huete Jimenez return (0);
1736411677aeSAaron LI
1737411677aeSAaron LI trunc:
1738*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
1739*ed775ee7SAntonio Huete Jimenez return (1);
1740*ed775ee7SAntonio Huete Jimenez
1741*ed775ee7SAntonio Huete Jimenez subtlv_too_long:
1742*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (> containing TLV length)");
1743*ed775ee7SAntonio Huete Jimenez return (1);
1744*ed775ee7SAntonio Huete Jimenez
1745*ed775ee7SAntonio Huete Jimenez subtlv_too_short:
1746*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (too short)");
1747411677aeSAaron LI return (1);
174841c99275SPeter Avalos }
174941c99275SPeter Avalos
175041c99275SPeter Avalos /* shared routine for printing system, node and lsp-ids */
175141c99275SPeter Avalos static char *
isis_print_id(netdissect_options * ndo,const uint8_t * cp,u_int id_len)1752*ed775ee7SAntonio Huete Jimenez isis_print_id(netdissect_options *ndo, const uint8_t *cp, u_int id_len)
175341c99275SPeter Avalos {
1754*ed775ee7SAntonio Huete Jimenez u_int i;
175541c99275SPeter Avalos static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
175641c99275SPeter Avalos char *pos = id;
1757*ed775ee7SAntonio Huete Jimenez u_int sysid_len;
175841c99275SPeter Avalos
1759411677aeSAaron LI sysid_len = SYSTEM_ID_LEN;
1760411677aeSAaron LI if (sysid_len > id_len)
1761411677aeSAaron LI sysid_len = id_len;
1762411677aeSAaron LI for (i = 1; i <= sysid_len; i++) {
1763*ed775ee7SAntonio Huete Jimenez snprintf(pos, sizeof(id) - (pos - id), "%02x", GET_U_1(cp));
1764*ed775ee7SAntonio Huete Jimenez cp++;
176541c99275SPeter Avalos pos += strlen(pos);
176641c99275SPeter Avalos if (i == 2 || i == 4)
176741c99275SPeter Avalos *pos++ = '.';
176841c99275SPeter Avalos }
176941c99275SPeter Avalos if (id_len >= NODE_ID_LEN) {
1770*ed775ee7SAntonio Huete Jimenez snprintf(pos, sizeof(id) - (pos - id), ".%02x", GET_U_1(cp));
1771*ed775ee7SAntonio Huete Jimenez cp++;
177241c99275SPeter Avalos pos += strlen(pos);
177341c99275SPeter Avalos }
177441c99275SPeter Avalos if (id_len == LSP_ID_LEN)
1775*ed775ee7SAntonio Huete Jimenez snprintf(pos, sizeof(id) - (pos - id), "-%02x", GET_U_1(cp));
177641c99275SPeter Avalos return (id);
177741c99275SPeter Avalos }
177841c99275SPeter Avalos
177941c99275SPeter Avalos /* print the 4-byte metric block which is common found in the old-style TLVs */
178041c99275SPeter Avalos static int
isis_print_metric_block(netdissect_options * ndo,const struct isis_metric_block * isis_metric_block)1781411677aeSAaron LI isis_print_metric_block(netdissect_options *ndo,
1782411677aeSAaron LI const struct isis_metric_block *isis_metric_block)
178341c99275SPeter Avalos {
1784*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Default Metric: %u, %s",
178541c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default),
1786*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal");
178741c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay))
1788*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t Delay Metric: %u, %s",
178941c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay),
1790*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal");
179141c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense))
1792*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t Expense Metric: %u, %s",
179341c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense),
1794*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal");
179541c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error))
1796*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t Error Metric: %u, %s",
179741c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error),
1798*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal");
179941c99275SPeter Avalos
180041c99275SPeter Avalos return(1); /* everything is ok */
180141c99275SPeter Avalos }
180241c99275SPeter Avalos
180341c99275SPeter Avalos static int
isis_print_tlv_ip_reach(netdissect_options * ndo,const uint8_t * cp,const char * ident,u_int length)1804411677aeSAaron LI isis_print_tlv_ip_reach(netdissect_options *ndo,
1805*ed775ee7SAntonio Huete Jimenez const uint8_t *cp, const char *ident, u_int length)
180641c99275SPeter Avalos {
180741c99275SPeter Avalos int prefix_len;
180841c99275SPeter Avalos const struct isis_tlv_ip_reach *tlv_ip_reach;
180941c99275SPeter Avalos
181041c99275SPeter Avalos tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
181141c99275SPeter Avalos
181241c99275SPeter Avalos while (length > 0) {
181341c99275SPeter Avalos if ((size_t)length < sizeof(*tlv_ip_reach)) {
1814*ed775ee7SAntonio Huete Jimenez ND_PRINT("short IPv4 Reachability (%u vs %zu)",
181541c99275SPeter Avalos length,
1816*ed775ee7SAntonio Huete Jimenez sizeof(*tlv_ip_reach));
181741c99275SPeter Avalos return (0);
181841c99275SPeter Avalos }
181941c99275SPeter Avalos
1820*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(tlv_ip_reach);
182141c99275SPeter Avalos
1822*ed775ee7SAntonio Huete Jimenez prefix_len = mask2plen(GET_IPV4_TO_HOST_ORDER(tlv_ip_reach->mask));
182341c99275SPeter Avalos
182441c99275SPeter Avalos if (prefix_len == -1)
1825*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv4 prefix: %s mask %s",
182641c99275SPeter Avalos ident,
1827*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(tlv_ip_reach->prefix),
1828*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(tlv_ip_reach->mask));
182941c99275SPeter Avalos else
1830*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv4 prefix: %15s/%u",
183141c99275SPeter Avalos ident,
1832*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(tlv_ip_reach->prefix),
1833*ed775ee7SAntonio Huete Jimenez prefix_len);
183441c99275SPeter Avalos
1835*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Distribution: %s, Metric: %u, %s",
183641c99275SPeter Avalos ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up",
183741c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default),
1838*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal");
183941c99275SPeter Avalos
184041c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay))
1841*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Delay Metric: %u, %s",
184241c99275SPeter Avalos ident,
184341c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay),
1844*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal");
184541c99275SPeter Avalos
184641c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense))
1847*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Expense Metric: %u, %s",
184841c99275SPeter Avalos ident,
184941c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense),
1850*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal");
185141c99275SPeter Avalos
185241c99275SPeter Avalos if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error))
1853*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Error Metric: %u, %s",
185441c99275SPeter Avalos ident,
185541c99275SPeter Avalos ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error),
1856*ed775ee7SAntonio Huete Jimenez ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal");
185741c99275SPeter Avalos
185841c99275SPeter Avalos length -= sizeof(struct isis_tlv_ip_reach);
185941c99275SPeter Avalos tlv_ip_reach++;
186041c99275SPeter Avalos }
186141c99275SPeter Avalos return (1);
1862*ed775ee7SAntonio Huete Jimenez trunc:
1863*ed775ee7SAntonio Huete Jimenez return 0;
186441c99275SPeter Avalos }
186541c99275SPeter Avalos
186641c99275SPeter Avalos /*
186741c99275SPeter Avalos * this is the common IP-REACH subTLV decoder it is called
186841c99275SPeter Avalos * from various EXTD-IP REACH TLVs (135,235,236,237)
186941c99275SPeter Avalos */
187041c99275SPeter Avalos
187141c99275SPeter Avalos static int
isis_print_ip_reach_subtlv(netdissect_options * ndo,const uint8_t * tptr,u_int subt,u_int subl,const char * ident)1872411677aeSAaron LI isis_print_ip_reach_subtlv(netdissect_options *ndo,
1873*ed775ee7SAntonio Huete Jimenez const uint8_t *tptr, u_int subt, u_int subl,
1874411677aeSAaron LI const char *ident)
1875411677aeSAaron LI {
187641c99275SPeter Avalos /* first lets see if we know the subTLVs name*/
1877*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s subTLV #%u, length: %u",
1878411677aeSAaron LI ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt),
1879*ed775ee7SAntonio Huete Jimenez subt, subl);
188041c99275SPeter Avalos
1881*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, subl);
188241c99275SPeter Avalos
188341c99275SPeter Avalos switch(subt) {
188441c99275SPeter Avalos case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */
188541c99275SPeter Avalos case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32:
188641c99275SPeter Avalos while (subl >= 4) {
1887*ed775ee7SAntonio Huete Jimenez ND_PRINT(", 0x%08x (=%u)",
1888*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tptr),
1889*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tptr));
189041c99275SPeter Avalos tptr+=4;
189141c99275SPeter Avalos subl-=4;
189241c99275SPeter Avalos }
189341c99275SPeter Avalos break;
189441c99275SPeter Avalos case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64:
189541c99275SPeter Avalos while (subl >= 8) {
1896*ed775ee7SAntonio Huete Jimenez ND_PRINT(", 0x%08x%08x",
1897*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tptr),
1898*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tptr + 4));
189941c99275SPeter Avalos tptr+=8;
190041c99275SPeter Avalos subl-=8;
190141c99275SPeter Avalos }
190241c99275SPeter Avalos break;
1903*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID:
1904411677aeSAaron LI {
1905*ed775ee7SAntonio Huete Jimenez uint8_t algo, flags;
1906*ed775ee7SAntonio Huete Jimenez uint32_t sid;
190741c99275SPeter Avalos
1908*ed775ee7SAntonio Huete Jimenez flags = GET_U_1(tptr);
1909*ed775ee7SAntonio Huete Jimenez algo = GET_U_1(tptr+1);
191041c99275SPeter Avalos
1911*ed775ee7SAntonio Huete Jimenez if (flags & ISIS_PREFIX_SID_FLAG_V) {
1912*ed775ee7SAntonio Huete Jimenez if (subl < 5)
1913*ed775ee7SAntonio Huete Jimenez goto trunc;
1914*ed775ee7SAntonio Huete Jimenez sid = GET_BE_U_3(tptr+2);
1915*ed775ee7SAntonio Huete Jimenez tptr+=5;
1916*ed775ee7SAntonio Huete Jimenez subl-=5;
1917*ed775ee7SAntonio Huete Jimenez } else {
1918411677aeSAaron LI if (subl < 6)
1919*ed775ee7SAntonio Huete Jimenez goto trunc;
1920*ed775ee7SAntonio Huete Jimenez sid = GET_BE_U_4(tptr+2);
1921*ed775ee7SAntonio Huete Jimenez tptr+=6;
1922*ed775ee7SAntonio Huete Jimenez subl-=6;
192341c99275SPeter Avalos }
1924*ed775ee7SAntonio Huete Jimenez
1925*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Flags [%s], Algo %s (%u), %s %u",
1926*ed775ee7SAntonio Huete Jimenez bittok2str(prefix_sid_flag_values, "None", flags),
1927*ed775ee7SAntonio Huete Jimenez tok2str(prefix_sid_algo_values, "Unknown", algo), algo,
1928*ed775ee7SAntonio Huete Jimenez flags & ISIS_PREFIX_SID_FLAG_V ? "label" : "index",
1929*ed775ee7SAntonio Huete Jimenez sid);
1930ea7b4bf5SPeter Avalos }
193141c99275SPeter Avalos break;
193241c99275SPeter Avalos default:
1933411677aeSAaron LI if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl))
193441c99275SPeter Avalos return(0);
193541c99275SPeter Avalos break;
193641c99275SPeter Avalos }
193741c99275SPeter Avalos return(1);
193841c99275SPeter Avalos
1939411677aeSAaron LI trunc:
1940*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
194141c99275SPeter Avalos return(0);
194241c99275SPeter Avalos }
194341c99275SPeter Avalos
194441c99275SPeter Avalos /*
194541c99275SPeter Avalos * this is the common IS-REACH decoder it is called
194641c99275SPeter Avalos * from various EXTD-IS REACH style TLVs (22,24,222)
194741c99275SPeter Avalos */
194841c99275SPeter Avalos
194941c99275SPeter Avalos static int
isis_print_ext_is_reach(netdissect_options * ndo,const uint8_t * tptr,const char * ident,u_int tlv_type,u_int tlv_remaining)1950411677aeSAaron LI isis_print_ext_is_reach(netdissect_options *ndo,
1951*ed775ee7SAntonio Huete Jimenez const uint8_t *tptr, const char *ident, u_int tlv_type,
1952*ed775ee7SAntonio Huete Jimenez u_int tlv_remaining)
1953411677aeSAaron LI {
195441c99275SPeter Avalos char ident_buffer[20];
1955*ed775ee7SAntonio Huete Jimenez u_int subtlv_type,subtlv_len,subtlv_sum_len;
195641c99275SPeter Avalos int proc_bytes = 0; /* how many bytes did we process ? */
1957*ed775ee7SAntonio Huete Jimenez u_int te_class,priority_level,gmpls_switch_cap;
1958*ed775ee7SAntonio Huete Jimenez union { /* int to float conversion buffer for several subTLVs */
1959*ed775ee7SAntonio Huete Jimenez float f;
1960*ed775ee7SAntonio Huete Jimenez uint32_t i;
1961*ed775ee7SAntonio Huete Jimenez } bw;
196241c99275SPeter Avalos
1963*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, NODE_ID_LEN);
1964*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < NODE_ID_LEN)
196541c99275SPeter Avalos return(0);
196641c99275SPeter Avalos
1967*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIS Neighbor: %s", ident, isis_print_id(ndo, tptr, NODE_ID_LEN));
1968*ed775ee7SAntonio Huete Jimenez tptr+=NODE_ID_LEN;
1969*ed775ee7SAntonio Huete Jimenez tlv_remaining-=NODE_ID_LEN;
1970*ed775ee7SAntonio Huete Jimenez proc_bytes+=NODE_ID_LEN;
197141c99275SPeter Avalos
197241c99275SPeter Avalos if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */
1973*ed775ee7SAntonio Huete Jimenez ND_TCHECK_3(tptr);
1974*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < 3)
197541c99275SPeter Avalos return(0);
1976*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Metric: %u", GET_BE_U_3(tptr));
197741c99275SPeter Avalos tptr+=3;
1978*ed775ee7SAntonio Huete Jimenez tlv_remaining-=3;
1979*ed775ee7SAntonio Huete Jimenez proc_bytes+=3;
198041c99275SPeter Avalos }
198141c99275SPeter Avalos
1982*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(tptr);
1983*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < 1)
198441c99275SPeter Avalos return(0);
1985*ed775ee7SAntonio Huete Jimenez subtlv_sum_len=GET_U_1(tptr); /* read out subTLV length */
1986*ed775ee7SAntonio Huete Jimenez tptr++;
1987*ed775ee7SAntonio Huete Jimenez tlv_remaining--;
1988*ed775ee7SAntonio Huete Jimenez proc_bytes++;
1989*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %ssub-TLVs present",subtlv_sum_len ? "" : "no ");
199041c99275SPeter Avalos if (subtlv_sum_len) {
1991*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (%u)", subtlv_sum_len);
1992411677aeSAaron LI /* prepend the indent string */
199341c99275SPeter Avalos snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
1994*ed775ee7SAntonio Huete Jimenez ident = ident_buffer;
1995*ed775ee7SAntonio Huete Jimenez while (subtlv_sum_len != 0) {
1996*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(tptr);
1997*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < 2) {
1998*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sRemaining data in TLV shorter than a subTLV header",ident);
1999*ed775ee7SAntonio Huete Jimenez proc_bytes += tlv_remaining;
2000*ed775ee7SAntonio Huete Jimenez break;
2001*ed775ee7SAntonio Huete Jimenez }
2002*ed775ee7SAntonio Huete Jimenez if (subtlv_sum_len < 2) {
2003*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sRemaining data in subTLVs shorter than a subTLV header",ident);
2004*ed775ee7SAntonio Huete Jimenez proc_bytes += subtlv_sum_len;
2005*ed775ee7SAntonio Huete Jimenez break;
2006*ed775ee7SAntonio Huete Jimenez }
2007*ed775ee7SAntonio Huete Jimenez subtlv_type=GET_U_1(tptr);
2008*ed775ee7SAntonio Huete Jimenez subtlv_len=GET_U_1(tptr + 1);
2009*ed775ee7SAntonio Huete Jimenez tptr += 2;
2010*ed775ee7SAntonio Huete Jimenez tlv_remaining -= 2;
2011*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 2;
2012*ed775ee7SAntonio Huete Jimenez proc_bytes += 2;
2013*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s subTLV #%u, length: %u",
2014*ed775ee7SAntonio Huete Jimenez ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subtlv_type),
2015*ed775ee7SAntonio Huete Jimenez subtlv_type, subtlv_len);
2016*ed775ee7SAntonio Huete Jimenez
2017*ed775ee7SAntonio Huete Jimenez if (subtlv_sum_len < subtlv_len) {
2018*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (remaining data in subTLVs shorter than the current subTLV)");
2019*ed775ee7SAntonio Huete Jimenez proc_bytes += subtlv_sum_len;
2020*ed775ee7SAntonio Huete Jimenez break;
2021*ed775ee7SAntonio Huete Jimenez }
2022*ed775ee7SAntonio Huete Jimenez
2023*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < subtlv_len) {
2024*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (> remaining tlv length)");
2025*ed775ee7SAntonio Huete Jimenez proc_bytes += tlv_remaining;
2026*ed775ee7SAntonio Huete Jimenez break;
2027*ed775ee7SAntonio Huete Jimenez }
2028*ed775ee7SAntonio Huete Jimenez
2029*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, subtlv_len);
2030*ed775ee7SAntonio Huete Jimenez
2031*ed775ee7SAntonio Huete Jimenez switch(subtlv_type) {
2032*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
2033*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID:
2034*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
2035*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 4) {
2036*ed775ee7SAntonio Huete Jimenez ND_PRINT(", 0x%08x", GET_BE_U_4(tptr));
2037*ed775ee7SAntonio Huete Jimenez if (subtlv_len == 8) /* rfc4205 */
2038*ed775ee7SAntonio Huete Jimenez ND_PRINT(", 0x%08x", GET_BE_U_4(tptr + 4));
2039*ed775ee7SAntonio Huete Jimenez }
2040*ed775ee7SAntonio Huete Jimenez break;
2041*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
2042*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
2043*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= sizeof(nd_ipv4))
2044*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %s", GET_IPADDR_STRING(tptr));
2045*ed775ee7SAntonio Huete Jimenez break;
2046*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
2047*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW:
2048*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 4) {
2049*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2050*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %.3f Mbps", bw.f * 8 / 1000000);
2051*ed775ee7SAntonio Huete Jimenez }
2052*ed775ee7SAntonio Huete Jimenez break;
2053*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
2054*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 32) {
2055*ed775ee7SAntonio Huete Jimenez for (te_class = 0; te_class < 8; te_class++) {
2056*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2057*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s TE-Class %u: %.3f Mbps",
2058*ed775ee7SAntonio Huete Jimenez ident,
2059*ed775ee7SAntonio Huete Jimenez te_class,
2060*ed775ee7SAntonio Huete Jimenez bw.f * 8 / 1000000);
2061*ed775ee7SAntonio Huete Jimenez tptr += 4;
2062*ed775ee7SAntonio Huete Jimenez subtlv_len -= 4;
2063*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 4;
2064*ed775ee7SAntonio Huete Jimenez proc_bytes += 4;
2065*ed775ee7SAntonio Huete Jimenez }
2066*ed775ee7SAntonio Huete Jimenez }
2067*ed775ee7SAntonio Huete Jimenez break;
2068*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
2069*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
2070*ed775ee7SAntonio Huete Jimenez if (subtlv_len == 0)
2071*ed775ee7SAntonio Huete Jimenez break;
2072*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sBandwidth Constraints Model ID: %s (%u)",
2073*ed775ee7SAntonio Huete Jimenez ident,
2074*ed775ee7SAntonio Huete Jimenez tok2str(diffserv_te_bc_values, "unknown", GET_U_1(tptr)),
2075*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr));
2076*ed775ee7SAntonio Huete Jimenez tptr++;
2077*ed775ee7SAntonio Huete Jimenez subtlv_len--;
2078*ed775ee7SAntonio Huete Jimenez subtlv_sum_len--;
2079*ed775ee7SAntonio Huete Jimenez proc_bytes++;
2080*ed775ee7SAntonio Huete Jimenez /* decode BCs until the subTLV ends */
2081*ed775ee7SAntonio Huete Jimenez for (te_class = 0; subtlv_len != 0; te_class++) {
2082*ed775ee7SAntonio Huete Jimenez if (subtlv_len < 4)
2083*ed775ee7SAntonio Huete Jimenez break;
2084*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2085*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Bandwidth constraint CT%u: %.3f Mbps",
2086*ed775ee7SAntonio Huete Jimenez ident,
2087*ed775ee7SAntonio Huete Jimenez te_class,
2088*ed775ee7SAntonio Huete Jimenez bw.f * 8 / 1000000);
2089*ed775ee7SAntonio Huete Jimenez tptr += 4;
2090*ed775ee7SAntonio Huete Jimenez subtlv_len -= 4;
2091*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 4;
2092*ed775ee7SAntonio Huete Jimenez proc_bytes += 4;
2093*ed775ee7SAntonio Huete Jimenez }
2094*ed775ee7SAntonio Huete Jimenez break;
2095*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC:
2096*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 3)
2097*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %u", GET_BE_U_3(tptr));
2098*ed775ee7SAntonio Huete Jimenez break;
2099*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE:
2100*ed775ee7SAntonio Huete Jimenez if (subtlv_len == 2) {
2101*ed775ee7SAntonio Huete Jimenez ND_PRINT(", [ %s ] (0x%04x)",
2102*ed775ee7SAntonio Huete Jimenez bittok2str(isis_subtlv_link_attribute_values,
2103*ed775ee7SAntonio Huete Jimenez "Unknown",
2104*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr)),
2105*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr));
2106*ed775ee7SAntonio Huete Jimenez }
2107*ed775ee7SAntonio Huete Jimenez break;
2108*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
2109*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 2) {
2110*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %s, Priority %u",
2111*ed775ee7SAntonio Huete Jimenez bittok2str(gmpls_link_prot_values, "none", GET_U_1(tptr)),
2112*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr + 1));
2113*ed775ee7SAntonio Huete Jimenez }
2114*ed775ee7SAntonio Huete Jimenez break;
2115*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_SPB_METRIC:
2116*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 6) {
2117*ed775ee7SAntonio Huete Jimenez ND_PRINT(", LM: %u", GET_BE_U_3(tptr));
2118*ed775ee7SAntonio Huete Jimenez tptr += 3;
2119*ed775ee7SAntonio Huete Jimenez subtlv_len -= 3;
2120*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 3;
2121*ed775ee7SAntonio Huete Jimenez proc_bytes += 3;
2122*ed775ee7SAntonio Huete Jimenez ND_PRINT(", P: %u", GET_U_1(tptr));
2123*ed775ee7SAntonio Huete Jimenez tptr++;
2124*ed775ee7SAntonio Huete Jimenez subtlv_len--;
2125*ed775ee7SAntonio Huete Jimenez subtlv_sum_len--;
2126*ed775ee7SAntonio Huete Jimenez proc_bytes++;
2127*ed775ee7SAntonio Huete Jimenez ND_PRINT(", P-ID: %u", GET_BE_U_2(tptr));
2128*ed775ee7SAntonio Huete Jimenez }
2129*ed775ee7SAntonio Huete Jimenez break;
2130*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
2131*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 36) {
2132*ed775ee7SAntonio Huete Jimenez gmpls_switch_cap = GET_U_1(tptr);
2133*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Interface Switching Capability:%s",
2134*ed775ee7SAntonio Huete Jimenez ident,
2135*ed775ee7SAntonio Huete Jimenez tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap));
2136*ed775ee7SAntonio Huete Jimenez ND_PRINT(", LSP Encoding: %s",
2137*ed775ee7SAntonio Huete Jimenez tok2str(gmpls_encoding_values, "Unknown", GET_U_1((tptr + 1))));
2138*ed775ee7SAntonio Huete Jimenez tptr += 4;
2139*ed775ee7SAntonio Huete Jimenez subtlv_len -= 4;
2140*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 4;
2141*ed775ee7SAntonio Huete Jimenez proc_bytes += 4;
2142*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Max LSP Bandwidth:", ident);
2143*ed775ee7SAntonio Huete Jimenez for (priority_level = 0; priority_level < 8; priority_level++) {
2144*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2145*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s priority level %u: %.3f Mbps",
2146*ed775ee7SAntonio Huete Jimenez ident,
2147*ed775ee7SAntonio Huete Jimenez priority_level,
2148*ed775ee7SAntonio Huete Jimenez bw.f * 8 / 1000000);
2149*ed775ee7SAntonio Huete Jimenez tptr += 4;
2150*ed775ee7SAntonio Huete Jimenez subtlv_len -= 4;
2151*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= 4;
2152*ed775ee7SAntonio Huete Jimenez proc_bytes += 4;
2153*ed775ee7SAntonio Huete Jimenez }
2154*ed775ee7SAntonio Huete Jimenez switch (gmpls_switch_cap) {
2155*ed775ee7SAntonio Huete Jimenez case GMPLS_PSC1:
2156*ed775ee7SAntonio Huete Jimenez case GMPLS_PSC2:
2157*ed775ee7SAntonio Huete Jimenez case GMPLS_PSC3:
2158*ed775ee7SAntonio Huete Jimenez case GMPLS_PSC4:
2159*ed775ee7SAntonio Huete Jimenez if (subtlv_len < 6)
2160*ed775ee7SAntonio Huete Jimenez break;
2161*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2162*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000);
2163*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Interface MTU: %u", ident,
2164*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr + 4));
2165*ed775ee7SAntonio Huete Jimenez break;
2166*ed775ee7SAntonio Huete Jimenez case GMPLS_TSC:
2167*ed775ee7SAntonio Huete Jimenez if (subtlv_len < 8)
2168*ed775ee7SAntonio Huete Jimenez break;
2169*ed775ee7SAntonio Huete Jimenez bw.i = GET_BE_U_4(tptr);
2170*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000);
2171*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Indication %s", ident,
2172*ed775ee7SAntonio Huete Jimenez tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", GET_U_1((tptr + 4))));
2173*ed775ee7SAntonio Huete Jimenez break;
2174*ed775ee7SAntonio Huete Jimenez default:
2175*ed775ee7SAntonio Huete Jimenez /* there is some optional stuff left to decode but this is as of yet
2176*ed775ee7SAntonio Huete Jimenez not specified so just lets hexdump what is left */
2177*ed775ee7SAntonio Huete Jimenez if (subtlv_len != 0) {
2178*ed775ee7SAntonio Huete Jimenez if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len))
217941c99275SPeter Avalos return(0);
2180*ed775ee7SAntonio Huete Jimenez }
2181*ed775ee7SAntonio Huete Jimenez }
2182*ed775ee7SAntonio Huete Jimenez }
2183*ed775ee7SAntonio Huete Jimenez break;
2184*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID:
2185*ed775ee7SAntonio Huete Jimenez if (subtlv_len >= 8) {
2186*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Flags: [%s]", ident,
2187*ed775ee7SAntonio Huete Jimenez bittok2str(isis_lan_adj_sid_flag_values,
2188*ed775ee7SAntonio Huete Jimenez "none",
2189*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr)));
2190*ed775ee7SAntonio Huete Jimenez int vflag = (GET_U_1(tptr) & 0x20) ? 1:0;
2191*ed775ee7SAntonio Huete Jimenez int lflag = (GET_U_1(tptr) & 0x10) ? 1:0;
2192*ed775ee7SAntonio Huete Jimenez tptr++;
2193*ed775ee7SAntonio Huete Jimenez subtlv_len--;
2194*ed775ee7SAntonio Huete Jimenez subtlv_sum_len--;
2195*ed775ee7SAntonio Huete Jimenez proc_bytes++;
2196*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Weight: %u", ident, GET_U_1(tptr));
2197*ed775ee7SAntonio Huete Jimenez tptr++;
2198*ed775ee7SAntonio Huete Jimenez subtlv_len--;
2199*ed775ee7SAntonio Huete Jimenez subtlv_sum_len--;
2200*ed775ee7SAntonio Huete Jimenez proc_bytes++;
2201*ed775ee7SAntonio Huete Jimenez if(subtlv_len>=SYSTEM_ID_LEN) {
2202*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
2203*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Neighbor System-ID: %s", ident,
2204*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tptr, SYSTEM_ID_LEN));
2205*ed775ee7SAntonio Huete Jimenez }
2206*ed775ee7SAntonio Huete Jimenez /* RFC 8667 section 2.2.2 */
2207*ed775ee7SAntonio Huete Jimenez /* if V-flag is set to 1 and L-flag is set to 1 ==> 3 octet label */
2208*ed775ee7SAntonio Huete Jimenez /* if V-flag is set to 0 and L-flag is set to 0 ==> 4 octet index */
2209*ed775ee7SAntonio Huete Jimenez if (vflag && lflag) {
2210*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Label: %u",
2211*ed775ee7SAntonio Huete Jimenez ident, GET_BE_U_3(tptr+SYSTEM_ID_LEN));
2212*ed775ee7SAntonio Huete Jimenez } else if ((!vflag) && (!lflag)) {
2213*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s Index: %u",
2214*ed775ee7SAntonio Huete Jimenez ident, GET_BE_U_4(tptr+SYSTEM_ID_LEN));
2215*ed775ee7SAntonio Huete Jimenez } else
2216*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
2217*ed775ee7SAntonio Huete Jimenez }
2218*ed775ee7SAntonio Huete Jimenez break;
2219*ed775ee7SAntonio Huete Jimenez default:
2220*ed775ee7SAntonio Huete Jimenez if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len))
2221*ed775ee7SAntonio Huete Jimenez return(0);
2222*ed775ee7SAntonio Huete Jimenez break;
2223*ed775ee7SAntonio Huete Jimenez }
2224*ed775ee7SAntonio Huete Jimenez
222541c99275SPeter Avalos tptr += subtlv_len;
2226*ed775ee7SAntonio Huete Jimenez tlv_remaining -= subtlv_len;
2227*ed775ee7SAntonio Huete Jimenez subtlv_sum_len -= subtlv_len;
2228*ed775ee7SAntonio Huete Jimenez proc_bytes += subtlv_len;
222941c99275SPeter Avalos }
223041c99275SPeter Avalos }
223141c99275SPeter Avalos return(proc_bytes);
2232*ed775ee7SAntonio Huete Jimenez
2233*ed775ee7SAntonio Huete Jimenez trunc:
2234*ed775ee7SAntonio Huete Jimenez return(0);
223541c99275SPeter Avalos }
223641c99275SPeter Avalos
223741c99275SPeter Avalos /*
223841c99275SPeter Avalos * this is the common Multi Topology ID decoder
223941c99275SPeter Avalos * it is called from various MT-TLVs (222,229,235,237)
224041c99275SPeter Avalos */
224141c99275SPeter Avalos
2242*ed775ee7SAntonio Huete Jimenez static uint8_t
isis_print_mtid(netdissect_options * ndo,const uint8_t * tptr,const char * ident,u_int tlv_remaining)2243411677aeSAaron LI isis_print_mtid(netdissect_options *ndo,
2244*ed775ee7SAntonio Huete Jimenez const uint8_t *tptr, const char *ident, u_int tlv_remaining)
2245411677aeSAaron LI {
2246*ed775ee7SAntonio Huete Jimenez if (tlv_remaining < 2)
2247*ed775ee7SAntonio Huete Jimenez goto trunc;
224841c99275SPeter Avalos
2249*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s",
225041c99275SPeter Avalos ident,
225141c99275SPeter Avalos tok2str(isis_mt_values,
225241c99275SPeter Avalos "Reserved for IETF Consensus",
2253*ed775ee7SAntonio Huete Jimenez ISIS_MASK_MTID(GET_BE_U_2(tptr))));
225441c99275SPeter Avalos
2255*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Topology (0x%03x), Flags: [%s]",
2256*ed775ee7SAntonio Huete Jimenez ISIS_MASK_MTID(GET_BE_U_2(tptr)),
2257*ed775ee7SAntonio Huete Jimenez bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(GET_BE_U_2(tptr))));
225841c99275SPeter Avalos
225941c99275SPeter Avalos return(2);
2260*ed775ee7SAntonio Huete Jimenez trunc:
2261*ed775ee7SAntonio Huete Jimenez return 0;
226241c99275SPeter Avalos }
226341c99275SPeter Avalos
226441c99275SPeter Avalos /*
226541c99275SPeter Avalos * this is the common extended IP reach decoder
226641c99275SPeter Avalos * it is called from TLVs (135,235,236,237)
226741c99275SPeter Avalos * we process the TLV and optional subTLVs and return
226841c99275SPeter Avalos * the amount of processed bytes
226941c99275SPeter Avalos */
227041c99275SPeter Avalos
2271*ed775ee7SAntonio Huete Jimenez static u_int
isis_print_extd_ip_reach(netdissect_options * ndo,const uint8_t * tptr,const char * ident,uint16_t afi)2272411677aeSAaron LI isis_print_extd_ip_reach(netdissect_options *ndo,
2273411677aeSAaron LI const uint8_t *tptr, const char *ident, uint16_t afi)
2274411677aeSAaron LI {
227541c99275SPeter Avalos char ident_buffer[20];
2276*ed775ee7SAntonio Huete Jimenez uint8_t prefix[sizeof(nd_ipv6)]; /* shared copy buffer for IPv4 and IPv6 prefixes */
227741c99275SPeter Avalos u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen;
227841c99275SPeter Avalos
2279*ed775ee7SAntonio Huete Jimenez metric = GET_BE_U_4(tptr);
228041c99275SPeter Avalos processed=4;
228141c99275SPeter Avalos tptr+=4;
228241c99275SPeter Avalos
2283ea7b4bf5SPeter Avalos if (afi == AF_INET) {
2284*ed775ee7SAntonio Huete Jimenez status_byte=GET_U_1(tptr);
2285*ed775ee7SAntonio Huete Jimenez tptr++;
228641c99275SPeter Avalos bit_length = status_byte&0x3f;
228741c99275SPeter Avalos if (bit_length > 32) {
2288*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv4 prefix: bad bit length %u",
228941c99275SPeter Avalos ident,
2290*ed775ee7SAntonio Huete Jimenez bit_length);
229141c99275SPeter Avalos return (0);
229241c99275SPeter Avalos }
229341c99275SPeter Avalos processed++;
2294ea7b4bf5SPeter Avalos } else if (afi == AF_INET6) {
2295*ed775ee7SAntonio Huete Jimenez status_byte=GET_U_1(tptr);
2296*ed775ee7SAntonio Huete Jimenez bit_length=GET_U_1(tptr + 1);
229741c99275SPeter Avalos if (bit_length > 128) {
2298*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv6 prefix: bad bit length %u",
229941c99275SPeter Avalos ident,
2300*ed775ee7SAntonio Huete Jimenez bit_length);
230141c99275SPeter Avalos return (0);
230241c99275SPeter Avalos }
2303*ed775ee7SAntonio Huete Jimenez tptr+=2;
230441c99275SPeter Avalos processed+=2;
230541c99275SPeter Avalos } else
230641c99275SPeter Avalos return (0); /* somebody is fooling us */
230741c99275SPeter Avalos
230841c99275SPeter Avalos byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
230941c99275SPeter Avalos
2310*ed775ee7SAntonio Huete Jimenez memset(prefix, 0, sizeof(prefix)); /* clear the copy buffer */
2311*ed775ee7SAntonio Huete Jimenez GET_CPY_BYTES(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */
231241c99275SPeter Avalos tptr+=byte_length;
231341c99275SPeter Avalos processed+=byte_length;
231441c99275SPeter Avalos
2315ea7b4bf5SPeter Avalos if (afi == AF_INET)
2316*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv4 prefix: %15s/%u",
231741c99275SPeter Avalos ident,
2318*ed775ee7SAntonio Huete Jimenez ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */
2319*ed775ee7SAntonio Huete Jimenez bit_length);
2320411677aeSAaron LI else if (afi == AF_INET6)
2321*ed775ee7SAntonio Huete Jimenez ND_PRINT("%sIPv6 prefix: %s/%u",
232241c99275SPeter Avalos ident,
2323*ed775ee7SAntonio Huete Jimenez ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */
2324*ed775ee7SAntonio Huete Jimenez bit_length);
232541c99275SPeter Avalos
2326*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Distribution: %s, Metric: %u",
232741c99275SPeter Avalos ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up",
2328*ed775ee7SAntonio Huete Jimenez metric);
232941c99275SPeter Avalos
2330ea7b4bf5SPeter Avalos if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
2331*ed775ee7SAntonio Huete Jimenez ND_PRINT(", sub-TLVs present");
2332411677aeSAaron LI else if (afi == AF_INET6)
2333*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %s%s",
233441c99275SPeter Avalos ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal",
2335*ed775ee7SAntonio Huete Jimenez ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : "");
233641c99275SPeter Avalos
2337ea7b4bf5SPeter Avalos if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
2338ea7b4bf5SPeter Avalos || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte))
2339ea7b4bf5SPeter Avalos ) {
234041c99275SPeter Avalos /* assume that one prefix can hold more
234141c99275SPeter Avalos than one subTLV - therefore the first byte must reflect
234241c99275SPeter Avalos the aggregate bytecount of the subTLVs for this prefix
234341c99275SPeter Avalos */
2344*ed775ee7SAntonio Huete Jimenez sublen=GET_U_1(tptr);
2345*ed775ee7SAntonio Huete Jimenez tptr++;
234641c99275SPeter Avalos processed+=sublen+1;
2347*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (%u)", sublen); /* print out subTLV length */
234841c99275SPeter Avalos
234941c99275SPeter Avalos while (sublen>0) {
2350*ed775ee7SAntonio Huete Jimenez subtlvtype=GET_U_1(tptr);
2351*ed775ee7SAntonio Huete Jimenez subtlvlen=GET_U_1(tptr + 1);
2352*ed775ee7SAntonio Huete Jimenez tptr+=2;
2353411677aeSAaron LI /* prepend the indent string */
235441c99275SPeter Avalos snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
2355411677aeSAaron LI if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer))
235641c99275SPeter Avalos return(0);
235741c99275SPeter Avalos tptr+=subtlvlen;
235841c99275SPeter Avalos sublen-=(subtlvlen+2);
235941c99275SPeter Avalos }
236041c99275SPeter Avalos }
236141c99275SPeter Avalos return (processed);
236241c99275SPeter Avalos }
236341c99275SPeter Avalos
2364*ed775ee7SAntonio Huete Jimenez static void
isis_print_router_cap_subtlv(netdissect_options * ndo,const uint8_t * tptr,uint8_t tlen)2365*ed775ee7SAntonio Huete Jimenez isis_print_router_cap_subtlv(netdissect_options *ndo, const uint8_t *tptr, uint8_t tlen)
2366*ed775ee7SAntonio Huete Jimenez {
2367*ed775ee7SAntonio Huete Jimenez uint8_t subt, subl;
2368*ed775ee7SAntonio Huete Jimenez
2369*ed775ee7SAntonio Huete Jimenez while (tlen >= 2) {
2370*ed775ee7SAntonio Huete Jimenez subt = GET_U_1(tptr);
2371*ed775ee7SAntonio Huete Jimenez subl = GET_U_1(tptr+1);
2372*ed775ee7SAntonio Huete Jimenez tlen -= 2;
2373*ed775ee7SAntonio Huete Jimenez tptr += 2;
2374*ed775ee7SAntonio Huete Jimenez
2375*ed775ee7SAntonio Huete Jimenez /* first lets see if we know the subTLVs name*/
2376*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\t%s subTLV #%u, length: %u",
2377*ed775ee7SAntonio Huete Jimenez tok2str(isis_router_capability_subtlv_values, "unknown", subt),
2378*ed775ee7SAntonio Huete Jimenez subt, subl);
2379*ed775ee7SAntonio Huete Jimenez
2380*ed775ee7SAntonio Huete Jimenez /*
2381*ed775ee7SAntonio Huete Jimenez * Boundary check.
2382*ed775ee7SAntonio Huete Jimenez */
2383*ed775ee7SAntonio Huete Jimenez if (subl > tlen) {
2384*ed775ee7SAntonio Huete Jimenez break;
2385*ed775ee7SAntonio Huete Jimenez }
2386*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, subl);
2387*ed775ee7SAntonio Huete Jimenez
2388*ed775ee7SAntonio Huete Jimenez switch (subt) {
2389*ed775ee7SAntonio Huete Jimenez case ISIS_SUBTLV_ROUTER_CAP_SR:
2390*ed775ee7SAntonio Huete Jimenez {
2391*ed775ee7SAntonio Huete Jimenez uint8_t flags, sid_tlen, sid_type, sid_len;
2392*ed775ee7SAntonio Huete Jimenez uint32_t range;
2393*ed775ee7SAntonio Huete Jimenez const uint8_t *sid_ptr;
2394*ed775ee7SAntonio Huete Jimenez
2395*ed775ee7SAntonio Huete Jimenez flags = GET_U_1(tptr);
2396*ed775ee7SAntonio Huete Jimenez range = GET_BE_U_3(tptr+1);
2397*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Flags [%s], Range %u",
2398*ed775ee7SAntonio Huete Jimenez bittok2str(isis_router_capability_sr_flags, "None", flags),
2399*ed775ee7SAntonio Huete Jimenez range);
2400*ed775ee7SAntonio Huete Jimenez sid_ptr = tptr + 4;
2401*ed775ee7SAntonio Huete Jimenez sid_tlen = subl - 4;
2402*ed775ee7SAntonio Huete Jimenez
2403*ed775ee7SAntonio Huete Jimenez while (sid_tlen >= 5) {
2404*ed775ee7SAntonio Huete Jimenez sid_type = GET_U_1(sid_ptr);
2405*ed775ee7SAntonio Huete Jimenez sid_len = GET_U_1(sid_ptr+1);
2406*ed775ee7SAntonio Huete Jimenez sid_tlen -= 2;
2407*ed775ee7SAntonio Huete Jimenez sid_ptr += 2;
2408*ed775ee7SAntonio Huete Jimenez
2409*ed775ee7SAntonio Huete Jimenez /*
2410*ed775ee7SAntonio Huete Jimenez * Boundary check.
2411*ed775ee7SAntonio Huete Jimenez */
2412*ed775ee7SAntonio Huete Jimenez if (sid_len > sid_tlen) {
2413*ed775ee7SAntonio Huete Jimenez break;
2414*ed775ee7SAntonio Huete Jimenez }
2415*ed775ee7SAntonio Huete Jimenez
2416*ed775ee7SAntonio Huete Jimenez switch (sid_type) {
2417*ed775ee7SAntonio Huete Jimenez case 1:
2418*ed775ee7SAntonio Huete Jimenez if (sid_len == 3) {
2419*ed775ee7SAntonio Huete Jimenez ND_PRINT(", SID value %u", GET_BE_U_3(sid_ptr));
2420*ed775ee7SAntonio Huete Jimenez } else if (sid_len == 4) {
2421*ed775ee7SAntonio Huete Jimenez ND_PRINT(", SID value %u", GET_BE_U_4(sid_ptr));
2422*ed775ee7SAntonio Huete Jimenez } else {
2423*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Unknown SID length%u", sid_len);
2424*ed775ee7SAntonio Huete Jimenez }
2425*ed775ee7SAntonio Huete Jimenez break;
2426*ed775ee7SAntonio Huete Jimenez default:
2427*ed775ee7SAntonio Huete Jimenez print_unknown_data(ndo, sid_ptr, "\n\t\t ", sid_len);
2428*ed775ee7SAntonio Huete Jimenez }
2429*ed775ee7SAntonio Huete Jimenez
2430*ed775ee7SAntonio Huete Jimenez sid_ptr += sid_len;
2431*ed775ee7SAntonio Huete Jimenez sid_tlen -= sid_len;
2432*ed775ee7SAntonio Huete Jimenez }
2433*ed775ee7SAntonio Huete Jimenez }
2434*ed775ee7SAntonio Huete Jimenez break;
2435*ed775ee7SAntonio Huete Jimenez default:
2436*ed775ee7SAntonio Huete Jimenez print_unknown_data(ndo, tptr, "\n\t\t", subl);
2437*ed775ee7SAntonio Huete Jimenez break;
2438*ed775ee7SAntonio Huete Jimenez }
2439*ed775ee7SAntonio Huete Jimenez
2440*ed775ee7SAntonio Huete Jimenez tlen -= subl;
2441*ed775ee7SAntonio Huete Jimenez tptr += subl;
2442*ed775ee7SAntonio Huete Jimenez }
2443*ed775ee7SAntonio Huete Jimenez trunc:
2444*ed775ee7SAntonio Huete Jimenez return;
2445*ed775ee7SAntonio Huete Jimenez }
2446*ed775ee7SAntonio Huete Jimenez
244741c99275SPeter Avalos /*
2448411677aeSAaron LI * Clear checksum and lifetime prior to signature verification.
2449411677aeSAaron LI */
2450411677aeSAaron LI static void
isis_clear_checksum_lifetime(void * header)2451411677aeSAaron LI isis_clear_checksum_lifetime(void *header)
2452411677aeSAaron LI {
2453411677aeSAaron LI struct isis_lsp_header *header_lsp = (struct isis_lsp_header *) header;
2454411677aeSAaron LI
2455411677aeSAaron LI header_lsp->checksum[0] = 0;
2456411677aeSAaron LI header_lsp->checksum[1] = 0;
2457411677aeSAaron LI header_lsp->remaining_lifetime[0] = 0;
2458411677aeSAaron LI header_lsp->remaining_lifetime[1] = 0;
2459411677aeSAaron LI }
2460411677aeSAaron LI
2461411677aeSAaron LI /*
246241c99275SPeter Avalos * isis_print
246341c99275SPeter Avalos * Decode IS-IS packets. Return 0 on error.
246441c99275SPeter Avalos */
246541c99275SPeter Avalos
2466*ed775ee7SAntonio Huete Jimenez #define INVALID_OR_DECREMENT(length,decr) \
2467*ed775ee7SAntonio Huete Jimenez if ((length) < (decr)) { \
2468*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [packet length %u < %zu]", (length), (decr)); \
2469*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo); \
2470*ed775ee7SAntonio Huete Jimenez return 1; \
2471*ed775ee7SAntonio Huete Jimenez } \
2472*ed775ee7SAntonio Huete Jimenez length -= (decr);
2473*ed775ee7SAntonio Huete Jimenez
2474411677aeSAaron LI static int
isis_print(netdissect_options * ndo,const uint8_t * p,u_int length)2475411677aeSAaron LI isis_print(netdissect_options *ndo,
2476411677aeSAaron LI const uint8_t *p, u_int length)
247741c99275SPeter Avalos {
247841c99275SPeter Avalos const struct isis_common_header *isis_header;
247941c99275SPeter Avalos
248041c99275SPeter Avalos const struct isis_iih_lan_header *header_iih_lan;
248141c99275SPeter Avalos const struct isis_iih_ptp_header *header_iih_ptp;
2482411677aeSAaron LI const struct isis_lsp_header *header_lsp;
248341c99275SPeter Avalos const struct isis_csnp_header *header_csnp;
248441c99275SPeter Avalos const struct isis_psnp_header *header_psnp;
248541c99275SPeter Avalos
248641c99275SPeter Avalos const struct isis_tlv_lsp *tlv_lsp;
248741c99275SPeter Avalos const struct isis_tlv_ptp_adj *tlv_ptp_adj;
248841c99275SPeter Avalos const struct isis_tlv_is_reach *tlv_is_reach;
248941c99275SPeter Avalos const struct isis_tlv_es_reach *tlv_es_reach;
249041c99275SPeter Avalos
2491*ed775ee7SAntonio Huete Jimenez uint8_t version, pdu_version, fixed_len;
2492*ed775ee7SAntonio Huete Jimenez uint8_t pdu_type, pdu_max_area, max_area, pdu_id_length, id_length, tlv_type, tlv_len, tlen, alen, prefix_len;
2493*ed775ee7SAntonio Huete Jimenez u_int ext_is_len, ext_ip_len;
2494*ed775ee7SAntonio Huete Jimenez uint8_t mt_len;
2495*ed775ee7SAntonio Huete Jimenez uint8_t isis_subtlv_idrp;
2496411677aeSAaron LI const uint8_t *optr, *pptr, *tptr;
2497*ed775ee7SAntonio Huete Jimenez u_int packet_len;
2498*ed775ee7SAntonio Huete Jimenez u_short pdu_len, key_id;
2499*ed775ee7SAntonio Huete Jimenez u_int i,vendor_id, num_vals;
2500*ed775ee7SAntonio Huete Jimenez uint8_t auth_type;
2501*ed775ee7SAntonio Huete Jimenez uint8_t num_system_ids;
250227bfbee1SPeter Avalos int sigcheck;
250341c99275SPeter Avalos
2504*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "isis";
250541c99275SPeter Avalos packet_len=length;
250641c99275SPeter Avalos optr = p; /* initialize the _o_riginal pointer to the packet start -
250727bfbee1SPeter Avalos need it for parsing the checksum TLV and authentication
250827bfbee1SPeter Avalos TLV verification */
250941c99275SPeter Avalos isis_header = (const struct isis_common_header *)p;
2510*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(isis_header);
2511411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE)
2512411677aeSAaron LI goto trunc;
251341c99275SPeter Avalos pptr = p+(ISIS_COMMON_HEADER_SIZE);
251441c99275SPeter Avalos header_iih_lan = (const struct isis_iih_lan_header *)pptr;
251541c99275SPeter Avalos header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
2516411677aeSAaron LI header_lsp = (const struct isis_lsp_header *)pptr;
251741c99275SPeter Avalos header_csnp = (const struct isis_csnp_header *)pptr;
251841c99275SPeter Avalos header_psnp = (const struct isis_psnp_header *)pptr;
251941c99275SPeter Avalos
2520411677aeSAaron LI if (!ndo->ndo_eflag)
2521*ed775ee7SAntonio Huete Jimenez ND_PRINT("IS-IS");
252241c99275SPeter Avalos
252341c99275SPeter Avalos /*
252441c99275SPeter Avalos * Sanity checking of the header.
252541c99275SPeter Avalos */
252641c99275SPeter Avalos
2527*ed775ee7SAntonio Huete Jimenez version = GET_U_1(isis_header->version);
2528*ed775ee7SAntonio Huete Jimenez if (version != ISIS_VERSION) {
2529*ed775ee7SAntonio Huete Jimenez ND_PRINT("version %u packet not supported", version);
253041c99275SPeter Avalos return (0);
253141c99275SPeter Avalos }
253241c99275SPeter Avalos
2533*ed775ee7SAntonio Huete Jimenez pdu_id_length = GET_U_1(isis_header->id_length);
2534*ed775ee7SAntonio Huete Jimenez if ((pdu_id_length != SYSTEM_ID_LEN) && (pdu_id_length != 0)) {
2535*ed775ee7SAntonio Huete Jimenez ND_PRINT("system ID length of %u is not supported",
2536*ed775ee7SAntonio Huete Jimenez pdu_id_length);
253741c99275SPeter Avalos return (0);
253841c99275SPeter Avalos }
253941c99275SPeter Avalos
2540*ed775ee7SAntonio Huete Jimenez pdu_version = GET_U_1(isis_header->pdu_version);
2541*ed775ee7SAntonio Huete Jimenez if (pdu_version != ISIS_VERSION) {
2542*ed775ee7SAntonio Huete Jimenez ND_PRINT("version %u packet not supported", pdu_version);
2543411677aeSAaron LI return (0);
2544411677aeSAaron LI }
2545411677aeSAaron LI
2546*ed775ee7SAntonio Huete Jimenez fixed_len = GET_U_1(isis_header->fixed_len);
2547*ed775ee7SAntonio Huete Jimenez if (length < fixed_len) {
2548*ed775ee7SAntonio Huete Jimenez ND_PRINT("fixed header length %u > packet length %u", fixed_len, length);
2549411677aeSAaron LI return (0);
2550411677aeSAaron LI }
2551411677aeSAaron LI
2552*ed775ee7SAntonio Huete Jimenez if (fixed_len < ISIS_COMMON_HEADER_SIZE) {
2553*ed775ee7SAntonio Huete Jimenez ND_PRINT("fixed header length %u < minimum header size %u", fixed_len, (u_int)ISIS_COMMON_HEADER_SIZE);
255441c99275SPeter Avalos return (0);
255541c99275SPeter Avalos }
255641c99275SPeter Avalos
2557*ed775ee7SAntonio Huete Jimenez pdu_max_area = GET_U_1(isis_header->max_area);
2558*ed775ee7SAntonio Huete Jimenez switch(pdu_max_area) {
255941c99275SPeter Avalos case 0:
256041c99275SPeter Avalos max_area = 3; /* silly shit */
256141c99275SPeter Avalos break;
256241c99275SPeter Avalos case 255:
2563*ed775ee7SAntonio Huete Jimenez ND_PRINT("bad packet -- 255 areas");
256441c99275SPeter Avalos return (0);
256541c99275SPeter Avalos default:
2566*ed775ee7SAntonio Huete Jimenez max_area = pdu_max_area;
256741c99275SPeter Avalos break;
256841c99275SPeter Avalos }
256941c99275SPeter Avalos
2570*ed775ee7SAntonio Huete Jimenez switch(pdu_id_length) {
257141c99275SPeter Avalos case 0:
257241c99275SPeter Avalos id_length = 6; /* silly shit again */
257341c99275SPeter Avalos break;
2574*ed775ee7SAntonio Huete Jimenez case 1: /* 1-8 are valid sys-ID lengths */
257541c99275SPeter Avalos case 2:
257641c99275SPeter Avalos case 3:
257741c99275SPeter Avalos case 4:
257841c99275SPeter Avalos case 5:
257941c99275SPeter Avalos case 6:
258041c99275SPeter Avalos case 7:
258141c99275SPeter Avalos case 8:
2582*ed775ee7SAntonio Huete Jimenez id_length = pdu_id_length;
258341c99275SPeter Avalos break;
258441c99275SPeter Avalos case 255:
258541c99275SPeter Avalos id_length = 0; /* entirely useless */
258641c99275SPeter Avalos break;
258741c99275SPeter Avalos default:
2588*ed775ee7SAntonio Huete Jimenez id_length = pdu_id_length;
258941c99275SPeter Avalos break;
259041c99275SPeter Avalos }
259141c99275SPeter Avalos
259241c99275SPeter Avalos /* toss any non 6-byte sys-ID len PDUs */
259341c99275SPeter Avalos if (id_length != 6 ) {
2594*ed775ee7SAntonio Huete Jimenez ND_PRINT("bad packet -- illegal sys-ID length (%u)", id_length);
259541c99275SPeter Avalos return (0);
259641c99275SPeter Avalos }
259741c99275SPeter Avalos
2598*ed775ee7SAntonio Huete Jimenez pdu_type = GET_U_1(isis_header->pdu_type);
259941c99275SPeter Avalos
260041c99275SPeter Avalos /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
2601411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2602*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s%s",
2603411677aeSAaron LI ndo->ndo_eflag ? "" : ", ",
2604*ed775ee7SAntonio Huete Jimenez tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type));
2605411677aeSAaron LI } else {
260641c99275SPeter Avalos /* ok they seem to want to know everything - lets fully decode it */
2607*ed775ee7SAntonio Huete Jimenez ND_PRINT("%slength %u", ndo->ndo_eflag ? "" : ", ", length);
260841c99275SPeter Avalos
2609*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
261041c99275SPeter Avalos tok2str(isis_pdu_values,
261141c99275SPeter Avalos "unknown, type %u",
261241c99275SPeter Avalos pdu_type),
2613*ed775ee7SAntonio Huete Jimenez fixed_len,
2614*ed775ee7SAntonio Huete Jimenez version,
2615*ed775ee7SAntonio Huete Jimenez pdu_version,
261641c99275SPeter Avalos id_length,
2617*ed775ee7SAntonio Huete Jimenez pdu_id_length,
261841c99275SPeter Avalos max_area,
2619*ed775ee7SAntonio Huete Jimenez pdu_max_area);
262041c99275SPeter Avalos
2621411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2622411677aeSAaron LI if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
262341c99275SPeter Avalos return (0); /* for optionally debugging the common header */
262441c99275SPeter Avalos }
2625411677aeSAaron LI }
262641c99275SPeter Avalos
262741c99275SPeter Avalos switch (pdu_type) {
262841c99275SPeter Avalos
262941c99275SPeter Avalos case ISIS_PDU_L1_LAN_IIH:
263041c99275SPeter Avalos case ISIS_PDU_L2_LAN_IIH:
2631*ed775ee7SAntonio Huete Jimenez if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
2632*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bogus fixed header length %u should be %zu",
2633*ed775ee7SAntonio Huete Jimenez fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
263441c99275SPeter Avalos return (0);
263541c99275SPeter Avalos }
2636*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(header_iih_lan);
2637411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)
2638411677aeSAaron LI goto trunc;
2639411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2640*ed775ee7SAntonio Huete Jimenez ND_PRINT(", src-id %s",
2641*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_iih_lan->source_id, SYSTEM_ID_LEN));
2642*ed775ee7SAntonio Huete Jimenez ND_PRINT(", lan-id %s, prio %u",
2643*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_iih_lan->lan_id,NODE_ID_LEN),
2644*ed775ee7SAntonio Huete Jimenez GET_U_1(header_iih_lan->priority));
2645*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2646411677aeSAaron LI return (1);
2647411677aeSAaron LI }
2648*ed775ee7SAntonio Huete Jimenez pdu_len=GET_BE_U_2(header_iih_lan->pdu_len);
264941c99275SPeter Avalos if (packet_len>pdu_len) {
265041c99275SPeter Avalos packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
265141c99275SPeter Avalos length=pdu_len;
265241c99275SPeter Avalos }
265341c99275SPeter Avalos
2654*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]",
2655*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_iih_lan->source_id,SYSTEM_ID_LEN),
2656*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_iih_lan->holding_time),
265741c99275SPeter Avalos tok2str(isis_iih_circuit_type_values,
265841c99275SPeter Avalos "unknown circuit type 0x%02x",
2659*ed775ee7SAntonio Huete Jimenez GET_U_1(header_iih_lan->circuit_type)));
266041c99275SPeter Avalos
2661*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t lan-id: %s, Priority: %u, PDU length: %u",
2662*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_iih_lan->lan_id, NODE_ID_LEN),
2663*ed775ee7SAntonio Huete Jimenez GET_U_1(header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
2664*ed775ee7SAntonio Huete Jimenez pdu_len);
266541c99275SPeter Avalos
2666411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2667411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
266841c99275SPeter Avalos return (0);
266941c99275SPeter Avalos }
267041c99275SPeter Avalos
2671*ed775ee7SAntonio Huete Jimenez INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
267241c99275SPeter Avalos pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
267341c99275SPeter Avalos break;
267441c99275SPeter Avalos
267541c99275SPeter Avalos case ISIS_PDU_PTP_IIH:
2676*ed775ee7SAntonio Huete Jimenez if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
2677*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bogus fixed header length %u should be %zu",
2678*ed775ee7SAntonio Huete Jimenez fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
267941c99275SPeter Avalos return (0);
268041c99275SPeter Avalos }
2681*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(header_iih_ptp);
2682411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)
2683411677aeSAaron LI goto trunc;
2684411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2685*ed775ee7SAntonio Huete Jimenez ND_PRINT(", src-id %s", isis_print_id(ndo, header_iih_ptp->source_id, SYSTEM_ID_LEN));
2686*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2687411677aeSAaron LI return (1);
2688411677aeSAaron LI }
2689*ed775ee7SAntonio Huete Jimenez pdu_len=GET_BE_U_2(header_iih_ptp->pdu_len);
269041c99275SPeter Avalos if (packet_len>pdu_len) {
269141c99275SPeter Avalos packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
269241c99275SPeter Avalos length=pdu_len;
269341c99275SPeter Avalos }
269441c99275SPeter Avalos
2695*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t source-id: %s, holding time: %us, Flags: [%s]",
2696*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_iih_ptp->source_id,SYSTEM_ID_LEN),
2697*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_iih_ptp->holding_time),
269841c99275SPeter Avalos tok2str(isis_iih_circuit_type_values,
269941c99275SPeter Avalos "unknown circuit type 0x%02x",
2700*ed775ee7SAntonio Huete Jimenez GET_U_1(header_iih_ptp->circuit_type)));
270141c99275SPeter Avalos
2702*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t circuit-id: 0x%02x, PDU length: %u",
2703*ed775ee7SAntonio Huete Jimenez GET_U_1(header_iih_ptp->circuit_id),
2704*ed775ee7SAntonio Huete Jimenez pdu_len);
270541c99275SPeter Avalos
2706411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2707411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
270841c99275SPeter Avalos return (0);
270941c99275SPeter Avalos }
2710*ed775ee7SAntonio Huete Jimenez INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
271141c99275SPeter Avalos pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
271241c99275SPeter Avalos break;
271341c99275SPeter Avalos
271441c99275SPeter Avalos case ISIS_PDU_L1_LSP:
271541c99275SPeter Avalos case ISIS_PDU_L2_LSP:
2716*ed775ee7SAntonio Huete Jimenez if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
2717*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bogus fixed header length %u should be %zu",
2718*ed775ee7SAntonio Huete Jimenez fixed_len, ISIS_LSP_HEADER_SIZE);
271941c99275SPeter Avalos return (0);
272041c99275SPeter Avalos }
2721*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(header_lsp);
2722411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)
2723411677aeSAaron LI goto trunc;
2724411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2725*ed775ee7SAntonio Huete Jimenez ND_PRINT(", lsp-id %s, seq 0x%08x, lifetime %5us",
2726*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN),
2727*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(header_lsp->sequence_number),
2728*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_lsp->remaining_lifetime));
2729*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2730411677aeSAaron LI return (1);
2731411677aeSAaron LI }
2732*ed775ee7SAntonio Huete Jimenez pdu_len=GET_BE_U_2(header_lsp->pdu_len);
273341c99275SPeter Avalos if (packet_len>pdu_len) {
273441c99275SPeter Avalos packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
273541c99275SPeter Avalos length=pdu_len;
273641c99275SPeter Avalos }
273741c99275SPeter Avalos
2738*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
2739*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_lsp->lsp_id, LSP_ID_LEN),
2740*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(header_lsp->sequence_number),
2741*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_lsp->remaining_lifetime),
2742*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_lsp->checksum));
274341c99275SPeter Avalos
2744411677aeSAaron LI osi_print_cksum(ndo, (const uint8_t *)header_lsp->lsp_id,
2745*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(header_lsp->checksum),
2746411677aeSAaron LI 12, length-12);
2747ea7b4bf5SPeter Avalos
2748*ed775ee7SAntonio Huete Jimenez ND_PRINT(", PDU length: %u, Flags: [ %s",
274941c99275SPeter Avalos pdu_len,
2750*ed775ee7SAntonio Huete Jimenez ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
275141c99275SPeter Avalos
275241c99275SPeter Avalos if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
2753*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
2754*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
2755*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
2756*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
2757*ed775ee7SAntonio Huete Jimenez ND_PRINT("ATT bit set, ");
275841c99275SPeter Avalos }
2759*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
2760*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
2761*ed775ee7SAntonio Huete Jimenez ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
276241c99275SPeter Avalos
2763411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2764411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
276541c99275SPeter Avalos return (0);
276641c99275SPeter Avalos }
276741c99275SPeter Avalos
2768*ed775ee7SAntonio Huete Jimenez INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
276941c99275SPeter Avalos pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
277041c99275SPeter Avalos break;
277141c99275SPeter Avalos
277241c99275SPeter Avalos case ISIS_PDU_L1_CSNP:
277341c99275SPeter Avalos case ISIS_PDU_L2_CSNP:
2774*ed775ee7SAntonio Huete Jimenez if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
2775*ed775ee7SAntonio Huete Jimenez ND_PRINT(", bogus fixed header length %u should be %zu",
2776*ed775ee7SAntonio Huete Jimenez fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
277741c99275SPeter Avalos return (0);
277841c99275SPeter Avalos }
2779*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(header_csnp);
2780411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)
2781411677aeSAaron LI goto trunc;
2782411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2783*ed775ee7SAntonio Huete Jimenez ND_PRINT(", src-id %s", isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN));
2784*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2785411677aeSAaron LI return (1);
2786411677aeSAaron LI }
2787*ed775ee7SAntonio Huete Jimenez pdu_len=GET_BE_U_2(header_csnp->pdu_len);
278841c99275SPeter Avalos if (packet_len>pdu_len) {
278941c99275SPeter Avalos packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
279041c99275SPeter Avalos length=pdu_len;
279141c99275SPeter Avalos }
279241c99275SPeter Avalos
2793*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t source-id: %s, PDU length: %u",
2794*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_csnp->source_id, NODE_ID_LEN),
2795*ed775ee7SAntonio Huete Jimenez pdu_len);
2796*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t start lsp-id: %s",
2797*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_csnp->start_lsp_id, LSP_ID_LEN));
2798*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t end lsp-id: %s",
2799*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_csnp->end_lsp_id, LSP_ID_LEN));
280041c99275SPeter Avalos
2801411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2802411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
280341c99275SPeter Avalos return (0);
280441c99275SPeter Avalos }
280541c99275SPeter Avalos
2806*ed775ee7SAntonio Huete Jimenez INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
280741c99275SPeter Avalos pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
280841c99275SPeter Avalos break;
280941c99275SPeter Avalos
281041c99275SPeter Avalos case ISIS_PDU_L1_PSNP:
281141c99275SPeter Avalos case ISIS_PDU_L2_PSNP:
2812*ed775ee7SAntonio Huete Jimenez if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
2813*ed775ee7SAntonio Huete Jimenez ND_PRINT("- bogus fixed header length %u should be %zu",
2814*ed775ee7SAntonio Huete Jimenez fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
281541c99275SPeter Avalos return (0);
281641c99275SPeter Avalos }
2817*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(header_psnp);
2818411677aeSAaron LI if (length < ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)
2819411677aeSAaron LI goto trunc;
2820411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2821*ed775ee7SAntonio Huete Jimenez ND_PRINT(", src-id %s", isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN));
2822*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2823411677aeSAaron LI return (1);
2824411677aeSAaron LI }
2825*ed775ee7SAntonio Huete Jimenez pdu_len=GET_BE_U_2(header_psnp->pdu_len);
282641c99275SPeter Avalos if (packet_len>pdu_len) {
282741c99275SPeter Avalos packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
282841c99275SPeter Avalos length=pdu_len;
282941c99275SPeter Avalos }
283041c99275SPeter Avalos
2831*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t source-id: %s, PDU length: %u",
2832*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, header_psnp->source_id, NODE_ID_LEN),
2833*ed775ee7SAntonio Huete Jimenez pdu_len);
283441c99275SPeter Avalos
2835411677aeSAaron LI if (ndo->ndo_vflag > 1) {
2836411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
283741c99275SPeter Avalos return (0);
283841c99275SPeter Avalos }
283941c99275SPeter Avalos
2840*ed775ee7SAntonio Huete Jimenez INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
284141c99275SPeter Avalos pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
284241c99275SPeter Avalos break;
284341c99275SPeter Avalos
284441c99275SPeter Avalos default:
2845411677aeSAaron LI if (ndo->ndo_vflag == 0) {
2846*ed775ee7SAntonio Huete Jimenez ND_PRINT(", length %u", length);
2847411677aeSAaron LI return (1);
2848411677aeSAaron LI }
2849411677aeSAaron LI (void)print_unknown_data(ndo, pptr, "\n\t ", length);
285041c99275SPeter Avalos return (0);
285141c99275SPeter Avalos }
285241c99275SPeter Avalos
285341c99275SPeter Avalos /*
285441c99275SPeter Avalos * Now print the TLV's.
285541c99275SPeter Avalos */
285641c99275SPeter Avalos
2857411677aeSAaron LI while (packet_len > 0) {
2858*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(pptr);
2859411677aeSAaron LI if (packet_len < 2)
2860411677aeSAaron LI goto trunc;
2861*ed775ee7SAntonio Huete Jimenez tlv_type = GET_U_1(pptr);
2862*ed775ee7SAntonio Huete Jimenez tlv_len = GET_U_1(pptr + 1);
2863*ed775ee7SAntonio Huete Jimenez pptr += 2;
286441c99275SPeter Avalos packet_len -= 2;
2865*ed775ee7SAntonio Huete Jimenez tlen = tlv_len; /* copy temporary len & pointer to packet data */
2866*ed775ee7SAntonio Huete Jimenez tptr = pptr;
286741c99275SPeter Avalos
286841c99275SPeter Avalos /* first lets see if we know the TLVs name*/
2869*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s TLV #%u, length: %u",
287041c99275SPeter Avalos tok2str(isis_tlv_values,
287141c99275SPeter Avalos "unknown",
287241c99275SPeter Avalos tlv_type),
287341c99275SPeter Avalos tlv_type,
2874*ed775ee7SAntonio Huete Jimenez tlv_len);
287541c99275SPeter Avalos
2876411677aeSAaron LI if (packet_len < tlv_len)
2877411677aeSAaron LI goto trunc;
2878411677aeSAaron LI
287941c99275SPeter Avalos /* now check if we have a decoder otherwise do a hexdump at the end*/
288041c99275SPeter Avalos switch (tlv_type) {
288141c99275SPeter Avalos case ISIS_TLV_AREA_ADDR:
2882*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2883*ed775ee7SAntonio Huete Jimenez alen = GET_U_1(tptr);
2884*ed775ee7SAntonio Huete Jimenez tptr++;
2885*ed775ee7SAntonio Huete Jimenez tlen--;
2886*ed775ee7SAntonio Huete Jimenez if (tlen < alen)
2887*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
2888*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Area address (length: %u): %s",
288941c99275SPeter Avalos alen,
2890*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(tptr, alen));
289141c99275SPeter Avalos tptr += alen;
2892*ed775ee7SAntonio Huete Jimenez tlen -= alen;
289341c99275SPeter Avalos }
289441c99275SPeter Avalos break;
289541c99275SPeter Avalos case ISIS_TLV_ISNEIGH:
2896*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2897*ed775ee7SAntonio Huete Jimenez if (tlen < MAC_ADDR_LEN)
2898*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
2899*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, MAC_ADDR_LEN);
2900*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t SNPA: %s", isis_print_id(ndo, tptr, MAC_ADDR_LEN));
2901*ed775ee7SAntonio Huete Jimenez tlen -= MAC_ADDR_LEN;
2902*ed775ee7SAntonio Huete Jimenez tptr += MAC_ADDR_LEN;
290341c99275SPeter Avalos }
290441c99275SPeter Avalos break;
290541c99275SPeter Avalos
2906*ed775ee7SAntonio Huete Jimenez case ISIS_TLV_INSTANCE_ID:
2907*ed775ee7SAntonio Huete Jimenez if (tlen < 4)
2908*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
2909*ed775ee7SAntonio Huete Jimenez num_vals = (tlen-2)/2;
2910*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Instance ID: %u, ITIDs(%u)%s ",
2911*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr), num_vals,
2912*ed775ee7SAntonio Huete Jimenez num_vals ? ":" : "");
2913*ed775ee7SAntonio Huete Jimenez tptr += 2;
2914*ed775ee7SAntonio Huete Jimenez tlen -= 2;
2915*ed775ee7SAntonio Huete Jimenez for (i=0; i < num_vals; i++) {
2916*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u", GET_BE_U_2(tptr));
2917*ed775ee7SAntonio Huete Jimenez if (i < (num_vals - 1)) {
2918*ed775ee7SAntonio Huete Jimenez ND_PRINT(", ");
291941c99275SPeter Avalos }
2920*ed775ee7SAntonio Huete Jimenez tptr += 2;
2921*ed775ee7SAntonio Huete Jimenez tlen -= 2;
292241c99275SPeter Avalos }
292341c99275SPeter Avalos break;
292441c99275SPeter Avalos
292541c99275SPeter Avalos case ISIS_TLV_PADDING:
292641c99275SPeter Avalos break;
292741c99275SPeter Avalos
292841c99275SPeter Avalos case ISIS_TLV_MT_IS_REACH:
2929*ed775ee7SAntonio Huete Jimenez mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen);
293041c99275SPeter Avalos if (mt_len == 0) /* did something go wrong ? */
2931*ed775ee7SAntonio Huete Jimenez goto trunc;
293241c99275SPeter Avalos tptr+=mt_len;
2933*ed775ee7SAntonio Huete Jimenez tlen-=mt_len;
2934*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2935*ed775ee7SAntonio Huete Jimenez ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen);
293641c99275SPeter Avalos if (ext_is_len == 0) /* did something go wrong ? */
2937*ed775ee7SAntonio Huete Jimenez goto trunc;
2938*ed775ee7SAntonio Huete Jimenez if (tlen < ext_is_len) {
2939*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len);
2940*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
2941*ed775ee7SAntonio Huete Jimenez break;
2942*ed775ee7SAntonio Huete Jimenez }
2943*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_is_len;
2944*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_is_len;
294541c99275SPeter Avalos }
294641c99275SPeter Avalos break;
294741c99275SPeter Avalos
294841c99275SPeter Avalos case ISIS_TLV_IS_ALIAS_ID:
2949*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2950*ed775ee7SAntonio Huete Jimenez ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen);
295141c99275SPeter Avalos if (ext_is_len == 0) /* did something go wrong ? */
2952*ed775ee7SAntonio Huete Jimenez goto trunc;
2953*ed775ee7SAntonio Huete Jimenez if (tlen < ext_is_len) {
2954*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len);
2955*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
2956*ed775ee7SAntonio Huete Jimenez break;
2957*ed775ee7SAntonio Huete Jimenez }
2958*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_is_len;
2959*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_is_len;
296041c99275SPeter Avalos }
296141c99275SPeter Avalos break;
296241c99275SPeter Avalos
296341c99275SPeter Avalos case ISIS_TLV_EXT_IS_REACH:
2964*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2965*ed775ee7SAntonio Huete Jimenez ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type, tlen);
296641c99275SPeter Avalos if (ext_is_len == 0) /* did something go wrong ? */
2967*ed775ee7SAntonio Huete Jimenez goto trunc;
2968*ed775ee7SAntonio Huete Jimenez if (tlen < ext_is_len) {
2969*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_is_len);
2970*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
2971*ed775ee7SAntonio Huete Jimenez break;
2972*ed775ee7SAntonio Huete Jimenez }
2973*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_is_len;
2974*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_is_len;
297541c99275SPeter Avalos }
297641c99275SPeter Avalos break;
297741c99275SPeter Avalos case ISIS_TLV_IS_REACH:
2978*ed775ee7SAntonio Huete Jimenez if (tlen < 1)
2979*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
2980*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s",
298141c99275SPeter Avalos tok2str(isis_is_reach_virtual_values,
298241c99275SPeter Avalos "bogus virtual flag 0x%02x",
2983*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr)));
2984*ed775ee7SAntonio Huete Jimenez tptr++;
2985*ed775ee7SAntonio Huete Jimenez tlen--;
298641c99275SPeter Avalos tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
2987*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
2988*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(struct isis_tlv_is_reach))
2989*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
2990*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(tlv_is_reach);
2991*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IS Neighbor: %s",
2992*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tlv_is_reach->neighbor_nodeid, NODE_ID_LEN));
2993411677aeSAaron LI isis_print_metric_block(ndo, &tlv_is_reach->isis_metric_block);
2994*ed775ee7SAntonio Huete Jimenez tlen -= sizeof(struct isis_tlv_is_reach);
299541c99275SPeter Avalos tlv_is_reach++;
299641c99275SPeter Avalos }
299741c99275SPeter Avalos break;
299841c99275SPeter Avalos
299941c99275SPeter Avalos case ISIS_TLV_ESNEIGH:
300041c99275SPeter Avalos tlv_es_reach = (const struct isis_tlv_es_reach *)tptr;
3001*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3002*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(struct isis_tlv_es_reach))
3003*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3004*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(tlv_es_reach);
3005*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t ES Neighbor: %s",
3006*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN));
3007411677aeSAaron LI isis_print_metric_block(ndo, &tlv_es_reach->isis_metric_block);
3008*ed775ee7SAntonio Huete Jimenez tlen -= sizeof(struct isis_tlv_es_reach);
300941c99275SPeter Avalos tlv_es_reach++;
301041c99275SPeter Avalos }
301141c99275SPeter Avalos break;
301241c99275SPeter Avalos
301341c99275SPeter Avalos /* those two TLVs share the same format */
301441c99275SPeter Avalos case ISIS_TLV_INT_IP_REACH:
301541c99275SPeter Avalos case ISIS_TLV_EXT_IP_REACH:
3016411677aeSAaron LI if (!isis_print_tlv_ip_reach(ndo, pptr, "\n\t ", tlv_len))
301741c99275SPeter Avalos return (1);
301841c99275SPeter Avalos break;
301941c99275SPeter Avalos
302041c99275SPeter Avalos case ISIS_TLV_EXTD_IP_REACH:
3021*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3022411677aeSAaron LI ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET);
302341c99275SPeter Avalos if (ext_ip_len == 0) /* did something go wrong ? */
3024*ed775ee7SAntonio Huete Jimenez goto trunc;
3025*ed775ee7SAntonio Huete Jimenez if (tlen < ext_ip_len) {
3026*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len);
3027*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
3028*ed775ee7SAntonio Huete Jimenez break;
3029*ed775ee7SAntonio Huete Jimenez }
3030*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_ip_len;
3031*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_ip_len;
303241c99275SPeter Avalos }
303341c99275SPeter Avalos break;
303441c99275SPeter Avalos
303541c99275SPeter Avalos case ISIS_TLV_MT_IP_REACH:
3036*ed775ee7SAntonio Huete Jimenez mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen);
303741c99275SPeter Avalos if (mt_len == 0) { /* did something go wrong ? */
3038*ed775ee7SAntonio Huete Jimenez goto trunc;
303941c99275SPeter Avalos }
304041c99275SPeter Avalos tptr+=mt_len;
3041*ed775ee7SAntonio Huete Jimenez tlen-=mt_len;
304241c99275SPeter Avalos
3043*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3044411677aeSAaron LI ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET);
304541c99275SPeter Avalos if (ext_ip_len == 0) /* did something go wrong ? */
3046*ed775ee7SAntonio Huete Jimenez goto trunc;
3047*ed775ee7SAntonio Huete Jimenez if (tlen < ext_ip_len) {
3048*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len);
3049*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
3050*ed775ee7SAntonio Huete Jimenez break;
3051*ed775ee7SAntonio Huete Jimenez }
3052*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_ip_len;
3053*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_ip_len;
305441c99275SPeter Avalos }
305541c99275SPeter Avalos break;
305641c99275SPeter Avalos
305741c99275SPeter Avalos case ISIS_TLV_IP6_REACH:
3058*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3059411677aeSAaron LI ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6);
306041c99275SPeter Avalos if (ext_ip_len == 0) /* did something go wrong ? */
3061*ed775ee7SAntonio Huete Jimenez goto trunc;
3062*ed775ee7SAntonio Huete Jimenez if (tlen < ext_ip_len) {
3063*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len);
3064*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
3065*ed775ee7SAntonio Huete Jimenez break;
3066*ed775ee7SAntonio Huete Jimenez }
3067*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_ip_len;
3068*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_ip_len;
306941c99275SPeter Avalos }
307041c99275SPeter Avalos break;
307141c99275SPeter Avalos
307241c99275SPeter Avalos case ISIS_TLV_MT_IP6_REACH:
3073*ed775ee7SAntonio Huete Jimenez mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen);
307441c99275SPeter Avalos if (mt_len == 0) { /* did something go wrong ? */
3075*ed775ee7SAntonio Huete Jimenez goto trunc;
307641c99275SPeter Avalos }
307741c99275SPeter Avalos tptr+=mt_len;
3078*ed775ee7SAntonio Huete Jimenez tlen-=mt_len;
307941c99275SPeter Avalos
3080*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3081411677aeSAaron LI ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6);
308241c99275SPeter Avalos if (ext_ip_len == 0) /* did something go wrong ? */
3083*ed775ee7SAntonio Huete Jimenez goto trunc;
3084*ed775ee7SAntonio Huete Jimenez if (tlen < ext_ip_len) {
3085*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [remaining tlv length %u < %u]", tlen, ext_ip_len);
3086*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
3087*ed775ee7SAntonio Huete Jimenez break;
3088*ed775ee7SAntonio Huete Jimenez }
3089*ed775ee7SAntonio Huete Jimenez tlen-=(uint8_t)ext_ip_len;
3090*ed775ee7SAntonio Huete Jimenez tptr+=(uint8_t)ext_ip_len;
309141c99275SPeter Avalos }
309241c99275SPeter Avalos break;
309341c99275SPeter Avalos
309441c99275SPeter Avalos case ISIS_TLV_IP6ADDR:
3095*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3096*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(nd_ipv6))
3097*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3098*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IPv6 interface address: %s",
3099*ed775ee7SAntonio Huete Jimenez GET_IP6ADDR_STRING(tptr));
310041c99275SPeter Avalos
3101*ed775ee7SAntonio Huete Jimenez tptr += sizeof(nd_ipv6);
3102*ed775ee7SAntonio Huete Jimenez tlen -= sizeof(nd_ipv6);
310341c99275SPeter Avalos }
310441c99275SPeter Avalos break;
310541c99275SPeter Avalos case ISIS_TLV_AUTH:
3106*ed775ee7SAntonio Huete Jimenez if (tlen < 1)
3107*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3108*ed775ee7SAntonio Huete Jimenez auth_type = GET_U_1(tptr);
3109*ed775ee7SAntonio Huete Jimenez tptr++;
3110*ed775ee7SAntonio Huete Jimenez tlen--;
311141c99275SPeter Avalos
3112*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s: ",
311341c99275SPeter Avalos tok2str(isis_subtlv_auth_values,
311441c99275SPeter Avalos "unknown Authentication type 0x%02x",
3115*ed775ee7SAntonio Huete Jimenez auth_type));
311641c99275SPeter Avalos
3117*ed775ee7SAntonio Huete Jimenez switch (auth_type) {
311841c99275SPeter Avalos case ISIS_SUBTLV_AUTH_SIMPLE:
3119*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, tptr, tlen);
312041c99275SPeter Avalos break;
312141c99275SPeter Avalos case ISIS_SUBTLV_AUTH_MD5:
3122*ed775ee7SAntonio Huete Jimenez for(i=0;i<tlen;i++) {
3123*ed775ee7SAntonio Huete Jimenez ND_PRINT("%02x", GET_U_1(tptr + i));
312441c99275SPeter Avalos }
3125*ed775ee7SAntonio Huete Jimenez if (tlen != ISIS_SUBTLV_AUTH_MD5_LEN)
3126*ed775ee7SAntonio Huete Jimenez ND_PRINT(", (invalid subTLV) ");
312727bfbee1SPeter Avalos
3128*ed775ee7SAntonio Huete Jimenez sigcheck = signature_verify(ndo, optr, length, tptr,
3129411677aeSAaron LI isis_clear_checksum_lifetime,
3130411677aeSAaron LI header_lsp);
3131*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck));
313227bfbee1SPeter Avalos
313327bfbee1SPeter Avalos break;
313427bfbee1SPeter Avalos case ISIS_SUBTLV_AUTH_GENERIC:
3135*ed775ee7SAntonio Huete Jimenez if (tlen < 2)
3136*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3137*ed775ee7SAntonio Huete Jimenez key_id = GET_BE_U_2(tptr);
3138*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u, password: ", key_id);
3139*ed775ee7SAntonio Huete Jimenez tptr += 2;
3140*ed775ee7SAntonio Huete Jimenez tlen -= 2;
3141*ed775ee7SAntonio Huete Jimenez for(i=0;i<tlen;i++) {
3142*ed775ee7SAntonio Huete Jimenez ND_PRINT("%02x", GET_U_1(tptr + i));
314327bfbee1SPeter Avalos }
314441c99275SPeter Avalos break;
314541c99275SPeter Avalos case ISIS_SUBTLV_AUTH_PRIVATE:
314641c99275SPeter Avalos default:
3147*ed775ee7SAntonio Huete Jimenez if (!print_unknown_data(ndo, tptr, "\n\t\t ", tlen))
314841c99275SPeter Avalos return(0);
314941c99275SPeter Avalos break;
315041c99275SPeter Avalos }
315141c99275SPeter Avalos break;
315241c99275SPeter Avalos
315341c99275SPeter Avalos case ISIS_TLV_PTP_ADJ:
315441c99275SPeter Avalos tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
3155*ed775ee7SAntonio Huete Jimenez if(tlen>=1) {
3156*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Adjacency State: %s (%u)",
3157*ed775ee7SAntonio Huete Jimenez tok2str(isis_ptp_adjancey_values, "unknown", GET_U_1(tptr)),
3158*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr));
3159*ed775ee7SAntonio Huete Jimenez tlen--;
316041c99275SPeter Avalos }
3161*ed775ee7SAntonio Huete Jimenez if(tlen>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
3162*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Extended Local circuit-ID: 0x%08x",
3163*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tlv_ptp_adj->extd_local_circuit_id));
3164*ed775ee7SAntonio Huete Jimenez tlen-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
316541c99275SPeter Avalos }
3166*ed775ee7SAntonio Huete Jimenez if(tlen>=SYSTEM_ID_LEN) {
3167*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN);
3168*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Neighbor System-ID: %s",
3169*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN));
3170*ed775ee7SAntonio Huete Jimenez tlen-=SYSTEM_ID_LEN;
317141c99275SPeter Avalos }
3172*ed775ee7SAntonio Huete Jimenez if(tlen>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
3173*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Neighbor Extended Local circuit-ID: 0x%08x",
3174*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tlv_ptp_adj->neighbor_extd_local_circuit_id));
317541c99275SPeter Avalos }
317641c99275SPeter Avalos break;
317741c99275SPeter Avalos
317841c99275SPeter Avalos case ISIS_TLV_PROTOCOLS:
3179*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t NLPID(s): ");
3180*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3181*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s (0x%02x)",
318241c99275SPeter Avalos tok2str(nlpid_values,
318341c99275SPeter Avalos "unknown",
3184*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr)),
3185*ed775ee7SAntonio Huete Jimenez GET_U_1(tptr));
3186*ed775ee7SAntonio Huete Jimenez if (tlen>1) /* further NPLIDs ? - put comma */
3187*ed775ee7SAntonio Huete Jimenez ND_PRINT(", ");
318841c99275SPeter Avalos tptr++;
3189*ed775ee7SAntonio Huete Jimenez tlen--;
319041c99275SPeter Avalos }
319141c99275SPeter Avalos break;
319241c99275SPeter Avalos
3193411677aeSAaron LI case ISIS_TLV_MT_PORT_CAP:
3194411677aeSAaron LI {
3195*ed775ee7SAntonio Huete Jimenez if (tlen < 2)
3196*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3197411677aeSAaron LI
3198*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t RES: %u, MTID(s): %u",
3199*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 12),
3200*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) & 0x0fff));
3201411677aeSAaron LI
3202*ed775ee7SAntonio Huete Jimenez tptr += 2;
3203*ed775ee7SAntonio Huete Jimenez tlen -= 2;
3204411677aeSAaron LI
3205*ed775ee7SAntonio Huete Jimenez if (tlen)
3206*ed775ee7SAntonio Huete Jimenez isis_print_mt_port_cap_subtlv(ndo, tptr, tlen);
3207411677aeSAaron LI
3208411677aeSAaron LI break;
3209411677aeSAaron LI }
3210411677aeSAaron LI
3211411677aeSAaron LI case ISIS_TLV_MT_CAPABILITY:
3212*ed775ee7SAntonio Huete Jimenez if (tlen < 2)
3213*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3214411677aeSAaron LI
3215*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t O: %u, RES: %u, MTID(s): %u",
3216*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 15) & 0x01,
3217*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(tptr) >> 12) & 0x07,
3218*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tptr) & 0x0fff);
3219411677aeSAaron LI
3220*ed775ee7SAntonio Huete Jimenez tptr += 2;
3221*ed775ee7SAntonio Huete Jimenez tlen -= 2;
3222411677aeSAaron LI
3223*ed775ee7SAntonio Huete Jimenez if (tlen)
3224*ed775ee7SAntonio Huete Jimenez isis_print_mt_capability_subtlv(ndo, tptr, tlen);
3225411677aeSAaron LI
3226411677aeSAaron LI break;
3227411677aeSAaron LI
322841c99275SPeter Avalos case ISIS_TLV_TE_ROUTER_ID:
3229*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(nd_ipv4))
3230*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3231*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Traffic Engineering Router ID: %s", GET_IPADDR_STRING(pptr));
323241c99275SPeter Avalos break;
323341c99275SPeter Avalos
323441c99275SPeter Avalos case ISIS_TLV_IPADDR:
3235*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3236*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(nd_ipv4))
3237*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3238*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr));
3239*ed775ee7SAntonio Huete Jimenez tptr += sizeof(nd_ipv4);
3240*ed775ee7SAntonio Huete Jimenez tlen -= sizeof(nd_ipv4);
324141c99275SPeter Avalos }
324241c99275SPeter Avalos break;
324341c99275SPeter Avalos
324441c99275SPeter Avalos case ISIS_TLV_HOSTNAME:
3245*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Hostname: ");
3246*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, tptr, tlen);
324741c99275SPeter Avalos break;
324841c99275SPeter Avalos
324941c99275SPeter Avalos case ISIS_TLV_SHARED_RISK_GROUP:
3250*ed775ee7SAntonio Huete Jimenez if (tlen < NODE_ID_LEN)
325141c99275SPeter Avalos break;
3252*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, NODE_ID_LEN);
3253*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IS Neighbor: %s", isis_print_id(ndo, tptr, NODE_ID_LEN));
3254*ed775ee7SAntonio Huete Jimenez tptr+=NODE_ID_LEN;
3255*ed775ee7SAntonio Huete Jimenez tlen-=NODE_ID_LEN;
325641c99275SPeter Avalos
3257*ed775ee7SAntonio Huete Jimenez if (tlen < 1)
325841c99275SPeter Avalos break;
3259*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Flags: [%s]",
3260*ed775ee7SAntonio Huete Jimenez ISIS_MASK_TLV_SHARED_RISK_GROUP(GET_U_1(tptr)) ? "numbered" : "unnumbered");
3261*ed775ee7SAntonio Huete Jimenez tptr++;
3262*ed775ee7SAntonio Huete Jimenez tlen--;
326341c99275SPeter Avalos
3264*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(nd_ipv4))
326541c99275SPeter Avalos break;
3266*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr));
3267*ed775ee7SAntonio Huete Jimenez tptr+=sizeof(nd_ipv4);
3268*ed775ee7SAntonio Huete Jimenez tlen-=sizeof(nd_ipv4);
326941c99275SPeter Avalos
3270*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(nd_ipv4))
327141c99275SPeter Avalos break;
3272*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t IPv4 neighbor address: %s", GET_IPADDR_STRING(tptr));
3273*ed775ee7SAntonio Huete Jimenez tptr+=sizeof(nd_ipv4);
3274*ed775ee7SAntonio Huete Jimenez tlen-=sizeof(nd_ipv4);
327541c99275SPeter Avalos
3276*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3277*ed775ee7SAntonio Huete Jimenez if (tlen < 4)
3278*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3279*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Link-ID: 0x%08x", GET_BE_U_4(tptr));
328041c99275SPeter Avalos tptr+=4;
3281*ed775ee7SAntonio Huete Jimenez tlen-=4;
328241c99275SPeter Avalos }
328341c99275SPeter Avalos break;
328441c99275SPeter Avalos
328541c99275SPeter Avalos case ISIS_TLV_LSP:
328641c99275SPeter Avalos tlv_lsp = (const struct isis_tlv_lsp *)tptr;
3287*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3288*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(struct isis_tlv_lsp))
3289*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3290*ed775ee7SAntonio Huete Jimenez ND_TCHECK_1(tlv_lsp->lsp_id + LSP_ID_LEN - 1);
3291*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t lsp-id: %s",
3292*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tlv_lsp->lsp_id, LSP_ID_LEN));
3293*ed775ee7SAntonio Huete Jimenez ND_PRINT(", seq: 0x%08x",
3294*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(tlv_lsp->sequence_number));
3295*ed775ee7SAntonio Huete Jimenez ND_PRINT(", lifetime: %5ds",
3296*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(tlv_lsp->remaining_lifetime));
3297*ed775ee7SAntonio Huete Jimenez ND_PRINT(", chksum: 0x%04x", GET_BE_U_2(tlv_lsp->checksum));
3298*ed775ee7SAntonio Huete Jimenez tlen-=sizeof(struct isis_tlv_lsp);
329941c99275SPeter Avalos tlv_lsp++;
330041c99275SPeter Avalos }
330141c99275SPeter Avalos break;
330241c99275SPeter Avalos
330341c99275SPeter Avalos case ISIS_TLV_CHECKSUM:
3304*ed775ee7SAntonio Huete Jimenez if (tlen < ISIS_TLV_CHECKSUM_MINLEN)
330541c99275SPeter Avalos break;
3306*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, ISIS_TLV_CHECKSUM_MINLEN);
3307*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t checksum: 0x%04x ", GET_BE_U_2(tptr));
330841c99275SPeter Avalos /* do not attempt to verify the checksum if it is zero
330941c99275SPeter Avalos * most likely a HMAC-MD5 TLV is also present and
331041c99275SPeter Avalos * to avoid conflicts the checksum TLV is zeroed.
331141c99275SPeter Avalos * see rfc3358 for details
331241c99275SPeter Avalos */
3313*ed775ee7SAntonio Huete Jimenez osi_print_cksum(ndo, optr, GET_BE_U_2(tptr), (int)(tptr-optr),
3314411677aeSAaron LI length);
3315411677aeSAaron LI break;
3316411677aeSAaron LI
3317411677aeSAaron LI case ISIS_TLV_POI:
3318*ed775ee7SAntonio Huete Jimenez if (tlen < 1)
3319*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3320*ed775ee7SAntonio Huete Jimenez num_system_ids = GET_U_1(tptr);
3321*ed775ee7SAntonio Huete Jimenez tptr++;
3322*ed775ee7SAntonio Huete Jimenez tlen--;
3323*ed775ee7SAntonio Huete Jimenez if (num_system_ids == 0) {
3324*ed775ee7SAntonio Huete Jimenez /* Not valid */
3325*ed775ee7SAntonio Huete Jimenez ND_PRINT(" No system IDs supplied");
3326*ed775ee7SAntonio Huete Jimenez } else {
3327*ed775ee7SAntonio Huete Jimenez if (tlen < SYSTEM_ID_LEN)
3328*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3329*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
3330*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Purge Originator System-ID: %s",
3331*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tptr, SYSTEM_ID_LEN));
3332*ed775ee7SAntonio Huete Jimenez tptr += SYSTEM_ID_LEN;
3333*ed775ee7SAntonio Huete Jimenez tlen -= SYSTEM_ID_LEN;
3334411677aeSAaron LI
3335*ed775ee7SAntonio Huete Jimenez if (num_system_ids > 1) {
3336*ed775ee7SAntonio Huete Jimenez if (tlen < SYSTEM_ID_LEN)
3337*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3338*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
3339*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, 2 * SYSTEM_ID_LEN + 1);
3340*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Received from System-ID: %s",
3341*ed775ee7SAntonio Huete Jimenez isis_print_id(ndo, tptr, SYSTEM_ID_LEN));
3342*ed775ee7SAntonio Huete Jimenez }
3343411677aeSAaron LI }
334441c99275SPeter Avalos break;
334541c99275SPeter Avalos
334641c99275SPeter Avalos case ISIS_TLV_MT_SUPPORTED:
3347*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
334841c99275SPeter Avalos /* length can only be a multiple of 2, otherwise there is
334941c99275SPeter Avalos something broken -> so decode down until length is 1 */
3350*ed775ee7SAntonio Huete Jimenez if (tlen!=1) {
3351*ed775ee7SAntonio Huete Jimenez mt_len = isis_print_mtid(ndo, tptr, "\n\t ", tlen);
335241c99275SPeter Avalos if (mt_len == 0) /* did something go wrong ? */
3353*ed775ee7SAntonio Huete Jimenez goto trunc;
335441c99275SPeter Avalos tptr+=mt_len;
3355*ed775ee7SAntonio Huete Jimenez tlen-=mt_len;
335641c99275SPeter Avalos } else {
3357*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t invalid MT-ID");
335841c99275SPeter Avalos break;
335941c99275SPeter Avalos }
336041c99275SPeter Avalos }
336141c99275SPeter Avalos break;
336241c99275SPeter Avalos
336341c99275SPeter Avalos case ISIS_TLV_RESTART_SIGNALING:
336441c99275SPeter Avalos /* first attempt to decode the flags */
3365*ed775ee7SAntonio Huete Jimenez if (tlen < ISIS_TLV_RESTART_SIGNALING_FLAGLEN)
336641c99275SPeter Avalos break;
3367*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN);
3368*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Flags [%s]",
3369*ed775ee7SAntonio Huete Jimenez bittok2str(isis_restart_flag_values, "none", GET_U_1(tptr)));
337041c99275SPeter Avalos tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
3371*ed775ee7SAntonio Huete Jimenez tlen-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
337241c99275SPeter Avalos
337341c99275SPeter Avalos /* is there anything other than the flags field? */
3374*ed775ee7SAntonio Huete Jimenez if (tlen == 0)
337541c99275SPeter Avalos break;
337641c99275SPeter Avalos
3377*ed775ee7SAntonio Huete Jimenez if (tlen < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)
337841c99275SPeter Avalos break;
3379*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN);
338041c99275SPeter Avalos
3381*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Remaining holding time %us", GET_BE_U_2(tptr));
338241c99275SPeter Avalos tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
3383*ed775ee7SAntonio Huete Jimenez tlen-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
338441c99275SPeter Avalos
338541c99275SPeter Avalos /* is there an additional sysid field present ?*/
3386*ed775ee7SAntonio Huete Jimenez if (tlen == SYSTEM_ID_LEN) {
3387*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
3388*ed775ee7SAntonio Huete Jimenez ND_PRINT(", for %s", isis_print_id(ndo, tptr,SYSTEM_ID_LEN));
338941c99275SPeter Avalos }
339041c99275SPeter Avalos break;
339141c99275SPeter Avalos
339241c99275SPeter Avalos case ISIS_TLV_IDRP_INFO:
3393*ed775ee7SAntonio Huete Jimenez if (tlen < 1)
339441c99275SPeter Avalos break;
3395*ed775ee7SAntonio Huete Jimenez isis_subtlv_idrp = GET_U_1(tptr);
3396*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Inter-Domain Information Type: %s",
339741c99275SPeter Avalos tok2str(isis_subtlv_idrp_values,
339841c99275SPeter Avalos "Unknown (0x%02x)",
3399*ed775ee7SAntonio Huete Jimenez isis_subtlv_idrp));
3400*ed775ee7SAntonio Huete Jimenez tptr++;
3401*ed775ee7SAntonio Huete Jimenez tlen--;
3402*ed775ee7SAntonio Huete Jimenez switch (isis_subtlv_idrp) {
340341c99275SPeter Avalos case ISIS_SUBTLV_IDRP_ASN:
3404*ed775ee7SAntonio Huete Jimenez if (tlen < 2)
3405*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3406*ed775ee7SAntonio Huete Jimenez ND_PRINT("AS Number: %u", GET_BE_U_2(tptr));
340741c99275SPeter Avalos break;
340841c99275SPeter Avalos case ISIS_SUBTLV_IDRP_LOCAL:
340941c99275SPeter Avalos case ISIS_SUBTLV_IDRP_RES:
341041c99275SPeter Avalos default:
3411*ed775ee7SAntonio Huete Jimenez if (!print_unknown_data(ndo, tptr, "\n\t ", tlen))
341241c99275SPeter Avalos return(0);
341341c99275SPeter Avalos break;
341441c99275SPeter Avalos }
341541c99275SPeter Avalos break;
341641c99275SPeter Avalos
341741c99275SPeter Avalos case ISIS_TLV_LSP_BUFFERSIZE:
3418*ed775ee7SAntonio Huete Jimenez if (tlen < 2)
341941c99275SPeter Avalos break;
3420*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t LSP Buffersize: %u", GET_BE_U_2(tptr));
342141c99275SPeter Avalos break;
342241c99275SPeter Avalos
342341c99275SPeter Avalos case ISIS_TLV_PART_DIS:
3424*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3425*ed775ee7SAntonio Huete Jimenez if (tlen < SYSTEM_ID_LEN)
3426*ed775ee7SAntonio Huete Jimenez goto tlv_trunc;
3427*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
3428*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %s", isis_print_id(ndo, tptr, SYSTEM_ID_LEN));
342941c99275SPeter Avalos tptr+=SYSTEM_ID_LEN;
3430*ed775ee7SAntonio Huete Jimenez tlen-=SYSTEM_ID_LEN;
343141c99275SPeter Avalos }
343241c99275SPeter Avalos break;
343341c99275SPeter Avalos
343441c99275SPeter Avalos case ISIS_TLV_PREFIX_NEIGH:
3435*ed775ee7SAntonio Huete Jimenez if (tlen < sizeof(struct isis_metric_block))
343641c99275SPeter Avalos break;
3437*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, sizeof(struct isis_metric_block));
3438*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Metric Block");
3439411677aeSAaron LI isis_print_metric_block(ndo, (const struct isis_metric_block *)tptr);
344041c99275SPeter Avalos tptr+=sizeof(struct isis_metric_block);
3441*ed775ee7SAntonio Huete Jimenez tlen-=sizeof(struct isis_metric_block);
344241c99275SPeter Avalos
3443*ed775ee7SAntonio Huete Jimenez while (tlen != 0) {
3444*ed775ee7SAntonio Huete Jimenez prefix_len=GET_U_1(tptr); /* read out prefix length in semioctets*/
3445*ed775ee7SAntonio Huete Jimenez tptr++;
3446*ed775ee7SAntonio Huete Jimenez tlen--;
344741c99275SPeter Avalos if (prefix_len < 2) {
3448*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\tAddress: prefix length %u < 2", prefix_len);
344941c99275SPeter Avalos break;
345041c99275SPeter Avalos }
3451*ed775ee7SAntonio Huete Jimenez if (tlen < prefix_len/2)
345241c99275SPeter Avalos break;
3453*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t\tAddress: %s/%u",
3454*ed775ee7SAntonio Huete Jimenez GET_ISONSAP_STRING(tptr, prefix_len / 2), prefix_len * 4);
345541c99275SPeter Avalos tptr+=prefix_len/2;
3456*ed775ee7SAntonio Huete Jimenez tlen-=prefix_len/2;
345741c99275SPeter Avalos }
345841c99275SPeter Avalos break;
345941c99275SPeter Avalos
346041c99275SPeter Avalos case ISIS_TLV_IIH_SEQNR:
3461*ed775ee7SAntonio Huete Jimenez if (tlen < 4)
346241c99275SPeter Avalos break;
3463*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Sequence number: %u", GET_BE_U_4(tptr));
3464*ed775ee7SAntonio Huete Jimenez break;
3465*ed775ee7SAntonio Huete Jimenez
3466*ed775ee7SAntonio Huete Jimenez case ISIS_TLV_ROUTER_CAPABILITY:
3467*ed775ee7SAntonio Huete Jimenez if (tlen < 5) {
3468*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [object length %u < 5]", tlen);
3469*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
3470*ed775ee7SAntonio Huete Jimenez break;
3471*ed775ee7SAntonio Huete Jimenez }
3472*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Router-ID %s", GET_IPADDR_STRING(tptr));
3473*ed775ee7SAntonio Huete Jimenez ND_PRINT(", Flags [%s]",
3474*ed775ee7SAntonio Huete Jimenez bittok2str(isis_tlv_router_capability_flags, "none", GET_U_1(tptr+4)));
3475*ed775ee7SAntonio Huete Jimenez
3476*ed775ee7SAntonio Huete Jimenez /* Optional set of sub-TLV */
3477*ed775ee7SAntonio Huete Jimenez if (tlen > 5) {
3478*ed775ee7SAntonio Huete Jimenez isis_print_router_cap_subtlv(ndo, tptr+5, tlen-5);
3479*ed775ee7SAntonio Huete Jimenez }
348041c99275SPeter Avalos break;
348141c99275SPeter Avalos
348241c99275SPeter Avalos case ISIS_TLV_VENDOR_PRIVATE:
3483*ed775ee7SAntonio Huete Jimenez if (tlen < 3)
348441c99275SPeter Avalos break;
3485*ed775ee7SAntonio Huete Jimenez vendor_id = GET_BE_U_3(tptr);
3486*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Vendor: %s (%u)",
348741c99275SPeter Avalos tok2str(oui_values, "Unknown", vendor_id),
3488*ed775ee7SAntonio Huete Jimenez vendor_id);
348941c99275SPeter Avalos tptr+=3;
3490*ed775ee7SAntonio Huete Jimenez tlen-=3;
3491*ed775ee7SAntonio Huete Jimenez if (tlen != 0) /* hexdump the rest */
3492*ed775ee7SAntonio Huete Jimenez if (!print_unknown_data(ndo, tptr, "\n\t\t", tlen))
349341c99275SPeter Avalos return(0);
349441c99275SPeter Avalos break;
349541c99275SPeter Avalos /*
349641c99275SPeter Avalos * FIXME those are the defined TLVs that lack a decoder
349741c99275SPeter Avalos * you are welcome to contribute code ;-)
349841c99275SPeter Avalos */
349941c99275SPeter Avalos
350041c99275SPeter Avalos case ISIS_TLV_DECNET_PHASE4:
350141c99275SPeter Avalos case ISIS_TLV_LUCENT_PRIVATE:
350241c99275SPeter Avalos case ISIS_TLV_IPAUTH:
350341c99275SPeter Avalos case ISIS_TLV_NORTEL_PRIVATE1:
350441c99275SPeter Avalos case ISIS_TLV_NORTEL_PRIVATE2:
350541c99275SPeter Avalos
350641c99275SPeter Avalos default:
3507411677aeSAaron LI if (ndo->ndo_vflag <= 1) {
3508411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t\t", tlv_len))
350941c99275SPeter Avalos return(0);
351041c99275SPeter Avalos }
351141c99275SPeter Avalos break;
351241c99275SPeter Avalos }
3513*ed775ee7SAntonio Huete Jimenez tlv_trunc:
351441c99275SPeter Avalos /* do we want to see an additionally hexdump ? */
3515411677aeSAaron LI if (ndo->ndo_vflag> 1) {
3516411677aeSAaron LI if (!print_unknown_data(ndo, pptr, "\n\t ", tlv_len))
351741c99275SPeter Avalos return(0);
351841c99275SPeter Avalos }
351941c99275SPeter Avalos
352041c99275SPeter Avalos pptr += tlv_len;
352141c99275SPeter Avalos packet_len -= tlv_len;
352241c99275SPeter Avalos }
352341c99275SPeter Avalos
352441c99275SPeter Avalos if (packet_len != 0) {
3525*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t %u straggler bytes", packet_len);
352641c99275SPeter Avalos }
352741c99275SPeter Avalos return (1);
352841c99275SPeter Avalos
352941c99275SPeter Avalos trunc:
3530*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
353141c99275SPeter Avalos return (1);
353241c99275SPeter Avalos }
353341c99275SPeter Avalos
3534ea7b4bf5SPeter Avalos static void
osi_print_cksum(netdissect_options * ndo,const uint8_t * pptr,uint16_t checksum,int checksum_offset,u_int length)3535411677aeSAaron LI osi_print_cksum(netdissect_options *ndo, const uint8_t *pptr,
3536411677aeSAaron LI uint16_t checksum, int checksum_offset, u_int length)
353741c99275SPeter Avalos {
3538411677aeSAaron LI uint16_t calculated_checksum;
353941c99275SPeter Avalos
3540411677aeSAaron LI /* do not attempt to verify the checksum if it is zero,
3541411677aeSAaron LI * if the offset is nonsense,
3542411677aeSAaron LI * or the base pointer is not sane
3543411677aeSAaron LI */
3544411677aeSAaron LI if (!checksum
3545411677aeSAaron LI || checksum_offset < 0
3546*ed775ee7SAntonio Huete Jimenez || !ND_TTEST_2(pptr + checksum_offset)
3547411677aeSAaron LI || (u_int)checksum_offset > length
3548*ed775ee7SAntonio Huete Jimenez || !ND_TTEST_LEN(pptr, length)) {
3549*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (unverified)");
3550ea7b4bf5SPeter Avalos } else {
3551411677aeSAaron LI #if 0
3552*ed775ee7SAntonio Huete Jimenez ND_PRINT("\nosi_print_cksum: %p %d %u\n", pptr, checksum_offset, length);
3553411677aeSAaron LI #endif
3554ea7b4bf5SPeter Avalos calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
3555ea7b4bf5SPeter Avalos if (checksum == calculated_checksum) {
3556*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (correct)");
3557ea7b4bf5SPeter Avalos } else {
3558*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (incorrect should be 0x%04x)", calculated_checksum);
355941c99275SPeter Avalos }
356041c99275SPeter Avalos }
3561ea7b4bf5SPeter Avalos }
3562