xref: /dragonfly/contrib/tcpdump/print-isoclns.c (revision ed775ee7)
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