1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek * Copyright (c) 1992, 1993, 1994, 1995, 1996
3*b636d99dSDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
4*b636d99dSDavid van Moolenbroek *
5*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek * written permission.
17*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek *
21*b636d99dSDavid van Moolenbroek * Original code by Matt Thomas, Digital Equipment Corporation
22*b636d99dSDavid van Moolenbroek *
23*b636d99dSDavid van Moolenbroek * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
24*b636d99dSDavid van Moolenbroek * complete IS-IS & CLNP support.
25*b636d99dSDavid van Moolenbroek */
26*b636d99dSDavid van Moolenbroek
27*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
28*b636d99dSDavid van Moolenbroek #ifndef lint
29*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-isoclns.c,v 1.6 2015/03/31 21:59:35 christos Exp $");
30*b636d99dSDavid van Moolenbroek #endif
31*b636d99dSDavid van Moolenbroek
32*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
33*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
34*b636d99dSDavid van Moolenbroek #include "config.h"
35*b636d99dSDavid van Moolenbroek #endif
36*b636d99dSDavid van Moolenbroek
37*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
38*b636d99dSDavid van Moolenbroek
39*b636d99dSDavid van Moolenbroek #include <string.h>
40*b636d99dSDavid van Moolenbroek
41*b636d99dSDavid van Moolenbroek #include "interface.h"
42*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
43*b636d99dSDavid van Moolenbroek #include "ether.h"
44*b636d99dSDavid van Moolenbroek #include "nlpid.h"
45*b636d99dSDavid van Moolenbroek #include "extract.h"
46*b636d99dSDavid van Moolenbroek #include "gmpls.h"
47*b636d99dSDavid van Moolenbroek #include "oui.h"
48*b636d99dSDavid van Moolenbroek #include "signature.h"
49*b636d99dSDavid van Moolenbroek
50*b636d99dSDavid van Moolenbroek /*
51*b636d99dSDavid van Moolenbroek * IS-IS is defined in ISO 10589. Look there for protocol definitions.
52*b636d99dSDavid van Moolenbroek */
53*b636d99dSDavid van Moolenbroek
54*b636d99dSDavid van Moolenbroek #define SYSTEM_ID_LEN ETHER_ADDR_LEN
55*b636d99dSDavid van Moolenbroek #define NODE_ID_LEN SYSTEM_ID_LEN+1
56*b636d99dSDavid van Moolenbroek #define LSP_ID_LEN SYSTEM_ID_LEN+2
57*b636d99dSDavid van Moolenbroek
58*b636d99dSDavid van Moolenbroek #define ISIS_VERSION 1
59*b636d99dSDavid van Moolenbroek #define ESIS_VERSION 1
60*b636d99dSDavid van Moolenbroek #define CLNP_VERSION 1
61*b636d99dSDavid van Moolenbroek
62*b636d99dSDavid van Moolenbroek #define ISIS_PDU_TYPE_MASK 0x1F
63*b636d99dSDavid van Moolenbroek #define ESIS_PDU_TYPE_MASK 0x1F
64*b636d99dSDavid van Moolenbroek #define CLNP_PDU_TYPE_MASK 0x1F
65*b636d99dSDavid van Moolenbroek #define CLNP_FLAG_MASK 0xE0
66*b636d99dSDavid van Moolenbroek #define ISIS_LAN_PRIORITY_MASK 0x7F
67*b636d99dSDavid van Moolenbroek
68*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L1_LAN_IIH 15
69*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L2_LAN_IIH 16
70*b636d99dSDavid van Moolenbroek #define ISIS_PDU_PTP_IIH 17
71*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L1_LSP 18
72*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L2_LSP 20
73*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L1_CSNP 24
74*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L2_CSNP 25
75*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L1_PSNP 26
76*b636d99dSDavid van Moolenbroek #define ISIS_PDU_L2_PSNP 27
77*b636d99dSDavid van Moolenbroek
78*b636d99dSDavid van Moolenbroek static const struct tok isis_pdu_values[] = {
79*b636d99dSDavid van Moolenbroek { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"},
80*b636d99dSDavid van Moolenbroek { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"},
81*b636d99dSDavid van Moolenbroek { ISIS_PDU_PTP_IIH, "p2p IIH"},
82*b636d99dSDavid van Moolenbroek { ISIS_PDU_L1_LSP, "L1 LSP"},
83*b636d99dSDavid van Moolenbroek { ISIS_PDU_L2_LSP, "L2 LSP"},
84*b636d99dSDavid van Moolenbroek { ISIS_PDU_L1_CSNP, "L1 CSNP"},
85*b636d99dSDavid van Moolenbroek { ISIS_PDU_L2_CSNP, "L2 CSNP"},
86*b636d99dSDavid van Moolenbroek { ISIS_PDU_L1_PSNP, "L1 PSNP"},
87*b636d99dSDavid van Moolenbroek { ISIS_PDU_L2_PSNP, "L2 PSNP"},
88*b636d99dSDavid van Moolenbroek { 0, NULL}
89*b636d99dSDavid van Moolenbroek };
90*b636d99dSDavid van Moolenbroek
91*b636d99dSDavid van Moolenbroek /*
92*b636d99dSDavid van Moolenbroek * A TLV is a tuple of a type, length and a value and is normally used for
93*b636d99dSDavid van Moolenbroek * encoding information in all sorts of places. This is an enumeration of
94*b636d99dSDavid van Moolenbroek * the well known types.
95*b636d99dSDavid van Moolenbroek *
96*b636d99dSDavid van Moolenbroek * list taken from rfc3359 plus some memory from veterans ;-)
97*b636d99dSDavid van Moolenbroek */
98*b636d99dSDavid van Moolenbroek
99*b636d99dSDavid van Moolenbroek #define ISIS_TLV_AREA_ADDR 1 /* iso10589 */
100*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IS_REACH 2 /* iso10589 */
101*b636d99dSDavid van Moolenbroek #define ISIS_TLV_ESNEIGH 3 /* iso10589 */
102*b636d99dSDavid van Moolenbroek #define ISIS_TLV_PART_DIS 4 /* iso10589 */
103*b636d99dSDavid van Moolenbroek #define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */
104*b636d99dSDavid van Moolenbroek #define ISIS_TLV_ISNEIGH 6 /* iso10589 */
105*b636d99dSDavid van Moolenbroek #define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */
106*b636d99dSDavid van Moolenbroek #define ISIS_TLV_PADDING 8 /* iso10589 */
107*b636d99dSDavid van Moolenbroek #define ISIS_TLV_LSP 9 /* iso10589 */
108*b636d99dSDavid van Moolenbroek #define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */
109*b636d99dSDavid van Moolenbroek #define ISIS_TLV_CHECKSUM 12 /* rfc3358 */
110*b636d99dSDavid van Moolenbroek #define ISIS_TLV_CHECKSUM_MINLEN 2
111*b636d99dSDavid van Moolenbroek #define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */
112*b636d99dSDavid van Moolenbroek #define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2
113*b636d99dSDavid van Moolenbroek #define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */
114*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */
115*b636d99dSDavid van Moolenbroek #define ISIS_TLV_DECNET_PHASE4 42
116*b636d99dSDavid van Moolenbroek #define ISIS_TLV_LUCENT_PRIVATE 66
117*b636d99dSDavid van Moolenbroek #define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */
118*b636d99dSDavid van Moolenbroek #define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */
119*b636d99dSDavid van Moolenbroek #define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */
120*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */
121*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IDRP_INFO_MINLEN 1
122*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IPADDR 132 /* rfc1195 */
123*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IPAUTH 133 /* rfc1195 */
124*b636d99dSDavid van Moolenbroek #define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */
125*b636d99dSDavid van Moolenbroek #define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */
126*b636d99dSDavid van Moolenbroek #define ISIS_TLV_HOSTNAME 137 /* rfc2763 */
127*b636d99dSDavid van Moolenbroek #define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */
128*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */
129*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_CAPABILITY 144 /* rfc6329 */
130*b636d99dSDavid van Moolenbroek #define ISIS_TLV_NORTEL_PRIVATE1 176
131*b636d99dSDavid van Moolenbroek #define ISIS_TLV_NORTEL_PRIVATE2 177
132*b636d99dSDavid van Moolenbroek #define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */
133*b636d99dSDavid van Moolenbroek #define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1
134*b636d99dSDavid van Moolenbroek #define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2
135*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
136*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
137*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_SUPPORTED_MINLEN 2
138*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */
139*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */
140*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */
141*b636d99dSDavid van Moolenbroek #define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
142*b636d99dSDavid van Moolenbroek #define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */
143*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
144*b636d99dSDavid van Moolenbroek #define ISIS_TLV_IIH_SEQNR_MINLEN 4
145*b636d99dSDavid van Moolenbroek #define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */
146*b636d99dSDavid van Moolenbroek #define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3
147*b636d99dSDavid van Moolenbroek
148*b636d99dSDavid van Moolenbroek static const struct tok isis_tlv_values[] = {
149*b636d99dSDavid van Moolenbroek { ISIS_TLV_AREA_ADDR, "Area address(es)"},
150*b636d99dSDavid van Moolenbroek { ISIS_TLV_IS_REACH, "IS Reachability"},
151*b636d99dSDavid van Moolenbroek { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"},
152*b636d99dSDavid van Moolenbroek { ISIS_TLV_PART_DIS, "Partition DIS"},
153*b636d99dSDavid van Moolenbroek { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"},
154*b636d99dSDavid van Moolenbroek { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"},
155*b636d99dSDavid van Moolenbroek { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"},
156*b636d99dSDavid van Moolenbroek { ISIS_TLV_PADDING, "Padding"},
157*b636d99dSDavid van Moolenbroek { ISIS_TLV_LSP, "LSP entries"},
158*b636d99dSDavid van Moolenbroek { ISIS_TLV_AUTH, "Authentication"},
159*b636d99dSDavid van Moolenbroek { ISIS_TLV_CHECKSUM, "Checksum"},
160*b636d99dSDavid van Moolenbroek { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"},
161*b636d99dSDavid van Moolenbroek { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"},
162*b636d99dSDavid van Moolenbroek { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"},
163*b636d99dSDavid van Moolenbroek { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"},
164*b636d99dSDavid van Moolenbroek { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"},
165*b636d99dSDavid van Moolenbroek { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"},
166*b636d99dSDavid van Moolenbroek { ISIS_TLV_PROTOCOLS, "Protocols supported"},
167*b636d99dSDavid van Moolenbroek { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"},
168*b636d99dSDavid van Moolenbroek { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"},
169*b636d99dSDavid van Moolenbroek { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"},
170*b636d99dSDavid van Moolenbroek { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"},
171*b636d99dSDavid van Moolenbroek { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"},
172*b636d99dSDavid van Moolenbroek { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"},
173*b636d99dSDavid van Moolenbroek { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"},
174*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_PORT_CAP, "Multi-Topology-Aware Port Capability"},
175*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_CAPABILITY, "Multi-Topology Capability"},
176*b636d99dSDavid van Moolenbroek { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"},
177*b636d99dSDavid van Moolenbroek { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"},
178*b636d99dSDavid van Moolenbroek { ISIS_TLV_HOSTNAME, "Hostname"},
179*b636d99dSDavid van Moolenbroek { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"},
180*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"},
181*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_SUPPORTED, "Multi Topology"},
182*b636d99dSDavid van Moolenbroek { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"},
183*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"},
184*b636d99dSDavid van Moolenbroek { ISIS_TLV_IP6_REACH, "IPv6 reachability"},
185*b636d99dSDavid van Moolenbroek { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"},
186*b636d99dSDavid van Moolenbroek { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"},
187*b636d99dSDavid van Moolenbroek { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"},
188*b636d99dSDavid van Moolenbroek { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"},
189*b636d99dSDavid van Moolenbroek { 0, NULL }
190*b636d99dSDavid van Moolenbroek };
191*b636d99dSDavid van Moolenbroek
192*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_PROTOCOLS 129
193*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */
194*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_SECURITY 197 /* iso9542 */
195*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */
196*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_PRIORITY 205 /* iso9542 */
197*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */
198*b636d99dSDavid van Moolenbroek #define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */
199*b636d99dSDavid van Moolenbroek
200*b636d99dSDavid van Moolenbroek static const struct tok esis_option_values[] = {
201*b636d99dSDavid van Moolenbroek { ESIS_OPTION_PROTOCOLS, "Protocols supported"},
202*b636d99dSDavid van Moolenbroek { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" },
203*b636d99dSDavid van Moolenbroek { ESIS_OPTION_SECURITY, "Security" },
204*b636d99dSDavid van Moolenbroek { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" },
205*b636d99dSDavid van Moolenbroek { ESIS_OPTION_PRIORITY, "Priority" },
206*b636d99dSDavid van Moolenbroek { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" },
207*b636d99dSDavid van Moolenbroek { ESIS_OPTION_SNPA_MASK, "SNPA Mask" },
208*b636d99dSDavid van Moolenbroek { 0, NULL }
209*b636d99dSDavid van Moolenbroek };
210*b636d99dSDavid van Moolenbroek
211*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_DISCARD_REASON 193
212*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */
213*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SECURITY 197 /* iso8473 */
214*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */
215*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */
216*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_PADDING 204 /* iso8473 */
217*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_PRIORITY 205 /* iso8473 */
218*b636d99dSDavid van Moolenbroek
219*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_values[] = {
220*b636d99dSDavid van Moolenbroek { CLNP_OPTION_DISCARD_REASON, "Discard Reason"},
221*b636d99dSDavid van Moolenbroek { CLNP_OPTION_PRIORITY, "Priority"},
222*b636d99dSDavid van Moolenbroek { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"},
223*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SECURITY, "Security"},
224*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"},
225*b636d99dSDavid van Moolenbroek { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"},
226*b636d99dSDavid van Moolenbroek { CLNP_OPTION_PADDING, "Padding"},
227*b636d99dSDavid van Moolenbroek { 0, NULL }
228*b636d99dSDavid van Moolenbroek };
229*b636d99dSDavid van Moolenbroek
230*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_class_values[] = {
231*b636d99dSDavid van Moolenbroek { 0x0, "General"},
232*b636d99dSDavid van Moolenbroek { 0x8, "Address"},
233*b636d99dSDavid van Moolenbroek { 0x9, "Source Routeing"},
234*b636d99dSDavid van Moolenbroek { 0xa, "Lifetime"},
235*b636d99dSDavid van Moolenbroek { 0xb, "PDU Discarded"},
236*b636d99dSDavid van Moolenbroek { 0xc, "Reassembly"},
237*b636d99dSDavid van Moolenbroek { 0, NULL }
238*b636d99dSDavid van Moolenbroek };
239*b636d99dSDavid van Moolenbroek
240*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_general_values[] = {
241*b636d99dSDavid van Moolenbroek { 0x0, "Reason not specified"},
242*b636d99dSDavid van Moolenbroek { 0x1, "Protocol procedure error"},
243*b636d99dSDavid van Moolenbroek { 0x2, "Incorrect checksum"},
244*b636d99dSDavid van Moolenbroek { 0x3, "PDU discarded due to congestion"},
245*b636d99dSDavid van Moolenbroek { 0x4, "Header syntax error (cannot be parsed)"},
246*b636d99dSDavid van Moolenbroek { 0x5, "Segmentation needed but not permitted"},
247*b636d99dSDavid van Moolenbroek { 0x6, "Incomplete PDU received"},
248*b636d99dSDavid van Moolenbroek { 0x7, "Duplicate option"},
249*b636d99dSDavid van Moolenbroek { 0, NULL }
250*b636d99dSDavid van Moolenbroek };
251*b636d99dSDavid van Moolenbroek
252*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_address_values[] = {
253*b636d99dSDavid van Moolenbroek { 0x0, "Destination address unreachable"},
254*b636d99dSDavid van Moolenbroek { 0x1, "Destination address unknown"},
255*b636d99dSDavid van Moolenbroek { 0, NULL }
256*b636d99dSDavid van Moolenbroek };
257*b636d99dSDavid van Moolenbroek
258*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_source_routeing_values[] = {
259*b636d99dSDavid van Moolenbroek { 0x0, "Unspecified source routeing error"},
260*b636d99dSDavid van Moolenbroek { 0x1, "Syntax error in source routeing field"},
261*b636d99dSDavid van Moolenbroek { 0x2, "Unknown address in source routeing field"},
262*b636d99dSDavid van Moolenbroek { 0x3, "Path not acceptable"},
263*b636d99dSDavid van Moolenbroek { 0, NULL }
264*b636d99dSDavid van Moolenbroek };
265*b636d99dSDavid van Moolenbroek
266*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_lifetime_values[] = {
267*b636d99dSDavid van Moolenbroek { 0x0, "Lifetime expired while data unit in transit"},
268*b636d99dSDavid van Moolenbroek { 0x1, "Lifetime expired during reassembly"},
269*b636d99dSDavid van Moolenbroek { 0, NULL }
270*b636d99dSDavid van Moolenbroek };
271*b636d99dSDavid van Moolenbroek
272*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_pdu_discard_values[] = {
273*b636d99dSDavid van Moolenbroek { 0x0, "Unsupported option not specified"},
274*b636d99dSDavid van Moolenbroek { 0x1, "Unsupported protocol version"},
275*b636d99dSDavid van Moolenbroek { 0x2, "Unsupported security option"},
276*b636d99dSDavid van Moolenbroek { 0x3, "Unsupported source routeing option"},
277*b636d99dSDavid van Moolenbroek { 0x4, "Unsupported recording of route option"},
278*b636d99dSDavid van Moolenbroek { 0, NULL }
279*b636d99dSDavid van Moolenbroek };
280*b636d99dSDavid van Moolenbroek
281*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_rfd_reassembly_values[] = {
282*b636d99dSDavid van Moolenbroek { 0x0, "Reassembly interference"},
283*b636d99dSDavid van Moolenbroek { 0, NULL }
284*b636d99dSDavid van Moolenbroek };
285*b636d99dSDavid van Moolenbroek
286*b636d99dSDavid van Moolenbroek /* array of 16 error-classes */
287*b636d99dSDavid van Moolenbroek static const struct tok *clnp_option_rfd_error_class[] = {
288*b636d99dSDavid van Moolenbroek clnp_option_rfd_general_values,
289*b636d99dSDavid van Moolenbroek NULL,
290*b636d99dSDavid van Moolenbroek NULL,
291*b636d99dSDavid van Moolenbroek NULL,
292*b636d99dSDavid van Moolenbroek NULL,
293*b636d99dSDavid van Moolenbroek NULL,
294*b636d99dSDavid van Moolenbroek NULL,
295*b636d99dSDavid van Moolenbroek NULL,
296*b636d99dSDavid van Moolenbroek clnp_option_rfd_address_values,
297*b636d99dSDavid van Moolenbroek clnp_option_rfd_source_routeing_values,
298*b636d99dSDavid van Moolenbroek clnp_option_rfd_lifetime_values,
299*b636d99dSDavid van Moolenbroek clnp_option_rfd_pdu_discard_values,
300*b636d99dSDavid van Moolenbroek clnp_option_rfd_reassembly_values,
301*b636d99dSDavid van Moolenbroek NULL,
302*b636d99dSDavid van Moolenbroek NULL,
303*b636d99dSDavid van Moolenbroek NULL
304*b636d99dSDavid van Moolenbroek };
305*b636d99dSDavid van Moolenbroek
306*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_OPTION_QOS_MASK 0x3f
307*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SCOPE_MASK 0xc0
308*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SCOPE_SA_SPEC 0x40
309*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SCOPE_DA_SPEC 0x80
310*b636d99dSDavid van Moolenbroek #define CLNP_OPTION_SCOPE_GLOBAL 0xc0
311*b636d99dSDavid van Moolenbroek
312*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_scope_values[] = {
313*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"},
314*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"},
315*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"},
316*b636d99dSDavid van Moolenbroek { 0, NULL }
317*b636d99dSDavid van Moolenbroek };
318*b636d99dSDavid van Moolenbroek
319*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_sr_rr_values[] = {
320*b636d99dSDavid van Moolenbroek { 0x0, "partial"},
321*b636d99dSDavid van Moolenbroek { 0x1, "complete"},
322*b636d99dSDavid van Moolenbroek { 0, NULL }
323*b636d99dSDavid van Moolenbroek };
324*b636d99dSDavid van Moolenbroek
325*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_sr_rr_string_values[] = {
326*b636d99dSDavid van Moolenbroek { CLNP_OPTION_SOURCE_ROUTING, "source routing"},
327*b636d99dSDavid van Moolenbroek { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"},
328*b636d99dSDavid van Moolenbroek { 0, NULL }
329*b636d99dSDavid van Moolenbroek };
330*b636d99dSDavid van Moolenbroek
331*b636d99dSDavid van Moolenbroek static const struct tok clnp_option_qos_global_values[] = {
332*b636d99dSDavid van Moolenbroek { 0x20, "reserved"},
333*b636d99dSDavid van Moolenbroek { 0x10, "sequencing vs. delay"},
334*b636d99dSDavid van Moolenbroek { 0x08, "congested"},
335*b636d99dSDavid van Moolenbroek { 0x04, "delay vs. cost"},
336*b636d99dSDavid van Moolenbroek { 0x02, "error vs. delay"},
337*b636d99dSDavid van Moolenbroek { 0x01, "error vs. cost"},
338*b636d99dSDavid van Moolenbroek { 0, NULL }
339*b636d99dSDavid van Moolenbroek };
340*b636d99dSDavid van Moolenbroek
341*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */
342*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */
343*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */
344*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */
345*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */
346*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */
347*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */
348*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */
349*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */
350*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */
351*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */
352*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */
353*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */
354*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */
355*b636d99dSDavid van Moolenbroek
356*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */
357*b636d99dSDavid van Moolenbroek
358*b636d99dSDavid van Moolenbroek static const struct tok isis_ext_is_reach_subtlv_values[] = {
359*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" },
360*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
361*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" },
362*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" },
363*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" },
364*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" },
365*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" },
366*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" },
367*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" },
368*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" },
369*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" },
370*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
371*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" },
372*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" },
373*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" },
374*b636d99dSDavid van Moolenbroek { 250, "Reserved for cisco specific extensions" },
375*b636d99dSDavid van Moolenbroek { 251, "Reserved for cisco specific extensions" },
376*b636d99dSDavid van Moolenbroek { 252, "Reserved for cisco specific extensions" },
377*b636d99dSDavid van Moolenbroek { 253, "Reserved for cisco specific extensions" },
378*b636d99dSDavid van Moolenbroek { 254, "Reserved for cisco specific extensions" },
379*b636d99dSDavid van Moolenbroek { 255, "Reserved for future expansion" },
380*b636d99dSDavid van Moolenbroek { 0, NULL }
381*b636d99dSDavid van Moolenbroek };
382*b636d99dSDavid van Moolenbroek
383*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */
384*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */
385*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */
386*b636d99dSDavid van Moolenbroek
387*b636d99dSDavid van Moolenbroek static const struct tok isis_ext_ip_reach_subtlv_values[] = {
388*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" },
389*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" },
390*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" },
391*b636d99dSDavid van Moolenbroek { 0, NULL }
392*b636d99dSDavid van Moolenbroek };
393*b636d99dSDavid van Moolenbroek
394*b636d99dSDavid van Moolenbroek static const struct tok isis_subtlv_link_attribute_values[] = {
395*b636d99dSDavid van Moolenbroek { 0x01, "Local Protection Available" },
396*b636d99dSDavid van Moolenbroek { 0x02, "Link excluded from local protection path" },
397*b636d99dSDavid van Moolenbroek { 0x04, "Local maintenance required"},
398*b636d99dSDavid van Moolenbroek { 0, NULL }
399*b636d99dSDavid van Moolenbroek };
400*b636d99dSDavid van Moolenbroek
401*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_AUTH_SIMPLE 1
402*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */
403*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_AUTH_MD5 54
404*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_AUTH_MD5_LEN 16
405*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_AUTH_PRIVATE 255
406*b636d99dSDavid van Moolenbroek
407*b636d99dSDavid van Moolenbroek static const struct tok isis_subtlv_auth_values[] = {
408*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"},
409*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"},
410*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"},
411*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"},
412*b636d99dSDavid van Moolenbroek { 0, NULL }
413*b636d99dSDavid van Moolenbroek };
414*b636d99dSDavid van Moolenbroek
415*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_IDRP_RES 0
416*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_IDRP_LOCAL 1
417*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_IDRP_ASN 2
418*b636d99dSDavid van Moolenbroek
419*b636d99dSDavid van Moolenbroek static const struct tok isis_subtlv_idrp_values[] = {
420*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_IDRP_RES, "Reserved"},
421*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"},
422*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"},
423*b636d99dSDavid van Moolenbroek { 0, NULL}
424*b636d99dSDavid van Moolenbroek };
425*b636d99dSDavid van Moolenbroek
426*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_MCID 4
427*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_DIGEST 5
428*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_BVID 6
429*b636d99dSDavid van Moolenbroek
430*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_INSTANCE 1
431*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPBM_SI 3
432*b636d99dSDavid van Moolenbroek
433*b636d99dSDavid van Moolenbroek #define ISIS_SPB_MCID_LEN 51
434*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_MCID_MIN_LEN 102
435*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_DIGEST_MIN_LEN 33
436*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_BVID_MIN_LEN 6
437*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN 19
438*b636d99dSDavid van Moolenbroek #define ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN 8
439*b636d99dSDavid van Moolenbroek
440*b636d99dSDavid van Moolenbroek static const struct tok isis_mt_port_cap_subtlv_values[] = {
441*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPB_MCID, "SPB MCID" },
442*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPB_DIGEST, "SPB Digest" },
443*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPB_BVID, "SPB BVID" },
444*b636d99dSDavid van Moolenbroek { 0, NULL }
445*b636d99dSDavid van Moolenbroek };
446*b636d99dSDavid van Moolenbroek
447*b636d99dSDavid van Moolenbroek static const struct tok isis_mt_capability_subtlv_values[] = {
448*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPB_INSTANCE, "SPB Instance" },
449*b636d99dSDavid van Moolenbroek { ISIS_SUBTLV_SPBM_SI, "SPBM Service Identifier and Unicast Address" },
450*b636d99dSDavid van Moolenbroek { 0, NULL }
451*b636d99dSDavid van Moolenbroek };
452*b636d99dSDavid van Moolenbroek
453*b636d99dSDavid van Moolenbroek struct isis_spb_mcid {
454*b636d99dSDavid van Moolenbroek uint8_t format_id;
455*b636d99dSDavid van Moolenbroek uint8_t name[32];
456*b636d99dSDavid van Moolenbroek uint8_t revision_lvl[2];
457*b636d99dSDavid van Moolenbroek uint8_t digest[16];
458*b636d99dSDavid van Moolenbroek };
459*b636d99dSDavid van Moolenbroek
460*b636d99dSDavid van Moolenbroek struct isis_subtlv_spb_mcid {
461*b636d99dSDavid van Moolenbroek struct isis_spb_mcid mcid;
462*b636d99dSDavid van Moolenbroek struct isis_spb_mcid aux_mcid;
463*b636d99dSDavid van Moolenbroek };
464*b636d99dSDavid van Moolenbroek
465*b636d99dSDavid van Moolenbroek struct isis_subtlv_spb_instance {
466*b636d99dSDavid van Moolenbroek uint8_t cist_root_id[8];
467*b636d99dSDavid van Moolenbroek uint8_t cist_external_root_path_cost[4];
468*b636d99dSDavid van Moolenbroek uint8_t bridge_priority[2];
469*b636d99dSDavid van Moolenbroek uint8_t spsourceid[4];
470*b636d99dSDavid van Moolenbroek uint8_t no_of_trees;
471*b636d99dSDavid van Moolenbroek };
472*b636d99dSDavid van Moolenbroek
473*b636d99dSDavid van Moolenbroek #define CLNP_SEGMENT_PART 0x80
474*b636d99dSDavid van Moolenbroek #define CLNP_MORE_SEGMENTS 0x40
475*b636d99dSDavid van Moolenbroek #define CLNP_REQUEST_ER 0x20
476*b636d99dSDavid van Moolenbroek
477*b636d99dSDavid van Moolenbroek static const struct tok clnp_flag_values[] = {
478*b636d99dSDavid van Moolenbroek { CLNP_SEGMENT_PART, "Segmentation permitted"},
479*b636d99dSDavid van Moolenbroek { CLNP_MORE_SEGMENTS, "more Segments"},
480*b636d99dSDavid van Moolenbroek { CLNP_REQUEST_ER, "request Error Report"},
481*b636d99dSDavid van Moolenbroek { 0, NULL}
482*b636d99dSDavid van Moolenbroek };
483*b636d99dSDavid van Moolenbroek
484*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
485*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
486*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
487*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
488*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
489*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
490*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
491*b636d99dSDavid van Moolenbroek #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
492*b636d99dSDavid van Moolenbroek
493*b636d99dSDavid van Moolenbroek #define ISIS_MASK_MTID(x) ((x)&0x0fff)
494*b636d99dSDavid van Moolenbroek #define ISIS_MASK_MTFLAGS(x) ((x)&0xf000)
495*b636d99dSDavid van Moolenbroek
496*b636d99dSDavid van Moolenbroek static const struct tok isis_mt_flag_values[] = {
497*b636d99dSDavid van Moolenbroek { 0x4000, "ATT bit set"},
498*b636d99dSDavid van Moolenbroek { 0x8000, "Overload bit set"},
499*b636d99dSDavid van Moolenbroek { 0, NULL}
500*b636d99dSDavid van Moolenbroek };
501*b636d99dSDavid van Moolenbroek
502*b636d99dSDavid van Moolenbroek #define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80)
503*b636d99dSDavid van Moolenbroek #define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40)
504*b636d99dSDavid van Moolenbroek
505*b636d99dSDavid van Moolenbroek #define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40)
506*b636d99dSDavid van Moolenbroek #define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20)
507*b636d99dSDavid van Moolenbroek
508*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
509*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
510*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
511*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
512*b636d99dSDavid van Moolenbroek
513*b636d99dSDavid van Moolenbroek #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
514*b636d99dSDavid van Moolenbroek
515*b636d99dSDavid van Moolenbroek static const struct tok isis_mt_values[] = {
516*b636d99dSDavid van Moolenbroek { 0, "IPv4 unicast"},
517*b636d99dSDavid van Moolenbroek { 1, "In-Band Management"},
518*b636d99dSDavid van Moolenbroek { 2, "IPv6 unicast"},
519*b636d99dSDavid van Moolenbroek { 3, "Multicast"},
520*b636d99dSDavid van Moolenbroek { 4095, "Development, Experimental or Proprietary"},
521*b636d99dSDavid van Moolenbroek { 0, NULL }
522*b636d99dSDavid van Moolenbroek };
523*b636d99dSDavid van Moolenbroek
524*b636d99dSDavid van Moolenbroek static const struct tok isis_iih_circuit_type_values[] = {
525*b636d99dSDavid van Moolenbroek { 1, "Level 1 only"},
526*b636d99dSDavid van Moolenbroek { 2, "Level 2 only"},
527*b636d99dSDavid van Moolenbroek { 3, "Level 1, Level 2"},
528*b636d99dSDavid van Moolenbroek { 0, NULL}
529*b636d99dSDavid van Moolenbroek };
530*b636d99dSDavid van Moolenbroek
531*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TYPE_UNUSED0 0
532*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TYPE_LEVEL_1 1
533*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TYPE_UNUSED2 2
534*b636d99dSDavid van Moolenbroek #define ISIS_LSP_TYPE_LEVEL_2 3
535*b636d99dSDavid van Moolenbroek
536*b636d99dSDavid van Moolenbroek static const struct tok isis_lsp_istype_values[] = {
537*b636d99dSDavid van Moolenbroek { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
538*b636d99dSDavid van Moolenbroek { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
539*b636d99dSDavid van Moolenbroek { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
540*b636d99dSDavid van Moolenbroek { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"},
541*b636d99dSDavid van Moolenbroek { 0, NULL }
542*b636d99dSDavid van Moolenbroek };
543*b636d99dSDavid van Moolenbroek
544*b636d99dSDavid van Moolenbroek /*
545*b636d99dSDavid van Moolenbroek * Katz's point to point adjacency TLV uses codes to tell us the state of
546*b636d99dSDavid van Moolenbroek * the remote adjacency. Enumerate them.
547*b636d99dSDavid van Moolenbroek */
548*b636d99dSDavid van Moolenbroek
549*b636d99dSDavid van Moolenbroek #define ISIS_PTP_ADJ_UP 0
550*b636d99dSDavid van Moolenbroek #define ISIS_PTP_ADJ_INIT 1
551*b636d99dSDavid van Moolenbroek #define ISIS_PTP_ADJ_DOWN 2
552*b636d99dSDavid van Moolenbroek
553*b636d99dSDavid van Moolenbroek static const struct tok isis_ptp_adjancey_values[] = {
554*b636d99dSDavid van Moolenbroek { ISIS_PTP_ADJ_UP, "Up" },
555*b636d99dSDavid van Moolenbroek { ISIS_PTP_ADJ_INIT, "Initializing" },
556*b636d99dSDavid van Moolenbroek { ISIS_PTP_ADJ_DOWN, "Down" },
557*b636d99dSDavid van Moolenbroek { 0, NULL}
558*b636d99dSDavid van Moolenbroek };
559*b636d99dSDavid van Moolenbroek
560*b636d99dSDavid van Moolenbroek struct isis_tlv_ptp_adj {
561*b636d99dSDavid van Moolenbroek uint8_t adjacency_state;
562*b636d99dSDavid van Moolenbroek uint8_t extd_local_circuit_id[4];
563*b636d99dSDavid van Moolenbroek uint8_t neighbor_sysid[SYSTEM_ID_LEN];
564*b636d99dSDavid van Moolenbroek uint8_t neighbor_extd_local_circuit_id[4];
565*b636d99dSDavid van Moolenbroek };
566*b636d99dSDavid van Moolenbroek
567*b636d99dSDavid van Moolenbroek static void osi_print_cksum(netdissect_options *, const uint8_t *pptr, uint16_t checksum,
568*b636d99dSDavid van Moolenbroek u_int checksum_offset, u_int length);
569*b636d99dSDavid van Moolenbroek static int clnp_print(netdissect_options *, const uint8_t *, u_int);
570*b636d99dSDavid van Moolenbroek static void esis_print(netdissect_options *, const uint8_t *, u_int);
571*b636d99dSDavid van Moolenbroek static int isis_print(netdissect_options *, const uint8_t *, u_int);
572*b636d99dSDavid van Moolenbroek
573*b636d99dSDavid van Moolenbroek struct isis_metric_block {
574*b636d99dSDavid van Moolenbroek uint8_t metric_default;
575*b636d99dSDavid van Moolenbroek uint8_t metric_delay;
576*b636d99dSDavid van Moolenbroek uint8_t metric_expense;
577*b636d99dSDavid van Moolenbroek uint8_t metric_error;
578*b636d99dSDavid van Moolenbroek };
579*b636d99dSDavid van Moolenbroek
580*b636d99dSDavid van Moolenbroek struct isis_tlv_is_reach {
581*b636d99dSDavid van Moolenbroek struct isis_metric_block isis_metric_block;
582*b636d99dSDavid van Moolenbroek uint8_t neighbor_nodeid[NODE_ID_LEN];
583*b636d99dSDavid van Moolenbroek };
584*b636d99dSDavid van Moolenbroek
585*b636d99dSDavid van Moolenbroek struct isis_tlv_es_reach {
586*b636d99dSDavid van Moolenbroek struct isis_metric_block isis_metric_block;
587*b636d99dSDavid van Moolenbroek uint8_t neighbor_sysid[SYSTEM_ID_LEN];
588*b636d99dSDavid van Moolenbroek };
589*b636d99dSDavid van Moolenbroek
590*b636d99dSDavid van Moolenbroek struct isis_tlv_ip_reach {
591*b636d99dSDavid van Moolenbroek struct isis_metric_block isis_metric_block;
592*b636d99dSDavid van Moolenbroek uint8_t prefix[4];
593*b636d99dSDavid van Moolenbroek uint8_t mask[4];
594*b636d99dSDavid van Moolenbroek };
595*b636d99dSDavid van Moolenbroek
596*b636d99dSDavid van Moolenbroek static const struct tok isis_is_reach_virtual_values[] = {
597*b636d99dSDavid van Moolenbroek { 0, "IsNotVirtual"},
598*b636d99dSDavid van Moolenbroek { 1, "IsVirtual"},
599*b636d99dSDavid van Moolenbroek { 0, NULL }
600*b636d99dSDavid van Moolenbroek };
601*b636d99dSDavid van Moolenbroek
602*b636d99dSDavid van Moolenbroek static const struct tok isis_restart_flag_values[] = {
603*b636d99dSDavid van Moolenbroek { 0x1, "Restart Request"},
604*b636d99dSDavid van Moolenbroek { 0x2, "Restart Acknowledgement"},
605*b636d99dSDavid van Moolenbroek { 0x4, "Suppress adjacency advertisement"},
606*b636d99dSDavid van Moolenbroek { 0, NULL }
607*b636d99dSDavid van Moolenbroek };
608*b636d99dSDavid van Moolenbroek
609*b636d99dSDavid van Moolenbroek struct isis_common_header {
610*b636d99dSDavid van Moolenbroek uint8_t nlpid;
611*b636d99dSDavid van Moolenbroek uint8_t fixed_len;
612*b636d99dSDavid van Moolenbroek uint8_t version; /* Protocol version */
613*b636d99dSDavid van Moolenbroek uint8_t id_length;
614*b636d99dSDavid van Moolenbroek uint8_t pdu_type; /* 3 MSbits are reserved */
615*b636d99dSDavid van Moolenbroek uint8_t pdu_version; /* Packet format version */
616*b636d99dSDavid van Moolenbroek uint8_t reserved;
617*b636d99dSDavid van Moolenbroek uint8_t max_area;
618*b636d99dSDavid van Moolenbroek };
619*b636d99dSDavid van Moolenbroek
620*b636d99dSDavid van Moolenbroek struct isis_iih_lan_header {
621*b636d99dSDavid van Moolenbroek uint8_t circuit_type;
622*b636d99dSDavid van Moolenbroek uint8_t source_id[SYSTEM_ID_LEN];
623*b636d99dSDavid van Moolenbroek uint8_t holding_time[2];
624*b636d99dSDavid van Moolenbroek uint8_t pdu_len[2];
625*b636d99dSDavid van Moolenbroek uint8_t priority;
626*b636d99dSDavid van Moolenbroek uint8_t lan_id[NODE_ID_LEN];
627*b636d99dSDavid van Moolenbroek };
628*b636d99dSDavid van Moolenbroek
629*b636d99dSDavid van Moolenbroek struct isis_iih_ptp_header {
630*b636d99dSDavid van Moolenbroek uint8_t circuit_type;
631*b636d99dSDavid van Moolenbroek uint8_t source_id[SYSTEM_ID_LEN];
632*b636d99dSDavid van Moolenbroek uint8_t holding_time[2];
633*b636d99dSDavid van Moolenbroek uint8_t pdu_len[2];
634*b636d99dSDavid van Moolenbroek uint8_t circuit_id;
635*b636d99dSDavid van Moolenbroek };
636*b636d99dSDavid van Moolenbroek
637*b636d99dSDavid van Moolenbroek struct isis_lsp_header {
638*b636d99dSDavid van Moolenbroek uint8_t pdu_len[2];
639*b636d99dSDavid van Moolenbroek uint8_t remaining_lifetime[2];
640*b636d99dSDavid van Moolenbroek uint8_t lsp_id[LSP_ID_LEN];
641*b636d99dSDavid van Moolenbroek uint8_t sequence_number[4];
642*b636d99dSDavid van Moolenbroek uint8_t checksum[2];
643*b636d99dSDavid van Moolenbroek uint8_t typeblock;
644*b636d99dSDavid van Moolenbroek };
645*b636d99dSDavid van Moolenbroek
646*b636d99dSDavid van Moolenbroek struct isis_csnp_header {
647*b636d99dSDavid van Moolenbroek uint8_t pdu_len[2];
648*b636d99dSDavid van Moolenbroek uint8_t source_id[NODE_ID_LEN];
649*b636d99dSDavid van Moolenbroek uint8_t start_lsp_id[LSP_ID_LEN];
650*b636d99dSDavid van Moolenbroek uint8_t end_lsp_id[LSP_ID_LEN];
651*b636d99dSDavid van Moolenbroek };
652*b636d99dSDavid van Moolenbroek
653*b636d99dSDavid van Moolenbroek struct isis_psnp_header {
654*b636d99dSDavid van Moolenbroek uint8_t pdu_len[2];
655*b636d99dSDavid van Moolenbroek uint8_t source_id[NODE_ID_LEN];
656*b636d99dSDavid van Moolenbroek };
657*b636d99dSDavid van Moolenbroek
658*b636d99dSDavid van Moolenbroek struct isis_tlv_lsp {
659*b636d99dSDavid van Moolenbroek uint8_t remaining_lifetime[2];
660*b636d99dSDavid van Moolenbroek uint8_t lsp_id[LSP_ID_LEN];
661*b636d99dSDavid van Moolenbroek uint8_t sequence_number[4];
662*b636d99dSDavid van Moolenbroek uint8_t checksum[2];
663*b636d99dSDavid van Moolenbroek };
664*b636d99dSDavid van Moolenbroek
665*b636d99dSDavid van Moolenbroek #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
666*b636d99dSDavid van Moolenbroek #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
667*b636d99dSDavid van Moolenbroek #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
668*b636d99dSDavid van Moolenbroek #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
669*b636d99dSDavid van Moolenbroek #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
670*b636d99dSDavid van Moolenbroek #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
671*b636d99dSDavid van Moolenbroek
isoclns_print(netdissect_options * ndo,const uint8_t * p,u_int length,u_int caplen)672*b636d99dSDavid van Moolenbroek void isoclns_print(netdissect_options *ndo,
673*b636d99dSDavid van Moolenbroek const uint8_t *p, u_int length, u_int caplen)
674*b636d99dSDavid van Moolenbroek {
675*b636d99dSDavid van Moolenbroek if (caplen <= 1) { /* enough bytes on the wire ? */
676*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "|OSI"));
677*b636d99dSDavid van Moolenbroek return;
678*b636d99dSDavid van Moolenbroek }
679*b636d99dSDavid van Moolenbroek
680*b636d99dSDavid van Moolenbroek if (ndo->ndo_eflag)
681*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "OSI NLPID %s (0x%02x): ", tok2str(nlpid_values, "Unknown", *p), *p));
682*b636d99dSDavid van Moolenbroek
683*b636d99dSDavid van Moolenbroek switch (*p) {
684*b636d99dSDavid van Moolenbroek
685*b636d99dSDavid van Moolenbroek case NLPID_CLNP:
686*b636d99dSDavid van Moolenbroek if (!clnp_print(ndo, p, length))
687*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, p, "\n\t", caplen);
688*b636d99dSDavid van Moolenbroek break;
689*b636d99dSDavid van Moolenbroek
690*b636d99dSDavid van Moolenbroek case NLPID_ESIS:
691*b636d99dSDavid van Moolenbroek esis_print(ndo, p, length);
692*b636d99dSDavid van Moolenbroek return;
693*b636d99dSDavid van Moolenbroek
694*b636d99dSDavid van Moolenbroek case NLPID_ISIS:
695*b636d99dSDavid van Moolenbroek if (!isis_print(ndo, p, length))
696*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, p, "\n\t", caplen);
697*b636d99dSDavid van Moolenbroek break;
698*b636d99dSDavid van Moolenbroek
699*b636d99dSDavid van Moolenbroek case NLPID_NULLNS:
700*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length));
701*b636d99dSDavid van Moolenbroek break;
702*b636d99dSDavid van Moolenbroek
703*b636d99dSDavid van Moolenbroek case NLPID_Q933:
704*b636d99dSDavid van Moolenbroek q933_print(ndo, p + 1, length - 1);
705*b636d99dSDavid van Moolenbroek break;
706*b636d99dSDavid van Moolenbroek
707*b636d99dSDavid van Moolenbroek case NLPID_IP:
708*b636d99dSDavid van Moolenbroek ip_print(ndo, p + 1, length - 1);
709*b636d99dSDavid van Moolenbroek break;
710*b636d99dSDavid van Moolenbroek
711*b636d99dSDavid van Moolenbroek case NLPID_IP6:
712*b636d99dSDavid van Moolenbroek ip6_print(ndo, p + 1, length - 1);
713*b636d99dSDavid van Moolenbroek break;
714*b636d99dSDavid van Moolenbroek
715*b636d99dSDavid van Moolenbroek case NLPID_PPP:
716*b636d99dSDavid van Moolenbroek ppp_print(ndo, p + 1, length - 1);
717*b636d99dSDavid van Moolenbroek break;
718*b636d99dSDavid van Moolenbroek
719*b636d99dSDavid van Moolenbroek default:
720*b636d99dSDavid van Moolenbroek if (!ndo->ndo_eflag)
721*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "OSI NLPID 0x%02x unknown", *p));
722*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%slength: %u", ndo->ndo_eflag ? "" : ", ", length));
723*b636d99dSDavid van Moolenbroek if (caplen > 1)
724*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, p, "\n\t", caplen);
725*b636d99dSDavid van Moolenbroek break;
726*b636d99dSDavid van Moolenbroek }
727*b636d99dSDavid van Moolenbroek }
728*b636d99dSDavid van Moolenbroek
729*b636d99dSDavid van Moolenbroek #define CLNP_PDU_ER 1
730*b636d99dSDavid van Moolenbroek #define CLNP_PDU_DT 28
731*b636d99dSDavid van Moolenbroek #define CLNP_PDU_MD 29
732*b636d99dSDavid van Moolenbroek #define CLNP_PDU_ERQ 30
733*b636d99dSDavid van Moolenbroek #define CLNP_PDU_ERP 31
734*b636d99dSDavid van Moolenbroek
735*b636d99dSDavid van Moolenbroek static const struct tok clnp_pdu_values[] = {
736*b636d99dSDavid van Moolenbroek { CLNP_PDU_ER, "Error Report"},
737*b636d99dSDavid van Moolenbroek { CLNP_PDU_MD, "MD"},
738*b636d99dSDavid van Moolenbroek { CLNP_PDU_DT, "Data"},
739*b636d99dSDavid van Moolenbroek { CLNP_PDU_ERQ, "Echo Request"},
740*b636d99dSDavid van Moolenbroek { CLNP_PDU_ERP, "Echo Response"},
741*b636d99dSDavid van Moolenbroek { 0, NULL }
742*b636d99dSDavid van Moolenbroek };
743*b636d99dSDavid van Moolenbroek
744*b636d99dSDavid van Moolenbroek struct clnp_header_t {
745*b636d99dSDavid van Moolenbroek uint8_t nlpid;
746*b636d99dSDavid van Moolenbroek uint8_t length_indicator;
747*b636d99dSDavid van Moolenbroek uint8_t version;
748*b636d99dSDavid van Moolenbroek uint8_t lifetime; /* units of 500ms */
749*b636d99dSDavid van Moolenbroek uint8_t type;
750*b636d99dSDavid van Moolenbroek uint8_t segment_length[2];
751*b636d99dSDavid van Moolenbroek uint8_t cksum[2];
752*b636d99dSDavid van Moolenbroek };
753*b636d99dSDavid van Moolenbroek
754*b636d99dSDavid van Moolenbroek struct clnp_segment_header_t {
755*b636d99dSDavid van Moolenbroek uint8_t data_unit_id[2];
756*b636d99dSDavid van Moolenbroek uint8_t segment_offset[2];
757*b636d99dSDavid van Moolenbroek uint8_t total_length[2];
758*b636d99dSDavid van Moolenbroek };
759*b636d99dSDavid van Moolenbroek
760*b636d99dSDavid van Moolenbroek /*
761*b636d99dSDavid van Moolenbroek * clnp_print
762*b636d99dSDavid van Moolenbroek * Decode CLNP packets. Return 0 on error.
763*b636d99dSDavid van Moolenbroek */
764*b636d99dSDavid van Moolenbroek
765*b636d99dSDavid van Moolenbroek static int
clnp_print(netdissect_options * ndo,const uint8_t * pptr,u_int length)766*b636d99dSDavid van Moolenbroek clnp_print(netdissect_options *ndo,
767*b636d99dSDavid van Moolenbroek const uint8_t *pptr, u_int length)
768*b636d99dSDavid van Moolenbroek {
769*b636d99dSDavid van Moolenbroek const uint8_t *optr,*source_address,*dest_address;
770*b636d99dSDavid van Moolenbroek u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags;
771*b636d99dSDavid van Moolenbroek const struct clnp_header_t *clnp_header;
772*b636d99dSDavid van Moolenbroek const struct clnp_segment_header_t *clnp_segment_header;
773*b636d99dSDavid van Moolenbroek uint8_t rfd_error_major,rfd_error_minor;
774*b636d99dSDavid van Moolenbroek
775*b636d99dSDavid van Moolenbroek clnp_header = (const struct clnp_header_t *) pptr;
776*b636d99dSDavid van Moolenbroek ND_TCHECK(*clnp_header);
777*b636d99dSDavid van Moolenbroek
778*b636d99dSDavid van Moolenbroek li = clnp_header->length_indicator;
779*b636d99dSDavid van Moolenbroek optr = pptr;
780*b636d99dSDavid van Moolenbroek
781*b636d99dSDavid van Moolenbroek if (!ndo->ndo_eflag)
782*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "CLNP"));
783*b636d99dSDavid van Moolenbroek
784*b636d99dSDavid van Moolenbroek /*
785*b636d99dSDavid van Moolenbroek * Sanity checking of the header.
786*b636d99dSDavid van Moolenbroek */
787*b636d99dSDavid van Moolenbroek
788*b636d99dSDavid van Moolenbroek if (clnp_header->version != CLNP_VERSION) {
789*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "version %d packet not supported", clnp_header->version));
790*b636d99dSDavid van Moolenbroek return (0);
791*b636d99dSDavid van Moolenbroek }
792*b636d99dSDavid van Moolenbroek
793*b636d99dSDavid van Moolenbroek /* FIXME further header sanity checking */
794*b636d99dSDavid van Moolenbroek
795*b636d99dSDavid van Moolenbroek clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK;
796*b636d99dSDavid van Moolenbroek clnp_flags = clnp_header->type & CLNP_FLAG_MASK;
797*b636d99dSDavid van Moolenbroek
798*b636d99dSDavid van Moolenbroek pptr += sizeof(struct clnp_header_t);
799*b636d99dSDavid van Moolenbroek li -= sizeof(struct clnp_header_t);
800*b636d99dSDavid van Moolenbroek dest_address_length = *pptr;
801*b636d99dSDavid van Moolenbroek dest_address = pptr + 1;
802*b636d99dSDavid van Moolenbroek
803*b636d99dSDavid van Moolenbroek pptr += (1 + dest_address_length);
804*b636d99dSDavid van Moolenbroek li -= (1 + dest_address_length);
805*b636d99dSDavid van Moolenbroek source_address_length = *pptr;
806*b636d99dSDavid van Moolenbroek source_address = pptr +1;
807*b636d99dSDavid van Moolenbroek
808*b636d99dSDavid van Moolenbroek pptr += (1 + source_address_length);
809*b636d99dSDavid van Moolenbroek li -= (1 + source_address_length);
810*b636d99dSDavid van Moolenbroek
811*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag < 1) {
812*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s > %s, %s, length %u",
813*b636d99dSDavid van Moolenbroek ndo->ndo_eflag ? "" : ", ",
814*b636d99dSDavid van Moolenbroek isonsap_string(source_address, source_address_length),
815*b636d99dSDavid van Moolenbroek isonsap_string(dest_address, dest_address_length),
816*b636d99dSDavid van Moolenbroek tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type),
817*b636d99dSDavid van Moolenbroek length));
818*b636d99dSDavid van Moolenbroek return (1);
819*b636d99dSDavid van Moolenbroek }
820*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
821*b636d99dSDavid van Moolenbroek
822*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x",
823*b636d99dSDavid van Moolenbroek tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type),
824*b636d99dSDavid van Moolenbroek clnp_header->length_indicator,
825*b636d99dSDavid van Moolenbroek clnp_header->version,
826*b636d99dSDavid van Moolenbroek clnp_header->lifetime/2,
827*b636d99dSDavid van Moolenbroek (clnp_header->lifetime%2)*5,
828*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(clnp_header->segment_length),
829*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(clnp_header->cksum)));
830*b636d99dSDavid van Moolenbroek
831*b636d99dSDavid van Moolenbroek osi_print_cksum(ndo, optr, EXTRACT_16BITS(clnp_header->cksum), 7,
832*b636d99dSDavid van Moolenbroek clnp_header->length_indicator);
833*b636d99dSDavid van Moolenbroek
834*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\tFlags [%s]",
835*b636d99dSDavid van Moolenbroek bittok2str(clnp_flag_values, "none", clnp_flags)));
836*b636d99dSDavid van Moolenbroek
837*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\tsource address (length %u): %s\n\tdest address (length %u): %s",
838*b636d99dSDavid van Moolenbroek source_address_length,
839*b636d99dSDavid van Moolenbroek isonsap_string(source_address, source_address_length),
840*b636d99dSDavid van Moolenbroek dest_address_length,
841*b636d99dSDavid van Moolenbroek isonsap_string(dest_address, dest_address_length)));
842*b636d99dSDavid van Moolenbroek
843*b636d99dSDavid van Moolenbroek if (clnp_flags & CLNP_SEGMENT_PART) {
844*b636d99dSDavid van Moolenbroek clnp_segment_header = (const struct clnp_segment_header_t *) pptr;
845*b636d99dSDavid van Moolenbroek ND_TCHECK(*clnp_segment_header);
846*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u",
847*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(clnp_segment_header->data_unit_id),
848*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(clnp_segment_header->segment_offset),
849*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(clnp_segment_header->total_length)));
850*b636d99dSDavid van Moolenbroek pptr+=sizeof(const struct clnp_segment_header_t);
851*b636d99dSDavid van Moolenbroek li-=sizeof(const struct clnp_segment_header_t);
852*b636d99dSDavid van Moolenbroek }
853*b636d99dSDavid van Moolenbroek
854*b636d99dSDavid van Moolenbroek /* now walk the options */
855*b636d99dSDavid van Moolenbroek while (li >= 2) {
856*b636d99dSDavid van Moolenbroek u_int op, opli;
857*b636d99dSDavid van Moolenbroek const uint8_t *tptr;
858*b636d99dSDavid van Moolenbroek
859*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, 2);
860*b636d99dSDavid van Moolenbroek if (li < 2) {
861*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad opts/li"));
862*b636d99dSDavid van Moolenbroek return (0);
863*b636d99dSDavid van Moolenbroek }
864*b636d99dSDavid van Moolenbroek op = *pptr++;
865*b636d99dSDavid van Moolenbroek opli = *pptr++;
866*b636d99dSDavid van Moolenbroek li -= 2;
867*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, opli);
868*b636d99dSDavid van Moolenbroek if (opli > li) {
869*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", opt (%d) too long", op));
870*b636d99dSDavid van Moolenbroek return (0);
871*b636d99dSDavid van Moolenbroek }
872*b636d99dSDavid van Moolenbroek li -= opli;
873*b636d99dSDavid van Moolenbroek tptr = pptr;
874*b636d99dSDavid van Moolenbroek tlen = opli;
875*b636d99dSDavid van Moolenbroek
876*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s Option #%u, length %u, value: ",
877*b636d99dSDavid van Moolenbroek tok2str(clnp_option_values,"Unknown",op),
878*b636d99dSDavid van Moolenbroek op,
879*b636d99dSDavid van Moolenbroek opli));
880*b636d99dSDavid van Moolenbroek
881*b636d99dSDavid van Moolenbroek switch (op) {
882*b636d99dSDavid van Moolenbroek
883*b636d99dSDavid van Moolenbroek
884*b636d99dSDavid van Moolenbroek case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */
885*b636d99dSDavid van Moolenbroek case CLNP_OPTION_SOURCE_ROUTING:
886*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s %s",
887*b636d99dSDavid van Moolenbroek tok2str(clnp_option_sr_rr_values,"Unknown",*tptr),
888*b636d99dSDavid van Moolenbroek tok2str(clnp_option_sr_rr_string_values, "Unknown Option %u", op)));
889*b636d99dSDavid van Moolenbroek nsap_offset=*(tptr+1);
890*b636d99dSDavid van Moolenbroek if (nsap_offset == 0) {
891*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " Bad NSAP offset (0)"));
892*b636d99dSDavid van Moolenbroek break;
893*b636d99dSDavid van Moolenbroek }
894*b636d99dSDavid van Moolenbroek nsap_offset-=1; /* offset to nsap list */
895*b636d99dSDavid van Moolenbroek if (nsap_offset > tlen) {
896*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " Bad NSAP offset (past end of option)"));
897*b636d99dSDavid van Moolenbroek break;
898*b636d99dSDavid van Moolenbroek }
899*b636d99dSDavid van Moolenbroek tptr+=nsap_offset;
900*b636d99dSDavid van Moolenbroek tlen-=nsap_offset;
901*b636d99dSDavid van Moolenbroek while (tlen > 0) {
902*b636d99dSDavid van Moolenbroek source_address_length=*tptr;
903*b636d99dSDavid van Moolenbroek if (tlen < source_address_length+1) {
904*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t NSAP address goes past end of option"));
905*b636d99dSDavid van Moolenbroek break;
906*b636d99dSDavid van Moolenbroek }
907*b636d99dSDavid van Moolenbroek if (source_address_length > 0) {
908*b636d99dSDavid van Moolenbroek source_address=(tptr+1);
909*b636d99dSDavid van Moolenbroek ND_TCHECK2(*source_address, source_address_length);
910*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t NSAP address (length %u): %s",
911*b636d99dSDavid van Moolenbroek source_address_length,
912*b636d99dSDavid van Moolenbroek isonsap_string(source_address, source_address_length)));
913*b636d99dSDavid van Moolenbroek }
914*b636d99dSDavid van Moolenbroek tlen-=source_address_length+1;
915*b636d99dSDavid van Moolenbroek }
916*b636d99dSDavid van Moolenbroek break;
917*b636d99dSDavid van Moolenbroek
918*b636d99dSDavid van Moolenbroek case CLNP_OPTION_PRIORITY:
919*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "0x%1x", *tptr&0x0f));
920*b636d99dSDavid van Moolenbroek break;
921*b636d99dSDavid van Moolenbroek
922*b636d99dSDavid van Moolenbroek case CLNP_OPTION_QOS_MAINTENANCE:
923*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Format Code: %s",
924*b636d99dSDavid van Moolenbroek tok2str(clnp_option_scope_values, "Reserved", *tptr&CLNP_OPTION_SCOPE_MASK)));
925*b636d99dSDavid van Moolenbroek
926*b636d99dSDavid van Moolenbroek if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL)
927*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t QoS Flags [%s]",
928*b636d99dSDavid van Moolenbroek bittok2str(clnp_option_qos_global_values,
929*b636d99dSDavid van Moolenbroek "none",
930*b636d99dSDavid van Moolenbroek *tptr&CLNP_OPTION_OPTION_QOS_MASK)));
931*b636d99dSDavid van Moolenbroek break;
932*b636d99dSDavid van Moolenbroek
933*b636d99dSDavid van Moolenbroek case CLNP_OPTION_SECURITY:
934*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Format Code: %s, Security-Level %u",
935*b636d99dSDavid van Moolenbroek tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK),
936*b636d99dSDavid van Moolenbroek *(tptr+1)));
937*b636d99dSDavid van Moolenbroek break;
938*b636d99dSDavid van Moolenbroek
939*b636d99dSDavid van Moolenbroek case CLNP_OPTION_DISCARD_REASON:
940*b636d99dSDavid van Moolenbroek rfd_error_major = (*tptr&0xf0) >> 4;
941*b636d99dSDavid van Moolenbroek rfd_error_minor = *tptr&0x0f;
942*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Class: %s Error (0x%01x), %s (0x%01x)",
943*b636d99dSDavid van Moolenbroek tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major),
944*b636d99dSDavid van Moolenbroek rfd_error_major,
945*b636d99dSDavid van Moolenbroek tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor),
946*b636d99dSDavid van Moolenbroek rfd_error_minor));
947*b636d99dSDavid van Moolenbroek break;
948*b636d99dSDavid van Moolenbroek
949*b636d99dSDavid van Moolenbroek case CLNP_OPTION_PADDING:
950*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "padding data"));
951*b636d99dSDavid van Moolenbroek break;
952*b636d99dSDavid van Moolenbroek
953*b636d99dSDavid van Moolenbroek /*
954*b636d99dSDavid van Moolenbroek * FIXME those are the defined Options that lack a decoder
955*b636d99dSDavid van Moolenbroek * you are welcome to contribute code ;-)
956*b636d99dSDavid van Moolenbroek */
957*b636d99dSDavid van Moolenbroek
958*b636d99dSDavid van Moolenbroek default:
959*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, tptr, "\n\t ", opli);
960*b636d99dSDavid van Moolenbroek break;
961*b636d99dSDavid van Moolenbroek }
962*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1)
963*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, pptr, "\n\t ", opli);
964*b636d99dSDavid van Moolenbroek pptr += opli;
965*b636d99dSDavid van Moolenbroek }
966*b636d99dSDavid van Moolenbroek
967*b636d99dSDavid van Moolenbroek switch (clnp_pdu_type) {
968*b636d99dSDavid van Moolenbroek
969*b636d99dSDavid van Moolenbroek case CLNP_PDU_ER: /* fall through */
970*b636d99dSDavid van Moolenbroek case CLNP_PDU_ERP:
971*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
972*b636d99dSDavid van Moolenbroek if (*(pptr) == NLPID_CLNP) {
973*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t-----original packet-----\n\t"));
974*b636d99dSDavid van Moolenbroek /* FIXME recursion protection */
975*b636d99dSDavid van Moolenbroek clnp_print(ndo, pptr, length - clnp_header->length_indicator);
976*b636d99dSDavid van Moolenbroek break;
977*b636d99dSDavid van Moolenbroek }
978*b636d99dSDavid van Moolenbroek
979*b636d99dSDavid van Moolenbroek case CLNP_PDU_DT:
980*b636d99dSDavid van Moolenbroek case CLNP_PDU_MD:
981*b636d99dSDavid van Moolenbroek case CLNP_PDU_ERQ:
982*b636d99dSDavid van Moolenbroek
983*b636d99dSDavid van Moolenbroek default:
984*b636d99dSDavid van Moolenbroek /* dump the PDU specific data */
985*b636d99dSDavid van Moolenbroek if (length-(pptr-optr) > 0) {
986*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t undecoded non-header data, length %u", length-clnp_header->length_indicator));
987*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, pptr, "\n\t ", length - (pptr - optr));
988*b636d99dSDavid van Moolenbroek }
989*b636d99dSDavid van Moolenbroek }
990*b636d99dSDavid van Moolenbroek
991*b636d99dSDavid van Moolenbroek return (1);
992*b636d99dSDavid van Moolenbroek
993*b636d99dSDavid van Moolenbroek trunc:
994*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|clnp]"));
995*b636d99dSDavid van Moolenbroek return (1);
996*b636d99dSDavid van Moolenbroek
997*b636d99dSDavid van Moolenbroek }
998*b636d99dSDavid van Moolenbroek
999*b636d99dSDavid van Moolenbroek
1000*b636d99dSDavid van Moolenbroek #define ESIS_PDU_REDIRECT 6
1001*b636d99dSDavid van Moolenbroek #define ESIS_PDU_ESH 2
1002*b636d99dSDavid van Moolenbroek #define ESIS_PDU_ISH 4
1003*b636d99dSDavid van Moolenbroek
1004*b636d99dSDavid van Moolenbroek static const struct tok esis_pdu_values[] = {
1005*b636d99dSDavid van Moolenbroek { ESIS_PDU_REDIRECT, "redirect"},
1006*b636d99dSDavid van Moolenbroek { ESIS_PDU_ESH, "ESH"},
1007*b636d99dSDavid van Moolenbroek { ESIS_PDU_ISH, "ISH"},
1008*b636d99dSDavid van Moolenbroek { 0, NULL }
1009*b636d99dSDavid van Moolenbroek };
1010*b636d99dSDavid van Moolenbroek
1011*b636d99dSDavid van Moolenbroek struct esis_header_t {
1012*b636d99dSDavid van Moolenbroek uint8_t nlpid;
1013*b636d99dSDavid van Moolenbroek uint8_t length_indicator;
1014*b636d99dSDavid van Moolenbroek uint8_t version;
1015*b636d99dSDavid van Moolenbroek uint8_t reserved;
1016*b636d99dSDavid van Moolenbroek uint8_t type;
1017*b636d99dSDavid van Moolenbroek uint8_t holdtime[2];
1018*b636d99dSDavid van Moolenbroek uint8_t cksum[2];
1019*b636d99dSDavid van Moolenbroek };
1020*b636d99dSDavid van Moolenbroek
1021*b636d99dSDavid van Moolenbroek static void
esis_print(netdissect_options * ndo,const uint8_t * pptr,u_int length)1022*b636d99dSDavid van Moolenbroek esis_print(netdissect_options *ndo,
1023*b636d99dSDavid van Moolenbroek const uint8_t *pptr, u_int length)
1024*b636d99dSDavid van Moolenbroek {
1025*b636d99dSDavid van Moolenbroek const uint8_t *optr;
1026*b636d99dSDavid van Moolenbroek u_int li,esis_pdu_type,source_address_length, source_address_number;
1027*b636d99dSDavid van Moolenbroek const struct esis_header_t *esis_header;
1028*b636d99dSDavid van Moolenbroek
1029*b636d99dSDavid van Moolenbroek if (!ndo->ndo_eflag)
1030*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ES-IS"));
1031*b636d99dSDavid van Moolenbroek
1032*b636d99dSDavid van Moolenbroek if (length <= 2) {
1033*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ndo->ndo_qflag ? "bad pkt!" : "no header at all!"));
1034*b636d99dSDavid van Moolenbroek return;
1035*b636d99dSDavid van Moolenbroek }
1036*b636d99dSDavid van Moolenbroek
1037*b636d99dSDavid van Moolenbroek esis_header = (const struct esis_header_t *) pptr;
1038*b636d99dSDavid van Moolenbroek ND_TCHECK(*esis_header);
1039*b636d99dSDavid van Moolenbroek li = esis_header->length_indicator;
1040*b636d99dSDavid van Moolenbroek optr = pptr;
1041*b636d99dSDavid van Moolenbroek
1042*b636d99dSDavid van Moolenbroek /*
1043*b636d99dSDavid van Moolenbroek * Sanity checking of the header.
1044*b636d99dSDavid van Moolenbroek */
1045*b636d99dSDavid van Moolenbroek
1046*b636d99dSDavid van Moolenbroek if (esis_header->nlpid != NLPID_ESIS) {
1047*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " nlpid 0x%02x packet not supported", esis_header->nlpid));
1048*b636d99dSDavid van Moolenbroek return;
1049*b636d99dSDavid van Moolenbroek }
1050*b636d99dSDavid van Moolenbroek
1051*b636d99dSDavid van Moolenbroek if (esis_header->version != ESIS_VERSION) {
1052*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " version %d packet not supported", esis_header->version));
1053*b636d99dSDavid van Moolenbroek return;
1054*b636d99dSDavid van Moolenbroek }
1055*b636d99dSDavid van Moolenbroek
1056*b636d99dSDavid van Moolenbroek if (li > length) {
1057*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " length indicator(%d) > PDU size (%d)!", li, length));
1058*b636d99dSDavid van Moolenbroek return;
1059*b636d99dSDavid van Moolenbroek }
1060*b636d99dSDavid van Moolenbroek
1061*b636d99dSDavid van Moolenbroek if (li < sizeof(struct esis_header_t) + 2) {
1062*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " length indicator < min PDU size %d:", li));
1063*b636d99dSDavid van Moolenbroek while (pptr < ndo->ndo_snapend)
1064*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%02X", *pptr++));
1065*b636d99dSDavid van Moolenbroek return;
1066*b636d99dSDavid van Moolenbroek }
1067*b636d99dSDavid van Moolenbroek
1068*b636d99dSDavid van Moolenbroek esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK;
1069*b636d99dSDavid van Moolenbroek
1070*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag < 1) {
1071*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s, length %u",
1072*b636d99dSDavid van Moolenbroek ndo->ndo_eflag ? "" : ", ",
1073*b636d99dSDavid van Moolenbroek tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type),
1074*b636d99dSDavid van Moolenbroek length));
1075*b636d99dSDavid van Moolenbroek return;
1076*b636d99dSDavid van Moolenbroek } else
1077*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%slength %u\n\t%s (%u)",
1078*b636d99dSDavid van Moolenbroek ndo->ndo_eflag ? "" : ", ",
1079*b636d99dSDavid van Moolenbroek length,
1080*b636d99dSDavid van Moolenbroek tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type),
1081*b636d99dSDavid van Moolenbroek esis_pdu_type));
1082*b636d99dSDavid van Moolenbroek
1083*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ));
1084*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)));
1085*b636d99dSDavid van Moolenbroek
1086*b636d99dSDavid van Moolenbroek osi_print_cksum(ndo, pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
1087*b636d99dSDavid van Moolenbroek
1088*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", holding time: %us, length indicator: %u",
1089*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(esis_header->holdtime), li));
1090*b636d99dSDavid van Moolenbroek
1091*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1)
1092*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, optr, "\n\t", sizeof(struct esis_header_t));
1093*b636d99dSDavid van Moolenbroek
1094*b636d99dSDavid van Moolenbroek pptr += sizeof(struct esis_header_t);
1095*b636d99dSDavid van Moolenbroek li -= sizeof(struct esis_header_t);
1096*b636d99dSDavid van Moolenbroek
1097*b636d99dSDavid van Moolenbroek switch (esis_pdu_type) {
1098*b636d99dSDavid van Moolenbroek case ESIS_PDU_REDIRECT: {
1099*b636d99dSDavid van Moolenbroek const uint8_t *dst, *snpa, *neta;
1100*b636d99dSDavid van Moolenbroek u_int dstl, snpal, netal;
1101*b636d99dSDavid van Moolenbroek
1102*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1103*b636d99dSDavid van Moolenbroek if (li < 1) {
1104*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1105*b636d99dSDavid van Moolenbroek return;
1106*b636d99dSDavid van Moolenbroek }
1107*b636d99dSDavid van Moolenbroek dstl = *pptr;
1108*b636d99dSDavid van Moolenbroek pptr++;
1109*b636d99dSDavid van Moolenbroek li--;
1110*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, dstl);
1111*b636d99dSDavid van Moolenbroek if (li < dstl) {
1112*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1113*b636d99dSDavid van Moolenbroek return;
1114*b636d99dSDavid van Moolenbroek }
1115*b636d99dSDavid van Moolenbroek dst = pptr;
1116*b636d99dSDavid van Moolenbroek pptr += dstl;
1117*b636d99dSDavid van Moolenbroek li -= dstl;
1118*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s", isonsap_string(dst, dstl)));
1119*b636d99dSDavid van Moolenbroek
1120*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1121*b636d99dSDavid van Moolenbroek if (li < 1) {
1122*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1123*b636d99dSDavid van Moolenbroek return;
1124*b636d99dSDavid van Moolenbroek }
1125*b636d99dSDavid van Moolenbroek snpal = *pptr;
1126*b636d99dSDavid van Moolenbroek pptr++;
1127*b636d99dSDavid van Moolenbroek li--;
1128*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, snpal);
1129*b636d99dSDavid van Moolenbroek if (li < snpal) {
1130*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1131*b636d99dSDavid van Moolenbroek return;
1132*b636d99dSDavid van Moolenbroek }
1133*b636d99dSDavid van Moolenbroek snpa = pptr;
1134*b636d99dSDavid van Moolenbroek pptr += snpal;
1135*b636d99dSDavid van Moolenbroek li -= snpal;
1136*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1137*b636d99dSDavid van Moolenbroek if (li < 1) {
1138*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1139*b636d99dSDavid van Moolenbroek return;
1140*b636d99dSDavid van Moolenbroek }
1141*b636d99dSDavid van Moolenbroek netal = *pptr;
1142*b636d99dSDavid van Moolenbroek pptr++;
1143*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, netal);
1144*b636d99dSDavid van Moolenbroek if (li < netal) {
1145*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad redirect/li"));
1146*b636d99dSDavid van Moolenbroek return;
1147*b636d99dSDavid van Moolenbroek }
1148*b636d99dSDavid van Moolenbroek neta = pptr;
1149*b636d99dSDavid van Moolenbroek pptr += netal;
1150*b636d99dSDavid van Moolenbroek li -= netal;
1151*b636d99dSDavid van Moolenbroek
1152*b636d99dSDavid van Moolenbroek if (netal == 0)
1153*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s", etheraddr_string(ndo, snpa)));
1154*b636d99dSDavid van Moolenbroek else
1155*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s", isonsap_string(neta, netal)));
1156*b636d99dSDavid van Moolenbroek break;
1157*b636d99dSDavid van Moolenbroek }
1158*b636d99dSDavid van Moolenbroek
1159*b636d99dSDavid van Moolenbroek case ESIS_PDU_ESH:
1160*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1161*b636d99dSDavid van Moolenbroek if (li < 1) {
1162*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad esh/li"));
1163*b636d99dSDavid van Moolenbroek return;
1164*b636d99dSDavid van Moolenbroek }
1165*b636d99dSDavid van Moolenbroek source_address_number = *pptr;
1166*b636d99dSDavid van Moolenbroek pptr++;
1167*b636d99dSDavid van Moolenbroek li--;
1168*b636d99dSDavid van Moolenbroek
1169*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Number of Source Addresses: %u", source_address_number));
1170*b636d99dSDavid van Moolenbroek
1171*b636d99dSDavid van Moolenbroek while (source_address_number > 0) {
1172*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1173*b636d99dSDavid van Moolenbroek if (li < 1) {
1174*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad esh/li"));
1175*b636d99dSDavid van Moolenbroek return;
1176*b636d99dSDavid van Moolenbroek }
1177*b636d99dSDavid van Moolenbroek source_address_length = *pptr;
1178*b636d99dSDavid van Moolenbroek pptr++;
1179*b636d99dSDavid van Moolenbroek li--;
1180*b636d99dSDavid van Moolenbroek
1181*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, source_address_length);
1182*b636d99dSDavid van Moolenbroek if (li < source_address_length) {
1183*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad esh/li"));
1184*b636d99dSDavid van Moolenbroek return;
1185*b636d99dSDavid van Moolenbroek }
1186*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t NET (length: %u): %s",
1187*b636d99dSDavid van Moolenbroek source_address_length,
1188*b636d99dSDavid van Moolenbroek isonsap_string(pptr, source_address_length)));
1189*b636d99dSDavid van Moolenbroek pptr += source_address_length;
1190*b636d99dSDavid van Moolenbroek li -= source_address_length;
1191*b636d99dSDavid van Moolenbroek source_address_number--;
1192*b636d99dSDavid van Moolenbroek }
1193*b636d99dSDavid van Moolenbroek
1194*b636d99dSDavid van Moolenbroek break;
1195*b636d99dSDavid van Moolenbroek
1196*b636d99dSDavid van Moolenbroek case ESIS_PDU_ISH: {
1197*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1198*b636d99dSDavid van Moolenbroek if (li < 1) {
1199*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad ish/li"));
1200*b636d99dSDavid van Moolenbroek return;
1201*b636d99dSDavid van Moolenbroek }
1202*b636d99dSDavid van Moolenbroek source_address_length = *pptr;
1203*b636d99dSDavid van Moolenbroek pptr++;
1204*b636d99dSDavid van Moolenbroek li--;
1205*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, source_address_length);
1206*b636d99dSDavid van Moolenbroek if (li < source_address_length) {
1207*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad ish/li"));
1208*b636d99dSDavid van Moolenbroek return;
1209*b636d99dSDavid van Moolenbroek }
1210*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length)));
1211*b636d99dSDavid van Moolenbroek pptr += source_address_length;
1212*b636d99dSDavid van Moolenbroek li -= source_address_length;
1213*b636d99dSDavid van Moolenbroek break;
1214*b636d99dSDavid van Moolenbroek }
1215*b636d99dSDavid van Moolenbroek
1216*b636d99dSDavid van Moolenbroek default:
1217*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag <= 1) {
1218*b636d99dSDavid van Moolenbroek if (pptr < ndo->ndo_snapend)
1219*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, pptr, "\n\t ", ndo->ndo_snapend - pptr);
1220*b636d99dSDavid van Moolenbroek }
1221*b636d99dSDavid van Moolenbroek return;
1222*b636d99dSDavid van Moolenbroek }
1223*b636d99dSDavid van Moolenbroek
1224*b636d99dSDavid van Moolenbroek /* now walk the options */
1225*b636d99dSDavid van Moolenbroek while (li != 0) {
1226*b636d99dSDavid van Moolenbroek u_int op, opli;
1227*b636d99dSDavid van Moolenbroek const uint8_t *tptr;
1228*b636d99dSDavid van Moolenbroek
1229*b636d99dSDavid van Moolenbroek if (li < 2) {
1230*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bad opts/li"));
1231*b636d99dSDavid van Moolenbroek return;
1232*b636d99dSDavid van Moolenbroek }
1233*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, 2);
1234*b636d99dSDavid van Moolenbroek op = *pptr++;
1235*b636d99dSDavid van Moolenbroek opli = *pptr++;
1236*b636d99dSDavid van Moolenbroek li -= 2;
1237*b636d99dSDavid van Moolenbroek if (opli > li) {
1238*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", opt (%d) too long", op));
1239*b636d99dSDavid van Moolenbroek return;
1240*b636d99dSDavid van Moolenbroek }
1241*b636d99dSDavid van Moolenbroek li -= opli;
1242*b636d99dSDavid van Moolenbroek tptr = pptr;
1243*b636d99dSDavid van Moolenbroek
1244*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s Option #%u, length %u, value: ",
1245*b636d99dSDavid van Moolenbroek tok2str(esis_option_values,"Unknown",op),
1246*b636d99dSDavid van Moolenbroek op,
1247*b636d99dSDavid van Moolenbroek opli));
1248*b636d99dSDavid van Moolenbroek
1249*b636d99dSDavid van Moolenbroek switch (op) {
1250*b636d99dSDavid van Moolenbroek
1251*b636d99dSDavid van Moolenbroek case ESIS_OPTION_ES_CONF_TIME:
1252*b636d99dSDavid van Moolenbroek if (opli == 2) {
1253*b636d99dSDavid van Moolenbroek ND_TCHECK2(*pptr, 2);
1254*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%us", EXTRACT_16BITS(tptr)));
1255*b636d99dSDavid van Moolenbroek } else
1256*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "(bad length)"));
1257*b636d99dSDavid van Moolenbroek break;
1258*b636d99dSDavid van Moolenbroek
1259*b636d99dSDavid van Moolenbroek case ESIS_OPTION_PROTOCOLS:
1260*b636d99dSDavid van Moolenbroek while (opli>0) {
1261*b636d99dSDavid van Moolenbroek ND_TCHECK(*pptr);
1262*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s (0x%02x)",
1263*b636d99dSDavid van Moolenbroek tok2str(nlpid_values,
1264*b636d99dSDavid van Moolenbroek "unknown",
1265*b636d99dSDavid van Moolenbroek *tptr),
1266*b636d99dSDavid van Moolenbroek *tptr));
1267*b636d99dSDavid van Moolenbroek if (opli>1) /* further NPLIDs ? - put comma */
1268*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", "));
1269*b636d99dSDavid van Moolenbroek tptr++;
1270*b636d99dSDavid van Moolenbroek opli--;
1271*b636d99dSDavid van Moolenbroek }
1272*b636d99dSDavid van Moolenbroek break;
1273*b636d99dSDavid van Moolenbroek
1274*b636d99dSDavid van Moolenbroek /*
1275*b636d99dSDavid van Moolenbroek * FIXME those are the defined Options that lack a decoder
1276*b636d99dSDavid van Moolenbroek * you are welcome to contribute code ;-)
1277*b636d99dSDavid van Moolenbroek */
1278*b636d99dSDavid van Moolenbroek
1279*b636d99dSDavid van Moolenbroek case ESIS_OPTION_QOS_MAINTENANCE:
1280*b636d99dSDavid van Moolenbroek case ESIS_OPTION_SECURITY:
1281*b636d99dSDavid van Moolenbroek case ESIS_OPTION_PRIORITY:
1282*b636d99dSDavid van Moolenbroek case ESIS_OPTION_ADDRESS_MASK:
1283*b636d99dSDavid van Moolenbroek case ESIS_OPTION_SNPA_MASK:
1284*b636d99dSDavid van Moolenbroek
1285*b636d99dSDavid van Moolenbroek default:
1286*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, tptr, "\n\t ", opli);
1287*b636d99dSDavid van Moolenbroek break;
1288*b636d99dSDavid van Moolenbroek }
1289*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1)
1290*b636d99dSDavid van Moolenbroek print_unknown_data(ndo, pptr, "\n\t ", opli);
1291*b636d99dSDavid van Moolenbroek pptr += opli;
1292*b636d99dSDavid van Moolenbroek }
1293*b636d99dSDavid van Moolenbroek trunc:
1294*b636d99dSDavid van Moolenbroek return;
1295*b636d99dSDavid van Moolenbroek }
1296*b636d99dSDavid van Moolenbroek
1297*b636d99dSDavid van Moolenbroek static void
isis_print_mcid(netdissect_options * ndo,const struct isis_spb_mcid * mcid)1298*b636d99dSDavid van Moolenbroek isis_print_mcid(netdissect_options *ndo,
1299*b636d99dSDavid van Moolenbroek const struct isis_spb_mcid *mcid)
1300*b636d99dSDavid van Moolenbroek {
1301*b636d99dSDavid van Moolenbroek int i;
1302*b636d99dSDavid van Moolenbroek
1303*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ID: %d, Name: ", mcid->format_id));
1304*b636d99dSDavid van Moolenbroek
1305*b636d99dSDavid van Moolenbroek for(i=0; i<32; i++)
1306*b636d99dSDavid van Moolenbroek {
1307*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%c", mcid->name[i]));
1308*b636d99dSDavid van Moolenbroek if(mcid->name[i] == '\0')
1309*b636d99dSDavid van Moolenbroek break;
1310*b636d99dSDavid van Moolenbroek }
1311*b636d99dSDavid van Moolenbroek
1312*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Lvl: %d", EXTRACT_16BITS(mcid->revision_lvl)));
1313*b636d99dSDavid van Moolenbroek
1314*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Digest: "));
1315*b636d99dSDavid van Moolenbroek
1316*b636d99dSDavid van Moolenbroek for(i=0;i<16;i++)
1317*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%.2x ", mcid->digest[i]));
1318*b636d99dSDavid van Moolenbroek }
1319*b636d99dSDavid van Moolenbroek
1320*b636d99dSDavid van Moolenbroek static int
isis_print_mt_port_cap_subtlv(netdissect_options * ndo,const uint8_t * tptr,int len)1321*b636d99dSDavid van Moolenbroek isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
1322*b636d99dSDavid van Moolenbroek const uint8_t *tptr, int len)
1323*b636d99dSDavid van Moolenbroek {
1324*b636d99dSDavid van Moolenbroek int stlv_type, stlv_len;
1325*b636d99dSDavid van Moolenbroek const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
1326*b636d99dSDavid van Moolenbroek int i;
1327*b636d99dSDavid van Moolenbroek
1328*b636d99dSDavid van Moolenbroek while (len > 0)
1329*b636d99dSDavid van Moolenbroek {
1330*b636d99dSDavid van Moolenbroek stlv_type = *(tptr++);
1331*b636d99dSDavid van Moolenbroek stlv_len = *(tptr++);
1332*b636d99dSDavid van Moolenbroek
1333*b636d99dSDavid van Moolenbroek /* first lets see if we know the subTLVs name*/
1334*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u",
1335*b636d99dSDavid van Moolenbroek tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type),
1336*b636d99dSDavid van Moolenbroek stlv_type,
1337*b636d99dSDavid van Moolenbroek stlv_len));
1338*b636d99dSDavid van Moolenbroek
1339*b636d99dSDavid van Moolenbroek /*len -= TLV_TYPE_LEN_OFFSET;*/
1340*b636d99dSDavid van Moolenbroek len = len -2;
1341*b636d99dSDavid van Moolenbroek
1342*b636d99dSDavid van Moolenbroek switch (stlv_type)
1343*b636d99dSDavid van Moolenbroek {
1344*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPB_MCID:
1345*b636d99dSDavid van Moolenbroek {
1346*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN))
1347*b636d99dSDavid van Moolenbroek goto trunctlv;
1348*b636d99dSDavid van Moolenbroek
1349*b636d99dSDavid van Moolenbroek subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr;
1350*b636d99dSDavid van Moolenbroek
1351*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t MCID: "));
1352*b636d99dSDavid van Moolenbroek isis_print_mcid(ndo, &(subtlv_spb_mcid->mcid));
1353*b636d99dSDavid van Moolenbroek
1354*b636d99dSDavid van Moolenbroek /*tptr += SPB_MCID_MIN_LEN;
1355*b636d99dSDavid van Moolenbroek len -= SPB_MCID_MIN_LEN; */
1356*b636d99dSDavid van Moolenbroek
1357*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t AUX-MCID: "));
1358*b636d99dSDavid van Moolenbroek isis_print_mcid(ndo, &(subtlv_spb_mcid->aux_mcid));
1359*b636d99dSDavid van Moolenbroek
1360*b636d99dSDavid van Moolenbroek /*tptr += SPB_MCID_MIN_LEN;
1361*b636d99dSDavid van Moolenbroek len -= SPB_MCID_MIN_LEN; */
1362*b636d99dSDavid van Moolenbroek tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
1363*b636d99dSDavid van Moolenbroek len = len - sizeof(struct isis_subtlv_spb_mcid);
1364*b636d99dSDavid van Moolenbroek
1365*b636d99dSDavid van Moolenbroek break;
1366*b636d99dSDavid van Moolenbroek }
1367*b636d99dSDavid van Moolenbroek
1368*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPB_DIGEST:
1369*b636d99dSDavid van Moolenbroek {
1370*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN))
1371*b636d99dSDavid van Moolenbroek goto trunctlv;
1372*b636d99dSDavid van Moolenbroek
1373*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
1374*b636d99dSDavid van Moolenbroek (*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
1375*b636d99dSDavid van Moolenbroek ((*(tptr) >> 2) & 0x03), ((*tptr) & 0x03)));
1376*b636d99dSDavid van Moolenbroek
1377*b636d99dSDavid van Moolenbroek tptr++;
1378*b636d99dSDavid van Moolenbroek
1379*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Digest: "));
1380*b636d99dSDavid van Moolenbroek
1381*b636d99dSDavid van Moolenbroek for(i=1;i<=8; i++)
1382*b636d99dSDavid van Moolenbroek {
1383*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%08x ", EXTRACT_32BITS(tptr)));
1384*b636d99dSDavid van Moolenbroek if (i%4 == 0 && i != 8)
1385*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t "));
1386*b636d99dSDavid van Moolenbroek tptr = tptr + 4;
1387*b636d99dSDavid van Moolenbroek }
1388*b636d99dSDavid van Moolenbroek
1389*b636d99dSDavid van Moolenbroek len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
1390*b636d99dSDavid van Moolenbroek
1391*b636d99dSDavid van Moolenbroek break;
1392*b636d99dSDavid van Moolenbroek }
1393*b636d99dSDavid van Moolenbroek
1394*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPB_BVID:
1395*b636d99dSDavid van Moolenbroek {
1396*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), stlv_len))
1397*b636d99dSDavid van Moolenbroek goto trunctlv;
1398*b636d99dSDavid van Moolenbroek
1399*b636d99dSDavid van Moolenbroek while (len)
1400*b636d99dSDavid van Moolenbroek {
1401*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN))
1402*b636d99dSDavid van Moolenbroek goto trunctlv;
1403*b636d99dSDavid van Moolenbroek
1404*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t ECT: %08x",
1405*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tptr)));
1406*b636d99dSDavid van Moolenbroek
1407*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1408*b636d99dSDavid van Moolenbroek
1409*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " BVID: %d, U:%01x M:%01x ",
1410*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS (tptr) >> 4) ,
1411*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS (tptr) >> 3) & 0x01,
1412*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS (tptr) >> 2) & 0x01));
1413*b636d99dSDavid van Moolenbroek
1414*b636d99dSDavid van Moolenbroek tptr = tptr + 2;
1415*b636d99dSDavid van Moolenbroek len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
1416*b636d99dSDavid van Moolenbroek }
1417*b636d99dSDavid van Moolenbroek
1418*b636d99dSDavid van Moolenbroek break;
1419*b636d99dSDavid van Moolenbroek }
1420*b636d99dSDavid van Moolenbroek
1421*b636d99dSDavid van Moolenbroek default:
1422*b636d99dSDavid van Moolenbroek break;
1423*b636d99dSDavid van Moolenbroek }
1424*b636d99dSDavid van Moolenbroek }
1425*b636d99dSDavid van Moolenbroek
1426*b636d99dSDavid van Moolenbroek return 0;
1427*b636d99dSDavid van Moolenbroek
1428*b636d99dSDavid van Moolenbroek trunctlv:
1429*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
1430*b636d99dSDavid van Moolenbroek return(1);
1431*b636d99dSDavid van Moolenbroek }
1432*b636d99dSDavid van Moolenbroek
1433*b636d99dSDavid van Moolenbroek static int
isis_print_mt_capability_subtlv(netdissect_options * ndo,const uint8_t * tptr,int len)1434*b636d99dSDavid van Moolenbroek isis_print_mt_capability_subtlv(netdissect_options *ndo,
1435*b636d99dSDavid van Moolenbroek const uint8_t *tptr, int len)
1436*b636d99dSDavid van Moolenbroek {
1437*b636d99dSDavid van Moolenbroek int stlv_type, stlv_len, tmp;
1438*b636d99dSDavid van Moolenbroek
1439*b636d99dSDavid van Moolenbroek while (len > 0)
1440*b636d99dSDavid van Moolenbroek {
1441*b636d99dSDavid van Moolenbroek stlv_type = *(tptr++);
1442*b636d99dSDavid van Moolenbroek stlv_len = *(tptr++);
1443*b636d99dSDavid van Moolenbroek
1444*b636d99dSDavid van Moolenbroek /* first lets see if we know the subTLVs name*/
1445*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s subTLV #%u, length: %u",
1446*b636d99dSDavid van Moolenbroek tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type),
1447*b636d99dSDavid van Moolenbroek stlv_type,
1448*b636d99dSDavid van Moolenbroek stlv_len));
1449*b636d99dSDavid van Moolenbroek
1450*b636d99dSDavid van Moolenbroek len = len - 2;
1451*b636d99dSDavid van Moolenbroek
1452*b636d99dSDavid van Moolenbroek switch (stlv_type)
1453*b636d99dSDavid van Moolenbroek {
1454*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPB_INSTANCE:
1455*b636d99dSDavid van Moolenbroek
1456*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN))
1457*b636d99dSDavid van Moolenbroek goto trunctlv;
1458*b636d99dSDavid van Moolenbroek
1459*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
1460*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1461*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " %08x", EXTRACT_32BITS(tptr)));
1462*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1463*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Path Cost: %08x", EXTRACT_32BITS(tptr)));
1464*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1465*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Prio: %d", EXTRACT_16BITS(tptr)));
1466*b636d99dSDavid van Moolenbroek tptr = tptr + 2;
1467*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t RES: %d",
1468*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tptr) >> 5));
1469*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", V: %d",
1470*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS(tptr) >> 4) & 0x0001));
1471*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", SPSource-ID: %d",
1472*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(tptr) & 0x000fffff)));
1473*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1474*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", No of Trees: %x", *(tptr)));
1475*b636d99dSDavid van Moolenbroek
1476*b636d99dSDavid van Moolenbroek tmp = *(tptr++);
1477*b636d99dSDavid van Moolenbroek
1478*b636d99dSDavid van Moolenbroek len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
1479*b636d99dSDavid van Moolenbroek
1480*b636d99dSDavid van Moolenbroek while (tmp)
1481*b636d99dSDavid van Moolenbroek {
1482*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN))
1483*b636d99dSDavid van Moolenbroek goto trunctlv;
1484*b636d99dSDavid van Moolenbroek
1485*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
1486*b636d99dSDavid van Moolenbroek *(tptr) >> 7, (*(tptr) >> 6) & 0x01,
1487*b636d99dSDavid van Moolenbroek (*(tptr) >> 5) & 0x01, (*(tptr) & 0x1f)));
1488*b636d99dSDavid van Moolenbroek
1489*b636d99dSDavid van Moolenbroek tptr++;
1490*b636d99dSDavid van Moolenbroek
1491*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", ECT: %08x", EXTRACT_32BITS(tptr)));
1492*b636d99dSDavid van Moolenbroek
1493*b636d99dSDavid van Moolenbroek tptr = tptr + 4;
1494*b636d99dSDavid van Moolenbroek
1495*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", BVID: %d, SPVID: %d",
1496*b636d99dSDavid van Moolenbroek (EXTRACT_24BITS(tptr) >> 12) & 0x000fff,
1497*b636d99dSDavid van Moolenbroek EXTRACT_24BITS(tptr) & 0x000fff));
1498*b636d99dSDavid van Moolenbroek
1499*b636d99dSDavid van Moolenbroek tptr = tptr + 3;
1500*b636d99dSDavid van Moolenbroek len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
1501*b636d99dSDavid van Moolenbroek tmp--;
1502*b636d99dSDavid van Moolenbroek }
1503*b636d99dSDavid van Moolenbroek
1504*b636d99dSDavid van Moolenbroek break;
1505*b636d99dSDavid van Moolenbroek
1506*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPBM_SI:
1507*b636d99dSDavid van Moolenbroek
1508*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), 6))
1509*b636d99dSDavid van Moolenbroek goto trunctlv;
1510*b636d99dSDavid van Moolenbroek
1511*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr)));
1512*b636d99dSDavid van Moolenbroek tptr = tptr+4;
1513*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%04x", EXTRACT_16BITS(tptr)));
1514*b636d99dSDavid van Moolenbroek tptr = tptr+2;
1515*b636d99dSDavid van Moolenbroek
1516*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", RES: %d, VID: %d", EXTRACT_16BITS(tptr) >> 12,
1517*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS(tptr)) & 0x0fff));
1518*b636d99dSDavid van Moolenbroek
1519*b636d99dSDavid van Moolenbroek tptr = tptr+2;
1520*b636d99dSDavid van Moolenbroek len = len - 8;
1521*b636d99dSDavid van Moolenbroek stlv_len = stlv_len - 8;
1522*b636d99dSDavid van Moolenbroek
1523*b636d99dSDavid van Moolenbroek while (stlv_len)
1524*b636d99dSDavid van Moolenbroek {
1525*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t T: %d, R: %d, RES: %d, ISID: %d",
1526*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(tptr) >> 31),
1527*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(tptr) >> 30) & 0x01,
1528*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(tptr) >> 24) & 0x03f,
1529*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(tptr)) & 0x0ffffff));
1530*b636d99dSDavid van Moolenbroek
1531*b636d99dSDavid van Moolenbroek tptr = tptr + 4;
1532*b636d99dSDavid van Moolenbroek len = len - 4;
1533*b636d99dSDavid van Moolenbroek stlv_len = stlv_len - 4;
1534*b636d99dSDavid van Moolenbroek }
1535*b636d99dSDavid van Moolenbroek
1536*b636d99dSDavid van Moolenbroek break;
1537*b636d99dSDavid van Moolenbroek
1538*b636d99dSDavid van Moolenbroek default:
1539*b636d99dSDavid van Moolenbroek break;
1540*b636d99dSDavid van Moolenbroek }
1541*b636d99dSDavid van Moolenbroek }
1542*b636d99dSDavid van Moolenbroek return 0;
1543*b636d99dSDavid van Moolenbroek
1544*b636d99dSDavid van Moolenbroek trunctlv:
1545*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
1546*b636d99dSDavid van Moolenbroek return(1);
1547*b636d99dSDavid van Moolenbroek }
1548*b636d99dSDavid van Moolenbroek
1549*b636d99dSDavid van Moolenbroek /* shared routine for printing system, node and lsp-ids */
1550*b636d99dSDavid van Moolenbroek static char *
isis_print_id(const uint8_t * cp,int id_len)1551*b636d99dSDavid van Moolenbroek isis_print_id(const uint8_t *cp, int id_len)
1552*b636d99dSDavid van Moolenbroek {
1553*b636d99dSDavid van Moolenbroek int i;
1554*b636d99dSDavid van Moolenbroek static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
1555*b636d99dSDavid van Moolenbroek char *pos = id;
1556*b636d99dSDavid van Moolenbroek
1557*b636d99dSDavid van Moolenbroek for (i = 1; i <= SYSTEM_ID_LEN; i++) {
1558*b636d99dSDavid van Moolenbroek snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
1559*b636d99dSDavid van Moolenbroek pos += strlen(pos);
1560*b636d99dSDavid van Moolenbroek if (i == 2 || i == 4)
1561*b636d99dSDavid van Moolenbroek *pos++ = '.';
1562*b636d99dSDavid van Moolenbroek }
1563*b636d99dSDavid van Moolenbroek if (id_len >= NODE_ID_LEN) {
1564*b636d99dSDavid van Moolenbroek snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++);
1565*b636d99dSDavid van Moolenbroek pos += strlen(pos);
1566*b636d99dSDavid van Moolenbroek }
1567*b636d99dSDavid van Moolenbroek if (id_len == LSP_ID_LEN)
1568*b636d99dSDavid van Moolenbroek snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp);
1569*b636d99dSDavid van Moolenbroek return (id);
1570*b636d99dSDavid van Moolenbroek }
1571*b636d99dSDavid van Moolenbroek
1572*b636d99dSDavid van Moolenbroek /* print the 4-byte metric block which is common found in the old-style TLVs */
1573*b636d99dSDavid van Moolenbroek static int
isis_print_metric_block(netdissect_options * ndo,const struct isis_metric_block * isis_metric_block)1574*b636d99dSDavid van Moolenbroek isis_print_metric_block(netdissect_options *ndo,
1575*b636d99dSDavid van Moolenbroek const struct isis_metric_block *isis_metric_block)
1576*b636d99dSDavid van Moolenbroek {
1577*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Default Metric: %d, %s",
1578*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default),
1579*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"));
1580*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay))
1581*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t Delay Metric: %d, %s",
1582*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay),
1583*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"));
1584*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense))
1585*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t Expense Metric: %d, %s",
1586*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense),
1587*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"));
1588*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error))
1589*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t Error Metric: %d, %s",
1590*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error),
1591*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"));
1592*b636d99dSDavid van Moolenbroek
1593*b636d99dSDavid van Moolenbroek return(1); /* everything is ok */
1594*b636d99dSDavid van Moolenbroek }
1595*b636d99dSDavid van Moolenbroek
1596*b636d99dSDavid van Moolenbroek static int
isis_print_tlv_ip_reach(netdissect_options * ndo,const uint8_t * cp,const char * ident,int length)1597*b636d99dSDavid van Moolenbroek isis_print_tlv_ip_reach(netdissect_options *ndo,
1598*b636d99dSDavid van Moolenbroek const uint8_t *cp, const char *ident, int length)
1599*b636d99dSDavid van Moolenbroek {
1600*b636d99dSDavid van Moolenbroek int prefix_len;
1601*b636d99dSDavid van Moolenbroek const struct isis_tlv_ip_reach *tlv_ip_reach;
1602*b636d99dSDavid van Moolenbroek
1603*b636d99dSDavid van Moolenbroek tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
1604*b636d99dSDavid van Moolenbroek
1605*b636d99dSDavid van Moolenbroek while (length > 0) {
1606*b636d99dSDavid van Moolenbroek if ((size_t)length < sizeof(*tlv_ip_reach)) {
1607*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "short IPv4 Reachability (%d vs %lu)",
1608*b636d99dSDavid van Moolenbroek length,
1609*b636d99dSDavid van Moolenbroek (unsigned long)sizeof(*tlv_ip_reach)));
1610*b636d99dSDavid van Moolenbroek return (0);
1611*b636d99dSDavid van Moolenbroek }
1612*b636d99dSDavid van Moolenbroek
1613*b636d99dSDavid van Moolenbroek if (!ND_TTEST(*tlv_ip_reach))
1614*b636d99dSDavid van Moolenbroek return (0);
1615*b636d99dSDavid van Moolenbroek
1616*b636d99dSDavid van Moolenbroek prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask));
1617*b636d99dSDavid van Moolenbroek
1618*b636d99dSDavid van Moolenbroek if (prefix_len == -1)
1619*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv4 prefix: %s mask %s",
1620*b636d99dSDavid van Moolenbroek ident,
1621*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, (tlv_ip_reach->prefix)),
1622*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, (tlv_ip_reach->mask))));
1623*b636d99dSDavid van Moolenbroek else
1624*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv4 prefix: %15s/%u",
1625*b636d99dSDavid van Moolenbroek ident,
1626*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, (tlv_ip_reach->prefix)),
1627*b636d99dSDavid van Moolenbroek prefix_len));
1628*b636d99dSDavid van Moolenbroek
1629*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Distribution: %s, Metric: %u, %s",
1630*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up",
1631*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default),
1632*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"));
1633*b636d99dSDavid van Moolenbroek
1634*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay))
1635*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Delay Metric: %u, %s",
1636*b636d99dSDavid van Moolenbroek ident,
1637*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay),
1638*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"));
1639*b636d99dSDavid van Moolenbroek
1640*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense))
1641*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Expense Metric: %u, %s",
1642*b636d99dSDavid van Moolenbroek ident,
1643*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense),
1644*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"));
1645*b636d99dSDavid van Moolenbroek
1646*b636d99dSDavid van Moolenbroek if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error))
1647*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Error Metric: %u, %s",
1648*b636d99dSDavid van Moolenbroek ident,
1649*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error),
1650*b636d99dSDavid van Moolenbroek ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"));
1651*b636d99dSDavid van Moolenbroek
1652*b636d99dSDavid van Moolenbroek length -= sizeof(struct isis_tlv_ip_reach);
1653*b636d99dSDavid van Moolenbroek tlv_ip_reach++;
1654*b636d99dSDavid van Moolenbroek }
1655*b636d99dSDavid van Moolenbroek return (1);
1656*b636d99dSDavid van Moolenbroek }
1657*b636d99dSDavid van Moolenbroek
1658*b636d99dSDavid van Moolenbroek /*
1659*b636d99dSDavid van Moolenbroek * this is the common IP-REACH subTLV decoder it is called
1660*b636d99dSDavid van Moolenbroek * from various EXTD-IP REACH TLVs (135,235,236,237)
1661*b636d99dSDavid van Moolenbroek */
1662*b636d99dSDavid van Moolenbroek
1663*b636d99dSDavid van Moolenbroek static int
isis_print_ip_reach_subtlv(netdissect_options * ndo,const uint8_t * tptr,int subt,int subl,const char * ident)1664*b636d99dSDavid van Moolenbroek isis_print_ip_reach_subtlv(netdissect_options *ndo,
1665*b636d99dSDavid van Moolenbroek const uint8_t *tptr, int subt, int subl,
1666*b636d99dSDavid van Moolenbroek const char *ident)
1667*b636d99dSDavid van Moolenbroek {
1668*b636d99dSDavid van Moolenbroek /* first lets see if we know the subTLVs name*/
1669*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s subTLV #%u, length: %u",
1670*b636d99dSDavid van Moolenbroek ident, tok2str(isis_ext_ip_reach_subtlv_values, "unknown", subt),
1671*b636d99dSDavid van Moolenbroek subt, subl));
1672*b636d99dSDavid van Moolenbroek
1673*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr,subl))
1674*b636d99dSDavid van Moolenbroek goto trunctlv;
1675*b636d99dSDavid van Moolenbroek
1676*b636d99dSDavid van Moolenbroek switch(subt) {
1677*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */
1678*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32:
1679*b636d99dSDavid van Moolenbroek while (subl >= 4) {
1680*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", 0x%08x (=%u)",
1681*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tptr),
1682*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tptr)));
1683*b636d99dSDavid van Moolenbroek tptr+=4;
1684*b636d99dSDavid van Moolenbroek subl-=4;
1685*b636d99dSDavid van Moolenbroek }
1686*b636d99dSDavid van Moolenbroek break;
1687*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64:
1688*b636d99dSDavid van Moolenbroek while (subl >= 8) {
1689*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", 0x%08x%08x",
1690*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tptr),
1691*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tptr+4)));
1692*b636d99dSDavid van Moolenbroek tptr+=8;
1693*b636d99dSDavid van Moolenbroek subl-=8;
1694*b636d99dSDavid van Moolenbroek }
1695*b636d99dSDavid van Moolenbroek break;
1696*b636d99dSDavid van Moolenbroek default:
1697*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl))
1698*b636d99dSDavid van Moolenbroek return(0);
1699*b636d99dSDavid van Moolenbroek break;
1700*b636d99dSDavid van Moolenbroek }
1701*b636d99dSDavid van Moolenbroek return(1);
1702*b636d99dSDavid van Moolenbroek
1703*b636d99dSDavid van Moolenbroek trunctlv:
1704*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%spacket exceeded snapshot", ident));
1705*b636d99dSDavid van Moolenbroek return(0);
1706*b636d99dSDavid van Moolenbroek }
1707*b636d99dSDavid van Moolenbroek
1708*b636d99dSDavid van Moolenbroek /*
1709*b636d99dSDavid van Moolenbroek * this is the common IS-REACH subTLV decoder it is called
1710*b636d99dSDavid van Moolenbroek * from isis_print_ext_is_reach()
1711*b636d99dSDavid van Moolenbroek */
1712*b636d99dSDavid van Moolenbroek
1713*b636d99dSDavid van Moolenbroek static int
isis_print_is_reach_subtlv(netdissect_options * ndo,const uint8_t * tptr,u_int subt,u_int subl,const char * ident)1714*b636d99dSDavid van Moolenbroek isis_print_is_reach_subtlv(netdissect_options *ndo,
1715*b636d99dSDavid van Moolenbroek const uint8_t *tptr, u_int subt, u_int subl,
1716*b636d99dSDavid van Moolenbroek const char *ident)
1717*b636d99dSDavid van Moolenbroek {
1718*b636d99dSDavid van Moolenbroek u_int te_class,priority_level,gmpls_switch_cap;
1719*b636d99dSDavid van Moolenbroek union { /* int to float conversion buffer for several subTLVs */
1720*b636d99dSDavid van Moolenbroek float f;
1721*b636d99dSDavid van Moolenbroek uint32_t i;
1722*b636d99dSDavid van Moolenbroek } bw;
1723*b636d99dSDavid van Moolenbroek
1724*b636d99dSDavid van Moolenbroek /* first lets see if we know the subTLVs name*/
1725*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s subTLV #%u, length: %u",
1726*b636d99dSDavid van Moolenbroek ident, tok2str(isis_ext_is_reach_subtlv_values, "unknown", subt),
1727*b636d99dSDavid van Moolenbroek subt, subl));
1728*b636d99dSDavid van Moolenbroek
1729*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr,subl))
1730*b636d99dSDavid van Moolenbroek goto trunctlv;
1731*b636d99dSDavid van Moolenbroek
1732*b636d99dSDavid van Moolenbroek switch(subt) {
1733*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
1734*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID:
1735*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
1736*b636d99dSDavid van Moolenbroek if (subl >= 4) {
1737*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr)));
1738*b636d99dSDavid van Moolenbroek if (subl == 8) /* rfc4205 */
1739*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr+4)));
1740*b636d99dSDavid van Moolenbroek }
1741*b636d99dSDavid van Moolenbroek break;
1742*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
1743*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
1744*b636d99dSDavid van Moolenbroek if (subl >= sizeof(struct in_addr))
1745*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr)));
1746*b636d99dSDavid van Moolenbroek break;
1747*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
1748*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW:
1749*b636d99dSDavid van Moolenbroek if (subl >= 4) {
1750*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1751*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %.3f Mbps", bw.f * 8 / 1000000));
1752*b636d99dSDavid van Moolenbroek }
1753*b636d99dSDavid van Moolenbroek break;
1754*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
1755*b636d99dSDavid van Moolenbroek if (subl >= 32) {
1756*b636d99dSDavid van Moolenbroek for (te_class = 0; te_class < 8; te_class++) {
1757*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1758*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s TE-Class %u: %.3f Mbps",
1759*b636d99dSDavid van Moolenbroek ident,
1760*b636d99dSDavid van Moolenbroek te_class,
1761*b636d99dSDavid van Moolenbroek bw.f * 8 / 1000000));
1762*b636d99dSDavid van Moolenbroek tptr+=4;
1763*b636d99dSDavid van Moolenbroek }
1764*b636d99dSDavid van Moolenbroek }
1765*b636d99dSDavid van Moolenbroek break;
1766*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
1767*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
1768*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sBandwidth Constraints Model ID: %s (%u)",
1769*b636d99dSDavid van Moolenbroek ident,
1770*b636d99dSDavid van Moolenbroek tok2str(diffserv_te_bc_values, "unknown", *tptr),
1771*b636d99dSDavid van Moolenbroek *tptr));
1772*b636d99dSDavid van Moolenbroek tptr++;
1773*b636d99dSDavid van Moolenbroek /* decode BCs until the subTLV ends */
1774*b636d99dSDavid van Moolenbroek for (te_class = 0; te_class < (subl-1)/4; te_class++) {
1775*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1776*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Bandwidth constraint CT%u: %.3f Mbps",
1777*b636d99dSDavid van Moolenbroek ident,
1778*b636d99dSDavid van Moolenbroek te_class,
1779*b636d99dSDavid van Moolenbroek bw.f * 8 / 1000000));
1780*b636d99dSDavid van Moolenbroek tptr+=4;
1781*b636d99dSDavid van Moolenbroek }
1782*b636d99dSDavid van Moolenbroek break;
1783*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC:
1784*b636d99dSDavid van Moolenbroek if (subl >= 3)
1785*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %u", EXTRACT_24BITS(tptr)));
1786*b636d99dSDavid van Moolenbroek break;
1787*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE:
1788*b636d99dSDavid van Moolenbroek if (subl == 2) {
1789*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", [ %s ] (0x%04x)",
1790*b636d99dSDavid van Moolenbroek bittok2str(isis_subtlv_link_attribute_values,
1791*b636d99dSDavid van Moolenbroek "Unknown",
1792*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tptr)),
1793*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tptr)));
1794*b636d99dSDavid van Moolenbroek }
1795*b636d99dSDavid van Moolenbroek break;
1796*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
1797*b636d99dSDavid van Moolenbroek if (subl >= 2) {
1798*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %s, Priority %u",
1799*b636d99dSDavid van Moolenbroek bittok2str(gmpls_link_prot_values, "none", *tptr),
1800*b636d99dSDavid van Moolenbroek *(tptr+1)));
1801*b636d99dSDavid van Moolenbroek }
1802*b636d99dSDavid van Moolenbroek break;
1803*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_SPB_METRIC:
1804*b636d99dSDavid van Moolenbroek if (subl >= 6) {
1805*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", LM: %u", EXTRACT_24BITS(tptr)));
1806*b636d99dSDavid van Moolenbroek tptr=tptr+3;
1807*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", P: %u", *(tptr)));
1808*b636d99dSDavid van Moolenbroek tptr++;
1809*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", P-ID: %u", EXTRACT_16BITS(tptr)));
1810*b636d99dSDavid van Moolenbroek }
1811*b636d99dSDavid van Moolenbroek break;
1812*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
1813*b636d99dSDavid van Moolenbroek if (subl >= 36) {
1814*b636d99dSDavid van Moolenbroek gmpls_switch_cap = *tptr;
1815*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Interface Switching Capability:%s",
1816*b636d99dSDavid van Moolenbroek ident,
1817*b636d99dSDavid van Moolenbroek tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap)));
1818*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", LSP Encoding: %s",
1819*b636d99dSDavid van Moolenbroek tok2str(gmpls_encoding_values, "Unknown", *(tptr + 1))));
1820*b636d99dSDavid van Moolenbroek tptr+=4;
1821*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Max LSP Bandwidth:", ident));
1822*b636d99dSDavid van Moolenbroek for (priority_level = 0; priority_level < 8; priority_level++) {
1823*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1824*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s priority level %d: %.3f Mbps",
1825*b636d99dSDavid van Moolenbroek ident,
1826*b636d99dSDavid van Moolenbroek priority_level,
1827*b636d99dSDavid van Moolenbroek bw.f * 8 / 1000000));
1828*b636d99dSDavid van Moolenbroek tptr+=4;
1829*b636d99dSDavid van Moolenbroek }
1830*b636d99dSDavid van Moolenbroek subl-=36;
1831*b636d99dSDavid van Moolenbroek switch (gmpls_switch_cap) {
1832*b636d99dSDavid van Moolenbroek case GMPLS_PSC1:
1833*b636d99dSDavid van Moolenbroek case GMPLS_PSC2:
1834*b636d99dSDavid van Moolenbroek case GMPLS_PSC3:
1835*b636d99dSDavid van Moolenbroek case GMPLS_PSC4:
1836*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1837*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
1838*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr + 4)));
1839*b636d99dSDavid van Moolenbroek break;
1840*b636d99dSDavid van Moolenbroek case GMPLS_TSC:
1841*b636d99dSDavid van Moolenbroek bw.i = EXTRACT_32BITS(tptr);
1842*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f * 8 / 1000000));
1843*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s Indication %s", ident,
1844*b636d99dSDavid van Moolenbroek tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", *(tptr + 4))));
1845*b636d99dSDavid van Moolenbroek break;
1846*b636d99dSDavid van Moolenbroek default:
1847*b636d99dSDavid van Moolenbroek /* there is some optional stuff left to decode but this is as of yet
1848*b636d99dSDavid van Moolenbroek not specified so just lets hexdump what is left */
1849*b636d99dSDavid van Moolenbroek if(subl>0){
1850*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl))
1851*b636d99dSDavid van Moolenbroek return(0);
1852*b636d99dSDavid van Moolenbroek }
1853*b636d99dSDavid van Moolenbroek }
1854*b636d99dSDavid van Moolenbroek }
1855*b636d99dSDavid van Moolenbroek break;
1856*b636d99dSDavid van Moolenbroek default:
1857*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl))
1858*b636d99dSDavid van Moolenbroek return(0);
1859*b636d99dSDavid van Moolenbroek break;
1860*b636d99dSDavid van Moolenbroek }
1861*b636d99dSDavid van Moolenbroek return(1);
1862*b636d99dSDavid van Moolenbroek
1863*b636d99dSDavid van Moolenbroek trunctlv:
1864*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%spacket exceeded snapshot", ident));
1865*b636d99dSDavid van Moolenbroek return(0);
1866*b636d99dSDavid van Moolenbroek }
1867*b636d99dSDavid van Moolenbroek
1868*b636d99dSDavid van Moolenbroek
1869*b636d99dSDavid van Moolenbroek /*
1870*b636d99dSDavid van Moolenbroek * this is the common IS-REACH decoder it is called
1871*b636d99dSDavid van Moolenbroek * from various EXTD-IS REACH style TLVs (22,24,222)
1872*b636d99dSDavid van Moolenbroek */
1873*b636d99dSDavid van Moolenbroek
1874*b636d99dSDavid van Moolenbroek static int
isis_print_ext_is_reach(netdissect_options * ndo,const uint8_t * tptr,const char * ident,int tlv_type)1875*b636d99dSDavid van Moolenbroek isis_print_ext_is_reach(netdissect_options *ndo,
1876*b636d99dSDavid van Moolenbroek const uint8_t *tptr, const char *ident, int tlv_type)
1877*b636d99dSDavid van Moolenbroek {
1878*b636d99dSDavid van Moolenbroek char ident_buffer[20];
1879*b636d99dSDavid van Moolenbroek int subtlv_type,subtlv_len,subtlv_sum_len;
1880*b636d99dSDavid van Moolenbroek int proc_bytes = 0; /* how many bytes did we process ? */
1881*b636d99dSDavid van Moolenbroek
1882*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, NODE_ID_LEN))
1883*b636d99dSDavid van Moolenbroek return(0);
1884*b636d99dSDavid van Moolenbroek
1885*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)));
1886*b636d99dSDavid van Moolenbroek tptr+=(NODE_ID_LEN);
1887*b636d99dSDavid van Moolenbroek
1888*b636d99dSDavid van Moolenbroek if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */
1889*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 3)) /* and is therefore skipped */
1890*b636d99dSDavid van Moolenbroek return(0);
1891*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Metric: %d", EXTRACT_24BITS(tptr)));
1892*b636d99dSDavid van Moolenbroek tptr+=3;
1893*b636d99dSDavid van Moolenbroek }
1894*b636d99dSDavid van Moolenbroek
1895*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
1896*b636d99dSDavid van Moolenbroek return(0);
1897*b636d99dSDavid van Moolenbroek subtlv_sum_len=*(tptr++); /* read out subTLV length */
1898*b636d99dSDavid van Moolenbroek proc_bytes=NODE_ID_LEN+3+1;
1899*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %ssub-TLVs present",subtlv_sum_len ? "" : "no "));
1900*b636d99dSDavid van Moolenbroek if (subtlv_sum_len) {
1901*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " (%u)", subtlv_sum_len));
1902*b636d99dSDavid van Moolenbroek while (subtlv_sum_len>0) {
1903*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr,2))
1904*b636d99dSDavid van Moolenbroek return(0);
1905*b636d99dSDavid van Moolenbroek subtlv_type=*(tptr++);
1906*b636d99dSDavid van Moolenbroek subtlv_len=*(tptr++);
1907*b636d99dSDavid van Moolenbroek /* prepend the ident string */
1908*b636d99dSDavid van Moolenbroek snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
1909*b636d99dSDavid van Moolenbroek if (!isis_print_is_reach_subtlv(ndo, tptr, subtlv_type, subtlv_len, ident_buffer))
1910*b636d99dSDavid van Moolenbroek return(0);
1911*b636d99dSDavid van Moolenbroek tptr+=subtlv_len;
1912*b636d99dSDavid van Moolenbroek subtlv_sum_len-=(subtlv_len+2);
1913*b636d99dSDavid van Moolenbroek proc_bytes+=(subtlv_len+2);
1914*b636d99dSDavid van Moolenbroek }
1915*b636d99dSDavid van Moolenbroek }
1916*b636d99dSDavid van Moolenbroek return(proc_bytes);
1917*b636d99dSDavid van Moolenbroek }
1918*b636d99dSDavid van Moolenbroek
1919*b636d99dSDavid van Moolenbroek /*
1920*b636d99dSDavid van Moolenbroek * this is the common Multi Topology ID decoder
1921*b636d99dSDavid van Moolenbroek * it is called from various MT-TLVs (222,229,235,237)
1922*b636d99dSDavid van Moolenbroek */
1923*b636d99dSDavid van Moolenbroek
1924*b636d99dSDavid van Moolenbroek static int
isis_print_mtid(netdissect_options * ndo,const uint8_t * tptr,const char * ident)1925*b636d99dSDavid van Moolenbroek isis_print_mtid(netdissect_options *ndo,
1926*b636d99dSDavid van Moolenbroek const uint8_t *tptr, const char *ident)
1927*b636d99dSDavid van Moolenbroek {
1928*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 2))
1929*b636d99dSDavid van Moolenbroek return(0);
1930*b636d99dSDavid van Moolenbroek
1931*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s",
1932*b636d99dSDavid van Moolenbroek ident,
1933*b636d99dSDavid van Moolenbroek tok2str(isis_mt_values,
1934*b636d99dSDavid van Moolenbroek "Reserved for IETF Consensus",
1935*b636d99dSDavid van Moolenbroek ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))));
1936*b636d99dSDavid van Moolenbroek
1937*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " Topology (0x%03x), Flags: [%s]",
1938*b636d99dSDavid van Moolenbroek ISIS_MASK_MTID(EXTRACT_16BITS(tptr)),
1939*b636d99dSDavid van Moolenbroek bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))));
1940*b636d99dSDavid van Moolenbroek
1941*b636d99dSDavid van Moolenbroek return(2);
1942*b636d99dSDavid van Moolenbroek }
1943*b636d99dSDavid van Moolenbroek
1944*b636d99dSDavid van Moolenbroek /*
1945*b636d99dSDavid van Moolenbroek * this is the common extended IP reach decoder
1946*b636d99dSDavid van Moolenbroek * it is called from TLVs (135,235,236,237)
1947*b636d99dSDavid van Moolenbroek * we process the TLV and optional subTLVs and return
1948*b636d99dSDavid van Moolenbroek * the amount of processed bytes
1949*b636d99dSDavid van Moolenbroek */
1950*b636d99dSDavid van Moolenbroek
1951*b636d99dSDavid van Moolenbroek static int
isis_print_extd_ip_reach(netdissect_options * ndo,const uint8_t * tptr,const char * ident,uint16_t afi)1952*b636d99dSDavid van Moolenbroek isis_print_extd_ip_reach(netdissect_options *ndo,
1953*b636d99dSDavid van Moolenbroek const uint8_t *tptr, const char *ident, uint16_t afi)
1954*b636d99dSDavid van Moolenbroek {
1955*b636d99dSDavid van Moolenbroek char ident_buffer[20];
1956*b636d99dSDavid van Moolenbroek #ifdef INET6
1957*b636d99dSDavid van Moolenbroek uint8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */
1958*b636d99dSDavid van Moolenbroek #else
1959*b636d99dSDavid van Moolenbroek uint8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */
1960*b636d99dSDavid van Moolenbroek #endif
1961*b636d99dSDavid van Moolenbroek u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen;
1962*b636d99dSDavid van Moolenbroek
1963*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 4))
1964*b636d99dSDavid van Moolenbroek return (0);
1965*b636d99dSDavid van Moolenbroek metric = EXTRACT_32BITS(tptr);
1966*b636d99dSDavid van Moolenbroek processed=4;
1967*b636d99dSDavid van Moolenbroek tptr+=4;
1968*b636d99dSDavid van Moolenbroek
1969*b636d99dSDavid van Moolenbroek if (afi == AF_INET) {
1970*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1)) /* fetch status byte */
1971*b636d99dSDavid van Moolenbroek return (0);
1972*b636d99dSDavid van Moolenbroek status_byte=*(tptr++);
1973*b636d99dSDavid van Moolenbroek bit_length = status_byte&0x3f;
1974*b636d99dSDavid van Moolenbroek if (bit_length > 32) {
1975*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv4 prefix: bad bit length %u",
1976*b636d99dSDavid van Moolenbroek ident,
1977*b636d99dSDavid van Moolenbroek bit_length));
1978*b636d99dSDavid van Moolenbroek return (0);
1979*b636d99dSDavid van Moolenbroek }
1980*b636d99dSDavid van Moolenbroek processed++;
1981*b636d99dSDavid van Moolenbroek #ifdef INET6
1982*b636d99dSDavid van Moolenbroek } else if (afi == AF_INET6) {
1983*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
1984*b636d99dSDavid van Moolenbroek return (0);
1985*b636d99dSDavid van Moolenbroek status_byte=*(tptr++);
1986*b636d99dSDavid van Moolenbroek bit_length=*(tptr++);
1987*b636d99dSDavid van Moolenbroek if (bit_length > 128) {
1988*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv6 prefix: bad bit length %u",
1989*b636d99dSDavid van Moolenbroek ident,
1990*b636d99dSDavid van Moolenbroek bit_length));
1991*b636d99dSDavid van Moolenbroek return (0);
1992*b636d99dSDavid van Moolenbroek }
1993*b636d99dSDavid van Moolenbroek processed+=2;
1994*b636d99dSDavid van Moolenbroek #endif
1995*b636d99dSDavid van Moolenbroek } else
1996*b636d99dSDavid van Moolenbroek return (0); /* somebody is fooling us */
1997*b636d99dSDavid van Moolenbroek
1998*b636d99dSDavid van Moolenbroek byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
1999*b636d99dSDavid van Moolenbroek
2000*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, byte_length))
2001*b636d99dSDavid van Moolenbroek return (0);
2002*b636d99dSDavid van Moolenbroek memset(prefix, 0, sizeof prefix); /* clear the copy buffer */
2003*b636d99dSDavid van Moolenbroek memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */
2004*b636d99dSDavid van Moolenbroek tptr+=byte_length;
2005*b636d99dSDavid van Moolenbroek processed+=byte_length;
2006*b636d99dSDavid van Moolenbroek
2007*b636d99dSDavid van Moolenbroek if (afi == AF_INET)
2008*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv4 prefix: %15s/%u",
2009*b636d99dSDavid van Moolenbroek ident,
2010*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, prefix),
2011*b636d99dSDavid van Moolenbroek bit_length));
2012*b636d99dSDavid van Moolenbroek #ifdef INET6
2013*b636d99dSDavid van Moolenbroek if (afi == AF_INET6)
2014*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%sIPv6 prefix: %s/%u",
2015*b636d99dSDavid van Moolenbroek ident,
2016*b636d99dSDavid van Moolenbroek ip6addr_string(ndo, prefix),
2017*b636d99dSDavid van Moolenbroek bit_length));
2018*b636d99dSDavid van Moolenbroek #endif
2019*b636d99dSDavid van Moolenbroek
2020*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Distribution: %s, Metric: %u",
2021*b636d99dSDavid van Moolenbroek ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up",
2022*b636d99dSDavid van Moolenbroek metric));
2023*b636d99dSDavid van Moolenbroek
2024*b636d99dSDavid van Moolenbroek if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
2025*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", sub-TLVs present"));
2026*b636d99dSDavid van Moolenbroek #ifdef INET6
2027*b636d99dSDavid van Moolenbroek if (afi == AF_INET6)
2028*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", %s%s",
2029*b636d99dSDavid van Moolenbroek ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal",
2030*b636d99dSDavid van Moolenbroek ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""));
2031*b636d99dSDavid van Moolenbroek #endif
2032*b636d99dSDavid van Moolenbroek
2033*b636d99dSDavid van Moolenbroek if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
2034*b636d99dSDavid van Moolenbroek #ifdef INET6
2035*b636d99dSDavid van Moolenbroek || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte))
2036*b636d99dSDavid van Moolenbroek #endif
2037*b636d99dSDavid van Moolenbroek ) {
2038*b636d99dSDavid van Moolenbroek /* assume that one prefix can hold more
2039*b636d99dSDavid van Moolenbroek than one subTLV - therefore the first byte must reflect
2040*b636d99dSDavid van Moolenbroek the aggregate bytecount of the subTLVs for this prefix
2041*b636d99dSDavid van Moolenbroek */
2042*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2043*b636d99dSDavid van Moolenbroek return (0);
2044*b636d99dSDavid van Moolenbroek sublen=*(tptr++);
2045*b636d99dSDavid van Moolenbroek processed+=sublen+1;
2046*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " (%u)", sublen)); /* print out subTLV length */
2047*b636d99dSDavid van Moolenbroek
2048*b636d99dSDavid van Moolenbroek while (sublen>0) {
2049*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr,2))
2050*b636d99dSDavid van Moolenbroek return (0);
2051*b636d99dSDavid van Moolenbroek subtlvtype=*(tptr++);
2052*b636d99dSDavid van Moolenbroek subtlvlen=*(tptr++);
2053*b636d99dSDavid van Moolenbroek /* prepend the ident string */
2054*b636d99dSDavid van Moolenbroek snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
2055*b636d99dSDavid van Moolenbroek if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer))
2056*b636d99dSDavid van Moolenbroek return(0);
2057*b636d99dSDavid van Moolenbroek tptr+=subtlvlen;
2058*b636d99dSDavid van Moolenbroek sublen-=(subtlvlen+2);
2059*b636d99dSDavid van Moolenbroek }
2060*b636d99dSDavid van Moolenbroek }
2061*b636d99dSDavid van Moolenbroek return (processed);
2062*b636d99dSDavid van Moolenbroek }
2063*b636d99dSDavid van Moolenbroek
2064*b636d99dSDavid van Moolenbroek /*
2065*b636d99dSDavid van Moolenbroek * isis_print
2066*b636d99dSDavid van Moolenbroek * Decode IS-IS packets. Return 0 on error.
2067*b636d99dSDavid van Moolenbroek */
2068*b636d99dSDavid van Moolenbroek
2069*b636d99dSDavid van Moolenbroek static int
isis_print(netdissect_options * ndo,const uint8_t * p,u_int length)2070*b636d99dSDavid van Moolenbroek isis_print(netdissect_options *ndo,
2071*b636d99dSDavid van Moolenbroek const uint8_t *p, u_int length)
2072*b636d99dSDavid van Moolenbroek {
2073*b636d99dSDavid van Moolenbroek const struct isis_common_header *isis_header;
2074*b636d99dSDavid van Moolenbroek
2075*b636d99dSDavid van Moolenbroek const struct isis_iih_lan_header *header_iih_lan;
2076*b636d99dSDavid van Moolenbroek const struct isis_iih_ptp_header *header_iih_ptp;
2077*b636d99dSDavid van Moolenbroek struct isis_lsp_header *header_lsp;
2078*b636d99dSDavid van Moolenbroek const struct isis_csnp_header *header_csnp;
2079*b636d99dSDavid van Moolenbroek const struct isis_psnp_header *header_psnp;
2080*b636d99dSDavid van Moolenbroek
2081*b636d99dSDavid van Moolenbroek const struct isis_tlv_lsp *tlv_lsp;
2082*b636d99dSDavid van Moolenbroek const struct isis_tlv_ptp_adj *tlv_ptp_adj;
2083*b636d99dSDavid van Moolenbroek const struct isis_tlv_is_reach *tlv_is_reach;
2084*b636d99dSDavid van Moolenbroek const struct isis_tlv_es_reach *tlv_es_reach;
2085*b636d99dSDavid van Moolenbroek
2086*b636d99dSDavid van Moolenbroek uint8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len;
2087*b636d99dSDavid van Moolenbroek uint8_t ext_is_len, ext_ip_len, mt_len;
2088*b636d99dSDavid van Moolenbroek const uint8_t *optr, *pptr, *tptr;
2089*b636d99dSDavid van Moolenbroek u_short packet_len,pdu_len, key_id;
2090*b636d99dSDavid van Moolenbroek u_int i,vendor_id;
2091*b636d99dSDavid van Moolenbroek int sigcheck;
2092*b636d99dSDavid van Moolenbroek
2093*b636d99dSDavid van Moolenbroek packet_len=length;
2094*b636d99dSDavid van Moolenbroek optr = p; /* initialize the _o_riginal pointer to the packet start -
2095*b636d99dSDavid van Moolenbroek need it for parsing the checksum TLV and authentication
2096*b636d99dSDavid van Moolenbroek TLV verification */
2097*b636d99dSDavid van Moolenbroek isis_header = (const struct isis_common_header *)p;
2098*b636d99dSDavid van Moolenbroek ND_TCHECK(*isis_header);
2099*b636d99dSDavid van Moolenbroek pptr = p+(ISIS_COMMON_HEADER_SIZE);
2100*b636d99dSDavid van Moolenbroek header_iih_lan = (const struct isis_iih_lan_header *)pptr;
2101*b636d99dSDavid van Moolenbroek header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
2102*b636d99dSDavid van Moolenbroek header_lsp = (struct isis_lsp_header *)pptr;
2103*b636d99dSDavid van Moolenbroek header_csnp = (const struct isis_csnp_header *)pptr;
2104*b636d99dSDavid van Moolenbroek header_psnp = (const struct isis_psnp_header *)pptr;
2105*b636d99dSDavid van Moolenbroek
2106*b636d99dSDavid van Moolenbroek if (!ndo->ndo_eflag)
2107*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "IS-IS"));
2108*b636d99dSDavid van Moolenbroek
2109*b636d99dSDavid van Moolenbroek /*
2110*b636d99dSDavid van Moolenbroek * Sanity checking of the header.
2111*b636d99dSDavid van Moolenbroek */
2112*b636d99dSDavid van Moolenbroek
2113*b636d99dSDavid van Moolenbroek if (isis_header->version != ISIS_VERSION) {
2114*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "version %d packet not supported", isis_header->version));
2115*b636d99dSDavid van Moolenbroek return (0);
2116*b636d99dSDavid van Moolenbroek }
2117*b636d99dSDavid van Moolenbroek
2118*b636d99dSDavid van Moolenbroek if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) {
2119*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "system ID length of %d is not supported",
2120*b636d99dSDavid van Moolenbroek isis_header->id_length));
2121*b636d99dSDavid van Moolenbroek return (0);
2122*b636d99dSDavid van Moolenbroek }
2123*b636d99dSDavid van Moolenbroek
2124*b636d99dSDavid van Moolenbroek if (isis_header->pdu_version != ISIS_VERSION) {
2125*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "version %d packet not supported", isis_header->pdu_version));
2126*b636d99dSDavid van Moolenbroek return (0);
2127*b636d99dSDavid van Moolenbroek }
2128*b636d99dSDavid van Moolenbroek
2129*b636d99dSDavid van Moolenbroek max_area = isis_header->max_area;
2130*b636d99dSDavid van Moolenbroek switch(max_area) {
2131*b636d99dSDavid van Moolenbroek case 0:
2132*b636d99dSDavid van Moolenbroek max_area = 3; /* silly shit */
2133*b636d99dSDavid van Moolenbroek break;
2134*b636d99dSDavid van Moolenbroek case 255:
2135*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "bad packet -- 255 areas"));
2136*b636d99dSDavid van Moolenbroek return (0);
2137*b636d99dSDavid van Moolenbroek default:
2138*b636d99dSDavid van Moolenbroek break;
2139*b636d99dSDavid van Moolenbroek }
2140*b636d99dSDavid van Moolenbroek
2141*b636d99dSDavid van Moolenbroek id_length = isis_header->id_length;
2142*b636d99dSDavid van Moolenbroek switch(id_length) {
2143*b636d99dSDavid van Moolenbroek case 0:
2144*b636d99dSDavid van Moolenbroek id_length = 6; /* silly shit again */
2145*b636d99dSDavid van Moolenbroek break;
2146*b636d99dSDavid van Moolenbroek case 1: /* 1-8 are valid sys-ID lenghts */
2147*b636d99dSDavid van Moolenbroek case 2:
2148*b636d99dSDavid van Moolenbroek case 3:
2149*b636d99dSDavid van Moolenbroek case 4:
2150*b636d99dSDavid van Moolenbroek case 5:
2151*b636d99dSDavid van Moolenbroek case 6:
2152*b636d99dSDavid van Moolenbroek case 7:
2153*b636d99dSDavid van Moolenbroek case 8:
2154*b636d99dSDavid van Moolenbroek break;
2155*b636d99dSDavid van Moolenbroek case 255:
2156*b636d99dSDavid van Moolenbroek id_length = 0; /* entirely useless */
2157*b636d99dSDavid van Moolenbroek break;
2158*b636d99dSDavid van Moolenbroek default:
2159*b636d99dSDavid van Moolenbroek break;
2160*b636d99dSDavid van Moolenbroek }
2161*b636d99dSDavid van Moolenbroek
2162*b636d99dSDavid van Moolenbroek /* toss any non 6-byte sys-ID len PDUs */
2163*b636d99dSDavid van Moolenbroek if (id_length != 6 ) {
2164*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "bad packet -- illegal sys-ID length (%u)", id_length));
2165*b636d99dSDavid van Moolenbroek return (0);
2166*b636d99dSDavid van Moolenbroek }
2167*b636d99dSDavid van Moolenbroek
2168*b636d99dSDavid van Moolenbroek pdu_type=isis_header->pdu_type;
2169*b636d99dSDavid van Moolenbroek
2170*b636d99dSDavid van Moolenbroek /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
2171*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag < 1) {
2172*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s%s",
2173*b636d99dSDavid van Moolenbroek ndo->ndo_eflag ? "" : ", ",
2174*b636d99dSDavid van Moolenbroek tok2str(isis_pdu_values, "unknown PDU-Type %u", pdu_type)));
2175*b636d99dSDavid van Moolenbroek
2176*b636d99dSDavid van Moolenbroek switch (pdu_type) {
2177*b636d99dSDavid van Moolenbroek
2178*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_LAN_IIH:
2179*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_LAN_IIH:
2180*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", src-id %s",
2181*b636d99dSDavid van Moolenbroek isis_print_id(header_iih_lan->source_id, SYSTEM_ID_LEN)));
2182*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", lan-id %s, prio %u",
2183*b636d99dSDavid van Moolenbroek isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
2184*b636d99dSDavid van Moolenbroek header_iih_lan->priority));
2185*b636d99dSDavid van Moolenbroek break;
2186*b636d99dSDavid van Moolenbroek case ISIS_PDU_PTP_IIH:
2187*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", src-id %s", isis_print_id(header_iih_ptp->source_id, SYSTEM_ID_LEN)));
2188*b636d99dSDavid van Moolenbroek break;
2189*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_LSP:
2190*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_LSP:
2191*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", lsp-id %s, seq 0x%08x, lifetime %5us",
2192*b636d99dSDavid van Moolenbroek isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
2193*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(header_lsp->sequence_number),
2194*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_lsp->remaining_lifetime)));
2195*b636d99dSDavid van Moolenbroek break;
2196*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_CSNP:
2197*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_CSNP:
2198*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", src-id %s", isis_print_id(header_csnp->source_id, NODE_ID_LEN)));
2199*b636d99dSDavid van Moolenbroek break;
2200*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_PSNP:
2201*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_PSNP:
2202*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", src-id %s", isis_print_id(header_psnp->source_id, NODE_ID_LEN)));
2203*b636d99dSDavid van Moolenbroek break;
2204*b636d99dSDavid van Moolenbroek
2205*b636d99dSDavid van Moolenbroek }
2206*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", length %u", length));
2207*b636d99dSDavid van Moolenbroek
2208*b636d99dSDavid van Moolenbroek return(1);
2209*b636d99dSDavid van Moolenbroek }
2210*b636d99dSDavid van Moolenbroek
2211*b636d99dSDavid van Moolenbroek /* ok they seem to want to know everything - lets fully decode it */
2212*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%slength %u", ndo->ndo_eflag ? "" : ", ", length));
2213*b636d99dSDavid van Moolenbroek
2214*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
2215*b636d99dSDavid van Moolenbroek tok2str(isis_pdu_values,
2216*b636d99dSDavid van Moolenbroek "unknown, type %u",
2217*b636d99dSDavid van Moolenbroek pdu_type),
2218*b636d99dSDavid van Moolenbroek isis_header->fixed_len,
2219*b636d99dSDavid van Moolenbroek isis_header->version,
2220*b636d99dSDavid van Moolenbroek isis_header->pdu_version,
2221*b636d99dSDavid van Moolenbroek id_length,
2222*b636d99dSDavid van Moolenbroek isis_header->id_length,
2223*b636d99dSDavid van Moolenbroek max_area,
2224*b636d99dSDavid van Moolenbroek isis_header->max_area));
2225*b636d99dSDavid van Moolenbroek
2226*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2227*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, optr, "\n\t", 8)) /* provide the _o_riginal pointer */
2228*b636d99dSDavid van Moolenbroek return(0); /* for optionally debugging the common header */
2229*b636d99dSDavid van Moolenbroek }
2230*b636d99dSDavid van Moolenbroek
2231*b636d99dSDavid van Moolenbroek switch (pdu_type) {
2232*b636d99dSDavid van Moolenbroek
2233*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_LAN_IIH:
2234*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_LAN_IIH:
2235*b636d99dSDavid van Moolenbroek if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
2236*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
2237*b636d99dSDavid van Moolenbroek isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE));
2238*b636d99dSDavid van Moolenbroek return (0);
2239*b636d99dSDavid van Moolenbroek }
2240*b636d99dSDavid van Moolenbroek
2241*b636d99dSDavid van Moolenbroek pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
2242*b636d99dSDavid van Moolenbroek if (packet_len>pdu_len) {
2243*b636d99dSDavid van Moolenbroek packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
2244*b636d99dSDavid van Moolenbroek length=pdu_len;
2245*b636d99dSDavid van Moolenbroek }
2246*b636d99dSDavid van Moolenbroek
2247*b636d99dSDavid van Moolenbroek ND_TCHECK(*header_iih_lan);
2248*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
2249*b636d99dSDavid van Moolenbroek isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
2250*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_iih_lan->holding_time),
2251*b636d99dSDavid van Moolenbroek tok2str(isis_iih_circuit_type_values,
2252*b636d99dSDavid van Moolenbroek "unknown circuit type 0x%02x",
2253*b636d99dSDavid van Moolenbroek header_iih_lan->circuit_type)));
2254*b636d99dSDavid van Moolenbroek
2255*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t lan-id: %s, Priority: %u, PDU length: %u",
2256*b636d99dSDavid van Moolenbroek isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
2257*b636d99dSDavid van Moolenbroek (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
2258*b636d99dSDavid van Moolenbroek pdu_len));
2259*b636d99dSDavid van Moolenbroek
2260*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2261*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_LAN_HEADER_SIZE))
2262*b636d99dSDavid van Moolenbroek return(0);
2263*b636d99dSDavid van Moolenbroek }
2264*b636d99dSDavid van Moolenbroek
2265*b636d99dSDavid van Moolenbroek packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
2266*b636d99dSDavid van Moolenbroek pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
2267*b636d99dSDavid van Moolenbroek break;
2268*b636d99dSDavid van Moolenbroek
2269*b636d99dSDavid van Moolenbroek case ISIS_PDU_PTP_IIH:
2270*b636d99dSDavid van Moolenbroek if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
2271*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
2272*b636d99dSDavid van Moolenbroek isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE));
2273*b636d99dSDavid van Moolenbroek return (0);
2274*b636d99dSDavid van Moolenbroek }
2275*b636d99dSDavid van Moolenbroek
2276*b636d99dSDavid van Moolenbroek pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
2277*b636d99dSDavid van Moolenbroek if (packet_len>pdu_len) {
2278*b636d99dSDavid van Moolenbroek packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
2279*b636d99dSDavid van Moolenbroek length=pdu_len;
2280*b636d99dSDavid van Moolenbroek }
2281*b636d99dSDavid van Moolenbroek
2282*b636d99dSDavid van Moolenbroek ND_TCHECK(*header_iih_ptp);
2283*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t source-id: %s, holding time: %us, Flags: [%s]",
2284*b636d99dSDavid van Moolenbroek isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
2285*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_iih_ptp->holding_time),
2286*b636d99dSDavid van Moolenbroek tok2str(isis_iih_circuit_type_values,
2287*b636d99dSDavid van Moolenbroek "unknown circuit type 0x%02x",
2288*b636d99dSDavid van Moolenbroek header_iih_ptp->circuit_type)));
2289*b636d99dSDavid van Moolenbroek
2290*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t circuit-id: 0x%02x, PDU length: %u",
2291*b636d99dSDavid van Moolenbroek header_iih_ptp->circuit_id,
2292*b636d99dSDavid van Moolenbroek pdu_len));
2293*b636d99dSDavid van Moolenbroek
2294*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2295*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE))
2296*b636d99dSDavid van Moolenbroek return(0);
2297*b636d99dSDavid van Moolenbroek }
2298*b636d99dSDavid van Moolenbroek
2299*b636d99dSDavid van Moolenbroek packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
2300*b636d99dSDavid van Moolenbroek pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
2301*b636d99dSDavid van Moolenbroek break;
2302*b636d99dSDavid van Moolenbroek
2303*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_LSP:
2304*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_LSP:
2305*b636d99dSDavid van Moolenbroek if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
2306*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
2307*b636d99dSDavid van Moolenbroek isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE));
2308*b636d99dSDavid van Moolenbroek return (0);
2309*b636d99dSDavid van Moolenbroek }
2310*b636d99dSDavid van Moolenbroek
2311*b636d99dSDavid van Moolenbroek pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
2312*b636d99dSDavid van Moolenbroek if (packet_len>pdu_len) {
2313*b636d99dSDavid van Moolenbroek packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
2314*b636d99dSDavid van Moolenbroek length=pdu_len;
2315*b636d99dSDavid van Moolenbroek }
2316*b636d99dSDavid van Moolenbroek
2317*b636d99dSDavid van Moolenbroek ND_TCHECK(*header_lsp);
2318*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
2319*b636d99dSDavid van Moolenbroek isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
2320*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(header_lsp->sequence_number),
2321*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_lsp->remaining_lifetime),
2322*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_lsp->checksum)));
2323*b636d99dSDavid van Moolenbroek
2324*b636d99dSDavid van Moolenbroek
2325*b636d99dSDavid van Moolenbroek osi_print_cksum(ndo, (uint8_t *)header_lsp->lsp_id,
2326*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(header_lsp->checksum), 12, length-12);
2327*b636d99dSDavid van Moolenbroek
2328*b636d99dSDavid van Moolenbroek /*
2329*b636d99dSDavid van Moolenbroek * Clear checksum and lifetime prior to signature verification.
2330*b636d99dSDavid van Moolenbroek */
2331*b636d99dSDavid van Moolenbroek header_lsp->checksum[0] = 0;
2332*b636d99dSDavid van Moolenbroek header_lsp->checksum[1] = 0;
2333*b636d99dSDavid van Moolenbroek header_lsp->remaining_lifetime[0] = 0;
2334*b636d99dSDavid van Moolenbroek header_lsp->remaining_lifetime[1] = 0;
2335*b636d99dSDavid van Moolenbroek
2336*b636d99dSDavid van Moolenbroek
2337*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", PDU length: %u, Flags: [ %s",
2338*b636d99dSDavid van Moolenbroek pdu_len,
2339*b636d99dSDavid van Moolenbroek ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""));
2340*b636d99dSDavid van Moolenbroek
2341*b636d99dSDavid van Moolenbroek if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
2342*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""));
2343*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""));
2344*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""));
2345*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""));
2346*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "ATT bit set, "));
2347*b636d99dSDavid van Moolenbroek }
2348*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""));
2349*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s ]", tok2str(isis_lsp_istype_values, "Unknown(0x%x)",
2350*b636d99dSDavid van Moolenbroek ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))));
2351*b636d99dSDavid van Moolenbroek
2352*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2353*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_LSP_HEADER_SIZE))
2354*b636d99dSDavid van Moolenbroek return(0);
2355*b636d99dSDavid van Moolenbroek }
2356*b636d99dSDavid van Moolenbroek
2357*b636d99dSDavid van Moolenbroek packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
2358*b636d99dSDavid van Moolenbroek pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
2359*b636d99dSDavid van Moolenbroek break;
2360*b636d99dSDavid van Moolenbroek
2361*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_CSNP:
2362*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_CSNP:
2363*b636d99dSDavid van Moolenbroek if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
2364*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", bogus fixed header length %u should be %lu",
2365*b636d99dSDavid van Moolenbroek isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE));
2366*b636d99dSDavid van Moolenbroek return (0);
2367*b636d99dSDavid van Moolenbroek }
2368*b636d99dSDavid van Moolenbroek
2369*b636d99dSDavid van Moolenbroek pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
2370*b636d99dSDavid van Moolenbroek if (packet_len>pdu_len) {
2371*b636d99dSDavid van Moolenbroek packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
2372*b636d99dSDavid van Moolenbroek length=pdu_len;
2373*b636d99dSDavid van Moolenbroek }
2374*b636d99dSDavid van Moolenbroek
2375*b636d99dSDavid van Moolenbroek ND_TCHECK(*header_csnp);
2376*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
2377*b636d99dSDavid van Moolenbroek isis_print_id(header_csnp->source_id, NODE_ID_LEN),
2378*b636d99dSDavid van Moolenbroek pdu_len));
2379*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t start lsp-id: %s",
2380*b636d99dSDavid van Moolenbroek isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)));
2381*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t end lsp-id: %s",
2382*b636d99dSDavid van Moolenbroek isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)));
2383*b636d99dSDavid van Moolenbroek
2384*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2385*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_CSNP_HEADER_SIZE))
2386*b636d99dSDavid van Moolenbroek return(0);
2387*b636d99dSDavid van Moolenbroek }
2388*b636d99dSDavid van Moolenbroek
2389*b636d99dSDavid van Moolenbroek packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
2390*b636d99dSDavid van Moolenbroek pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
2391*b636d99dSDavid van Moolenbroek break;
2392*b636d99dSDavid van Moolenbroek
2393*b636d99dSDavid van Moolenbroek case ISIS_PDU_L1_PSNP:
2394*b636d99dSDavid van Moolenbroek case ISIS_PDU_L2_PSNP:
2395*b636d99dSDavid van Moolenbroek if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
2396*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "- bogus fixed header length %u should be %lu",
2397*b636d99dSDavid van Moolenbroek isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE));
2398*b636d99dSDavid van Moolenbroek return (0);
2399*b636d99dSDavid van Moolenbroek }
2400*b636d99dSDavid van Moolenbroek
2401*b636d99dSDavid van Moolenbroek pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
2402*b636d99dSDavid van Moolenbroek if (packet_len>pdu_len) {
2403*b636d99dSDavid van Moolenbroek packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
2404*b636d99dSDavid van Moolenbroek length=pdu_len;
2405*b636d99dSDavid van Moolenbroek }
2406*b636d99dSDavid van Moolenbroek
2407*b636d99dSDavid van Moolenbroek ND_TCHECK(*header_psnp);
2408*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t source-id: %s, PDU length: %u",
2409*b636d99dSDavid van Moolenbroek isis_print_id(header_psnp->source_id, NODE_ID_LEN),
2410*b636d99dSDavid van Moolenbroek pdu_len));
2411*b636d99dSDavid van Moolenbroek
2412*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1) {
2413*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_PSNP_HEADER_SIZE))
2414*b636d99dSDavid van Moolenbroek return(0);
2415*b636d99dSDavid van Moolenbroek }
2416*b636d99dSDavid van Moolenbroek
2417*b636d99dSDavid van Moolenbroek packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
2418*b636d99dSDavid van Moolenbroek pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
2419*b636d99dSDavid van Moolenbroek break;
2420*b636d99dSDavid van Moolenbroek
2421*b636d99dSDavid van Moolenbroek default:
2422*b636d99dSDavid van Moolenbroek (void)print_unknown_data(ndo, pptr, "\n\t ", length);
2423*b636d99dSDavid van Moolenbroek return (0);
2424*b636d99dSDavid van Moolenbroek }
2425*b636d99dSDavid van Moolenbroek
2426*b636d99dSDavid van Moolenbroek /*
2427*b636d99dSDavid van Moolenbroek * Now print the TLV's.
2428*b636d99dSDavid van Moolenbroek */
2429*b636d99dSDavid van Moolenbroek
2430*b636d99dSDavid van Moolenbroek while (packet_len >= 2) {
2431*b636d99dSDavid van Moolenbroek if (pptr == ndo->ndo_snapend) {
2432*b636d99dSDavid van Moolenbroek return (1);
2433*b636d99dSDavid van Moolenbroek }
2434*b636d99dSDavid van Moolenbroek
2435*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*pptr, 2)) {
2436*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t packet exceeded snapshot (%ld) bytes",
2437*b636d99dSDavid van Moolenbroek (long)(pptr - ndo->ndo_snapend)));
2438*b636d99dSDavid van Moolenbroek return (1);
2439*b636d99dSDavid van Moolenbroek }
2440*b636d99dSDavid van Moolenbroek tlv_type = *pptr++;
2441*b636d99dSDavid van Moolenbroek tlv_len = *pptr++;
2442*b636d99dSDavid van Moolenbroek tmp =tlv_len; /* copy temporary len & pointer to packet data */
2443*b636d99dSDavid van Moolenbroek tptr = pptr;
2444*b636d99dSDavid van Moolenbroek packet_len -= 2;
2445*b636d99dSDavid van Moolenbroek if (tlv_len > packet_len) {
2446*b636d99dSDavid van Moolenbroek break;
2447*b636d99dSDavid van Moolenbroek }
2448*b636d99dSDavid van Moolenbroek
2449*b636d99dSDavid van Moolenbroek /* first lets see if we know the TLVs name*/
2450*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s TLV #%u, length: %u",
2451*b636d99dSDavid van Moolenbroek tok2str(isis_tlv_values,
2452*b636d99dSDavid van Moolenbroek "unknown",
2453*b636d99dSDavid van Moolenbroek tlv_type),
2454*b636d99dSDavid van Moolenbroek tlv_type,
2455*b636d99dSDavid van Moolenbroek tlv_len));
2456*b636d99dSDavid van Moolenbroek
2457*b636d99dSDavid van Moolenbroek if (tlv_len == 0) /* something is malformed */
2458*b636d99dSDavid van Moolenbroek continue;
2459*b636d99dSDavid van Moolenbroek
2460*b636d99dSDavid van Moolenbroek /* now check if we have a decoder otherwise do a hexdump at the end*/
2461*b636d99dSDavid van Moolenbroek switch (tlv_type) {
2462*b636d99dSDavid van Moolenbroek case ISIS_TLV_AREA_ADDR:
2463*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2464*b636d99dSDavid van Moolenbroek goto trunctlv;
2465*b636d99dSDavid van Moolenbroek alen = *tptr++;
2466*b636d99dSDavid van Moolenbroek while (tmp && alen < tmp) {
2467*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Area address (length: %u): %s",
2468*b636d99dSDavid van Moolenbroek alen,
2469*b636d99dSDavid van Moolenbroek isonsap_string(tptr, alen)));
2470*b636d99dSDavid van Moolenbroek tptr += alen;
2471*b636d99dSDavid van Moolenbroek tmp -= alen + 1;
2472*b636d99dSDavid van Moolenbroek if (tmp==0) /* if this is the last area address do not attemt a boundary check */
2473*b636d99dSDavid van Moolenbroek break;
2474*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2475*b636d99dSDavid van Moolenbroek goto trunctlv;
2476*b636d99dSDavid van Moolenbroek alen = *tptr++;
2477*b636d99dSDavid van Moolenbroek }
2478*b636d99dSDavid van Moolenbroek break;
2479*b636d99dSDavid van Moolenbroek case ISIS_TLV_ISNEIGH:
2480*b636d99dSDavid van Moolenbroek while (tmp >= ETHER_ADDR_LEN) {
2481*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ETHER_ADDR_LEN))
2482*b636d99dSDavid van Moolenbroek goto trunctlv;
2483*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t SNPA: %s", isis_print_id(tptr, ETHER_ADDR_LEN)));
2484*b636d99dSDavid van Moolenbroek tmp -= ETHER_ADDR_LEN;
2485*b636d99dSDavid van Moolenbroek tptr += ETHER_ADDR_LEN;
2486*b636d99dSDavid van Moolenbroek }
2487*b636d99dSDavid van Moolenbroek break;
2488*b636d99dSDavid van Moolenbroek
2489*b636d99dSDavid van Moolenbroek case ISIS_TLV_ISNEIGH_VARLEN:
2490*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */
2491*b636d99dSDavid van Moolenbroek goto trunctlv;
2492*b636d99dSDavid van Moolenbroek lan_alen = *tptr++; /* LAN address length */
2493*b636d99dSDavid van Moolenbroek if (lan_alen == 0) {
2494*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t LAN address length 0 bytes (invalid)"));
2495*b636d99dSDavid van Moolenbroek break;
2496*b636d99dSDavid van Moolenbroek }
2497*b636d99dSDavid van Moolenbroek tmp --;
2498*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t LAN address length %u bytes ", lan_alen));
2499*b636d99dSDavid van Moolenbroek while (tmp >= lan_alen) {
2500*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, lan_alen))
2501*b636d99dSDavid van Moolenbroek goto trunctlv;
2502*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\tIS Neighbor: %s", isis_print_id(tptr, lan_alen)));
2503*b636d99dSDavid van Moolenbroek tmp -= lan_alen;
2504*b636d99dSDavid van Moolenbroek tptr +=lan_alen;
2505*b636d99dSDavid van Moolenbroek }
2506*b636d99dSDavid van Moolenbroek break;
2507*b636d99dSDavid van Moolenbroek
2508*b636d99dSDavid van Moolenbroek case ISIS_TLV_PADDING:
2509*b636d99dSDavid van Moolenbroek break;
2510*b636d99dSDavid van Moolenbroek
2511*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_IS_REACH:
2512*b636d99dSDavid van Moolenbroek mt_len = isis_print_mtid(ndo, tptr, "\n\t ");
2513*b636d99dSDavid van Moolenbroek if (mt_len == 0) /* did something go wrong ? */
2514*b636d99dSDavid van Moolenbroek goto trunctlv;
2515*b636d99dSDavid van Moolenbroek tptr+=mt_len;
2516*b636d99dSDavid van Moolenbroek tmp-=mt_len;
2517*b636d99dSDavid van Moolenbroek while (tmp >= 2+NODE_ID_LEN+3+1) {
2518*b636d99dSDavid van Moolenbroek ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type);
2519*b636d99dSDavid van Moolenbroek if (ext_is_len == 0) /* did something go wrong ? */
2520*b636d99dSDavid van Moolenbroek goto trunctlv;
2521*b636d99dSDavid van Moolenbroek
2522*b636d99dSDavid van Moolenbroek tmp-=ext_is_len;
2523*b636d99dSDavid van Moolenbroek tptr+=ext_is_len;
2524*b636d99dSDavid van Moolenbroek }
2525*b636d99dSDavid van Moolenbroek break;
2526*b636d99dSDavid van Moolenbroek
2527*b636d99dSDavid van Moolenbroek case ISIS_TLV_IS_ALIAS_ID:
2528*b636d99dSDavid van Moolenbroek while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */
2529*b636d99dSDavid van Moolenbroek ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type);
2530*b636d99dSDavid van Moolenbroek if (ext_is_len == 0) /* did something go wrong ? */
2531*b636d99dSDavid van Moolenbroek goto trunctlv;
2532*b636d99dSDavid van Moolenbroek tmp-=ext_is_len;
2533*b636d99dSDavid van Moolenbroek tptr+=ext_is_len;
2534*b636d99dSDavid van Moolenbroek }
2535*b636d99dSDavid van Moolenbroek break;
2536*b636d99dSDavid van Moolenbroek
2537*b636d99dSDavid van Moolenbroek case ISIS_TLV_EXT_IS_REACH:
2538*b636d99dSDavid van Moolenbroek while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */
2539*b636d99dSDavid van Moolenbroek ext_is_len = isis_print_ext_is_reach(ndo, tptr, "\n\t ", tlv_type);
2540*b636d99dSDavid van Moolenbroek if (ext_is_len == 0) /* did something go wrong ? */
2541*b636d99dSDavid van Moolenbroek goto trunctlv;
2542*b636d99dSDavid van Moolenbroek tmp-=ext_is_len;
2543*b636d99dSDavid van Moolenbroek tptr+=ext_is_len;
2544*b636d99dSDavid van Moolenbroek }
2545*b636d99dSDavid van Moolenbroek break;
2546*b636d99dSDavid van Moolenbroek case ISIS_TLV_IS_REACH:
2547*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
2548*b636d99dSDavid van Moolenbroek goto trunctlv;
2549*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s",
2550*b636d99dSDavid van Moolenbroek tok2str(isis_is_reach_virtual_values,
2551*b636d99dSDavid van Moolenbroek "bogus virtual flag 0x%02x",
2552*b636d99dSDavid van Moolenbroek *tptr++)));
2553*b636d99dSDavid van Moolenbroek tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
2554*b636d99dSDavid van Moolenbroek while (tmp >= sizeof(struct isis_tlv_is_reach)) {
2555*b636d99dSDavid van Moolenbroek if (!ND_TTEST(*tlv_is_reach))
2556*b636d99dSDavid van Moolenbroek goto trunctlv;
2557*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IS Neighbor: %s",
2558*b636d99dSDavid van Moolenbroek isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)));
2559*b636d99dSDavid van Moolenbroek isis_print_metric_block(ndo, &tlv_is_reach->isis_metric_block);
2560*b636d99dSDavid van Moolenbroek tmp -= sizeof(struct isis_tlv_is_reach);
2561*b636d99dSDavid van Moolenbroek tlv_is_reach++;
2562*b636d99dSDavid van Moolenbroek }
2563*b636d99dSDavid van Moolenbroek break;
2564*b636d99dSDavid van Moolenbroek
2565*b636d99dSDavid van Moolenbroek case ISIS_TLV_ESNEIGH:
2566*b636d99dSDavid van Moolenbroek tlv_es_reach = (const struct isis_tlv_es_reach *)tptr;
2567*b636d99dSDavid van Moolenbroek while (tmp >= sizeof(struct isis_tlv_es_reach)) {
2568*b636d99dSDavid van Moolenbroek if (!ND_TTEST(*tlv_es_reach))
2569*b636d99dSDavid van Moolenbroek goto trunctlv;
2570*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t ES Neighbor: %s",
2571*b636d99dSDavid van Moolenbroek isis_print_id(tlv_es_reach->neighbor_sysid, SYSTEM_ID_LEN)));
2572*b636d99dSDavid van Moolenbroek isis_print_metric_block(ndo, &tlv_es_reach->isis_metric_block);
2573*b636d99dSDavid van Moolenbroek tmp -= sizeof(struct isis_tlv_es_reach);
2574*b636d99dSDavid van Moolenbroek tlv_es_reach++;
2575*b636d99dSDavid van Moolenbroek }
2576*b636d99dSDavid van Moolenbroek break;
2577*b636d99dSDavid van Moolenbroek
2578*b636d99dSDavid van Moolenbroek /* those two TLVs share the same format */
2579*b636d99dSDavid van Moolenbroek case ISIS_TLV_INT_IP_REACH:
2580*b636d99dSDavid van Moolenbroek case ISIS_TLV_EXT_IP_REACH:
2581*b636d99dSDavid van Moolenbroek if (!isis_print_tlv_ip_reach(ndo, pptr, "\n\t ", tlv_len))
2582*b636d99dSDavid van Moolenbroek return (1);
2583*b636d99dSDavid van Moolenbroek break;
2584*b636d99dSDavid van Moolenbroek
2585*b636d99dSDavid van Moolenbroek case ISIS_TLV_EXTD_IP_REACH:
2586*b636d99dSDavid van Moolenbroek while (tmp>0) {
2587*b636d99dSDavid van Moolenbroek ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET);
2588*b636d99dSDavid van Moolenbroek if (ext_ip_len == 0) /* did something go wrong ? */
2589*b636d99dSDavid van Moolenbroek goto trunctlv;
2590*b636d99dSDavid van Moolenbroek tptr+=ext_ip_len;
2591*b636d99dSDavid van Moolenbroek tmp-=ext_ip_len;
2592*b636d99dSDavid van Moolenbroek }
2593*b636d99dSDavid van Moolenbroek break;
2594*b636d99dSDavid van Moolenbroek
2595*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_IP_REACH:
2596*b636d99dSDavid van Moolenbroek mt_len = isis_print_mtid(ndo, tptr, "\n\t ");
2597*b636d99dSDavid van Moolenbroek if (mt_len == 0) { /* did something go wrong ? */
2598*b636d99dSDavid van Moolenbroek goto trunctlv;
2599*b636d99dSDavid van Moolenbroek }
2600*b636d99dSDavid van Moolenbroek tptr+=mt_len;
2601*b636d99dSDavid van Moolenbroek tmp-=mt_len;
2602*b636d99dSDavid van Moolenbroek
2603*b636d99dSDavid van Moolenbroek while (tmp>0) {
2604*b636d99dSDavid van Moolenbroek ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET);
2605*b636d99dSDavid van Moolenbroek if (ext_ip_len == 0) /* did something go wrong ? */
2606*b636d99dSDavid van Moolenbroek goto trunctlv;
2607*b636d99dSDavid van Moolenbroek tptr+=ext_ip_len;
2608*b636d99dSDavid van Moolenbroek tmp-=ext_ip_len;
2609*b636d99dSDavid van Moolenbroek }
2610*b636d99dSDavid van Moolenbroek break;
2611*b636d99dSDavid van Moolenbroek
2612*b636d99dSDavid van Moolenbroek #ifdef INET6
2613*b636d99dSDavid van Moolenbroek case ISIS_TLV_IP6_REACH:
2614*b636d99dSDavid van Moolenbroek while (tmp>0) {
2615*b636d99dSDavid van Moolenbroek ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6);
2616*b636d99dSDavid van Moolenbroek if (ext_ip_len == 0) /* did something go wrong ? */
2617*b636d99dSDavid van Moolenbroek goto trunctlv;
2618*b636d99dSDavid van Moolenbroek tptr+=ext_ip_len;
2619*b636d99dSDavid van Moolenbroek tmp-=ext_ip_len;
2620*b636d99dSDavid van Moolenbroek }
2621*b636d99dSDavid van Moolenbroek break;
2622*b636d99dSDavid van Moolenbroek
2623*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_IP6_REACH:
2624*b636d99dSDavid van Moolenbroek mt_len = isis_print_mtid(ndo, tptr, "\n\t ");
2625*b636d99dSDavid van Moolenbroek if (mt_len == 0) { /* did something go wrong ? */
2626*b636d99dSDavid van Moolenbroek goto trunctlv;
2627*b636d99dSDavid van Moolenbroek }
2628*b636d99dSDavid van Moolenbroek tptr+=mt_len;
2629*b636d99dSDavid van Moolenbroek tmp-=mt_len;
2630*b636d99dSDavid van Moolenbroek
2631*b636d99dSDavid van Moolenbroek while (tmp>0) {
2632*b636d99dSDavid van Moolenbroek ext_ip_len = isis_print_extd_ip_reach(ndo, tptr, "\n\t ", AF_INET6);
2633*b636d99dSDavid van Moolenbroek if (ext_ip_len == 0) /* did something go wrong ? */
2634*b636d99dSDavid van Moolenbroek goto trunctlv;
2635*b636d99dSDavid van Moolenbroek tptr+=ext_ip_len;
2636*b636d99dSDavid van Moolenbroek tmp-=ext_ip_len;
2637*b636d99dSDavid van Moolenbroek }
2638*b636d99dSDavid van Moolenbroek break;
2639*b636d99dSDavid van Moolenbroek
2640*b636d99dSDavid van Moolenbroek case ISIS_TLV_IP6ADDR:
2641*b636d99dSDavid van Moolenbroek while (tmp>=sizeof(struct in6_addr)) {
2642*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, sizeof(struct in6_addr)))
2643*b636d99dSDavid van Moolenbroek goto trunctlv;
2644*b636d99dSDavid van Moolenbroek
2645*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv6 interface address: %s",
2646*b636d99dSDavid van Moolenbroek ip6addr_string(ndo, tptr)));
2647*b636d99dSDavid van Moolenbroek
2648*b636d99dSDavid van Moolenbroek tptr += sizeof(struct in6_addr);
2649*b636d99dSDavid van Moolenbroek tmp -= sizeof(struct in6_addr);
2650*b636d99dSDavid van Moolenbroek }
2651*b636d99dSDavid van Moolenbroek break;
2652*b636d99dSDavid van Moolenbroek #endif
2653*b636d99dSDavid van Moolenbroek case ISIS_TLV_AUTH:
2654*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2655*b636d99dSDavid van Moolenbroek goto trunctlv;
2656*b636d99dSDavid van Moolenbroek
2657*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s: ",
2658*b636d99dSDavid van Moolenbroek tok2str(isis_subtlv_auth_values,
2659*b636d99dSDavid van Moolenbroek "unknown Authentication type 0x%02x",
2660*b636d99dSDavid van Moolenbroek *tptr)));
2661*b636d99dSDavid van Moolenbroek
2662*b636d99dSDavid van Moolenbroek switch (*tptr) {
2663*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_AUTH_SIMPLE:
2664*b636d99dSDavid van Moolenbroek for(i=1;i<tlv_len;i++) {
2665*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr + i), 1))
2666*b636d99dSDavid van Moolenbroek goto trunctlv;
2667*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%c", *(tptr + i)));
2668*b636d99dSDavid van Moolenbroek }
2669*b636d99dSDavid van Moolenbroek break;
2670*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_AUTH_MD5:
2671*b636d99dSDavid van Moolenbroek for(i=1;i<tlv_len;i++) {
2672*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr + i), 1))
2673*b636d99dSDavid van Moolenbroek goto trunctlv;
2674*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%02x", *(tptr + i)));
2675*b636d99dSDavid van Moolenbroek }
2676*b636d99dSDavid van Moolenbroek if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1)
2677*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", (malformed subTLV) "));
2678*b636d99dSDavid van Moolenbroek
2679*b636d99dSDavid van Moolenbroek #ifdef HAVE_LIBCRYPTO
2680*b636d99dSDavid van Moolenbroek sigcheck = signature_verify(ndo, optr, length,
2681*b636d99dSDavid van Moolenbroek (unsigned char *)tptr + 1);
2682*b636d99dSDavid van Moolenbroek #else
2683*b636d99dSDavid van Moolenbroek sigcheck = CANT_CHECK_SIGNATURE;
2684*b636d99dSDavid van Moolenbroek #endif
2685*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " (%s)", tok2str(signature_check_values, "Unknown", sigcheck)));
2686*b636d99dSDavid van Moolenbroek
2687*b636d99dSDavid van Moolenbroek break;
2688*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_AUTH_GENERIC:
2689*b636d99dSDavid van Moolenbroek key_id = EXTRACT_16BITS((tptr+1));
2690*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%u, password: ", key_id));
2691*b636d99dSDavid van Moolenbroek for(i=1 + sizeof(uint16_t);i<tlv_len;i++) {
2692*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr + i), 1))
2693*b636d99dSDavid van Moolenbroek goto trunctlv;
2694*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%02x", *(tptr + i)));
2695*b636d99dSDavid van Moolenbroek }
2696*b636d99dSDavid van Moolenbroek break;
2697*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_AUTH_PRIVATE:
2698*b636d99dSDavid van Moolenbroek default:
2699*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr + 1, "\n\t\t ", tlv_len - 1))
2700*b636d99dSDavid van Moolenbroek return(0);
2701*b636d99dSDavid van Moolenbroek break;
2702*b636d99dSDavid van Moolenbroek }
2703*b636d99dSDavid van Moolenbroek break;
2704*b636d99dSDavid van Moolenbroek
2705*b636d99dSDavid van Moolenbroek case ISIS_TLV_PTP_ADJ:
2706*b636d99dSDavid van Moolenbroek tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
2707*b636d99dSDavid van Moolenbroek if(tmp>=1) {
2708*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2709*b636d99dSDavid van Moolenbroek goto trunctlv;
2710*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Adjacency State: %s (%u)",
2711*b636d99dSDavid van Moolenbroek tok2str(isis_ptp_adjancey_values, "unknown", *tptr),
2712*b636d99dSDavid van Moolenbroek *tptr));
2713*b636d99dSDavid van Moolenbroek tmp--;
2714*b636d99dSDavid van Moolenbroek }
2715*b636d99dSDavid van Moolenbroek if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
2716*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_ptp_adj->extd_local_circuit_id,
2717*b636d99dSDavid van Moolenbroek sizeof(tlv_ptp_adj->extd_local_circuit_id)))
2718*b636d99dSDavid van Moolenbroek goto trunctlv;
2719*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Extended Local circuit-ID: 0x%08x",
2720*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)));
2721*b636d99dSDavid van Moolenbroek tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
2722*b636d99dSDavid van Moolenbroek }
2723*b636d99dSDavid van Moolenbroek if(tmp>=SYSTEM_ID_LEN) {
2724*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN))
2725*b636d99dSDavid van Moolenbroek goto trunctlv;
2726*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Neighbor System-ID: %s",
2727*b636d99dSDavid van Moolenbroek isis_print_id(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)));
2728*b636d99dSDavid van Moolenbroek tmp-=SYSTEM_ID_LEN;
2729*b636d99dSDavid van Moolenbroek }
2730*b636d99dSDavid van Moolenbroek if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
2731*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id,
2732*b636d99dSDavid van Moolenbroek sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)))
2733*b636d99dSDavid van Moolenbroek goto trunctlv;
2734*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Neighbor Extended Local circuit-ID: 0x%08x",
2735*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)));
2736*b636d99dSDavid van Moolenbroek }
2737*b636d99dSDavid van Moolenbroek break;
2738*b636d99dSDavid van Moolenbroek
2739*b636d99dSDavid van Moolenbroek case ISIS_TLV_PROTOCOLS:
2740*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t NLPID(s): "));
2741*b636d99dSDavid van Moolenbroek while (tmp>0) {
2742*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), 1))
2743*b636d99dSDavid van Moolenbroek goto trunctlv;
2744*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s (0x%02x)",
2745*b636d99dSDavid van Moolenbroek tok2str(nlpid_values,
2746*b636d99dSDavid van Moolenbroek "unknown",
2747*b636d99dSDavid van Moolenbroek *tptr),
2748*b636d99dSDavid van Moolenbroek *tptr));
2749*b636d99dSDavid van Moolenbroek if (tmp>1) /* further NPLIDs ? - put comma */
2750*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", "));
2751*b636d99dSDavid van Moolenbroek tptr++;
2752*b636d99dSDavid van Moolenbroek tmp--;
2753*b636d99dSDavid van Moolenbroek }
2754*b636d99dSDavid van Moolenbroek break;
2755*b636d99dSDavid van Moolenbroek
2756*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_PORT_CAP:
2757*b636d99dSDavid van Moolenbroek {
2758*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), 2))
2759*b636d99dSDavid van Moolenbroek goto trunctlv;
2760*b636d99dSDavid van Moolenbroek
2761*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t RES: %d, MTID(s): %d",
2762*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS (tptr) >> 12),
2763*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS (tptr) & 0x0fff)));
2764*b636d99dSDavid van Moolenbroek
2765*b636d99dSDavid van Moolenbroek tmp = tmp-2;
2766*b636d99dSDavid van Moolenbroek tptr = tptr+2;
2767*b636d99dSDavid van Moolenbroek
2768*b636d99dSDavid van Moolenbroek if (tmp)
2769*b636d99dSDavid van Moolenbroek isis_print_mt_port_cap_subtlv(ndo, tptr, tmp);
2770*b636d99dSDavid van Moolenbroek
2771*b636d99dSDavid van Moolenbroek break;
2772*b636d99dSDavid van Moolenbroek }
2773*b636d99dSDavid van Moolenbroek
2774*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_CAPABILITY:
2775*b636d99dSDavid van Moolenbroek
2776*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*(tptr), 2))
2777*b636d99dSDavid van Moolenbroek goto trunctlv;
2778*b636d99dSDavid van Moolenbroek
2779*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t O: %d, RES: %d, MTID(s): %d",
2780*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS(tptr) >> 15) & 0x01,
2781*b636d99dSDavid van Moolenbroek (EXTRACT_16BITS(tptr) >> 12) & 0x07,
2782*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tptr) & 0x0fff));
2783*b636d99dSDavid van Moolenbroek
2784*b636d99dSDavid van Moolenbroek tmp = tmp-2;
2785*b636d99dSDavid van Moolenbroek tptr = tptr+2;
2786*b636d99dSDavid van Moolenbroek
2787*b636d99dSDavid van Moolenbroek if (tmp)
2788*b636d99dSDavid van Moolenbroek isis_print_mt_capability_subtlv(ndo, tptr, tmp);
2789*b636d99dSDavid van Moolenbroek
2790*b636d99dSDavid van Moolenbroek break;
2791*b636d99dSDavid van Moolenbroek
2792*b636d99dSDavid van Moolenbroek case ISIS_TLV_TE_ROUTER_ID:
2793*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*pptr, sizeof(struct in_addr)))
2794*b636d99dSDavid van Moolenbroek goto trunctlv;
2795*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Traffic Engineering Router ID: %s", ipaddr_string(ndo, pptr)));
2796*b636d99dSDavid van Moolenbroek break;
2797*b636d99dSDavid van Moolenbroek
2798*b636d99dSDavid van Moolenbroek case ISIS_TLV_IPADDR:
2799*b636d99dSDavid van Moolenbroek while (tmp>=sizeof(struct in_addr)) {
2800*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, sizeof(struct in_addr)))
2801*b636d99dSDavid van Moolenbroek goto trunctlv;
2802*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr)));
2803*b636d99dSDavid van Moolenbroek tptr += sizeof(struct in_addr);
2804*b636d99dSDavid van Moolenbroek tmp -= sizeof(struct in_addr);
2805*b636d99dSDavid van Moolenbroek }
2806*b636d99dSDavid van Moolenbroek break;
2807*b636d99dSDavid van Moolenbroek
2808*b636d99dSDavid van Moolenbroek case ISIS_TLV_HOSTNAME:
2809*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Hostname: "));
2810*b636d99dSDavid van Moolenbroek while (tmp>0) {
2811*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2812*b636d99dSDavid van Moolenbroek goto trunctlv;
2813*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%c", *tptr++));
2814*b636d99dSDavid van Moolenbroek tmp--;
2815*b636d99dSDavid van Moolenbroek }
2816*b636d99dSDavid van Moolenbroek break;
2817*b636d99dSDavid van Moolenbroek
2818*b636d99dSDavid van Moolenbroek case ISIS_TLV_SHARED_RISK_GROUP:
2819*b636d99dSDavid van Moolenbroek if (tmp < NODE_ID_LEN)
2820*b636d99dSDavid van Moolenbroek break;
2821*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, NODE_ID_LEN))
2822*b636d99dSDavid van Moolenbroek goto trunctlv;
2823*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)));
2824*b636d99dSDavid van Moolenbroek tptr+=(NODE_ID_LEN);
2825*b636d99dSDavid van Moolenbroek tmp-=(NODE_ID_LEN);
2826*b636d99dSDavid van Moolenbroek
2827*b636d99dSDavid van Moolenbroek if (tmp < 1)
2828*b636d99dSDavid van Moolenbroek break;
2829*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2830*b636d99dSDavid van Moolenbroek goto trunctlv;
2831*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"));
2832*b636d99dSDavid van Moolenbroek tmp--;
2833*b636d99dSDavid van Moolenbroek
2834*b636d99dSDavid van Moolenbroek if (tmp < sizeof(struct in_addr))
2835*b636d99dSDavid van Moolenbroek break;
2836*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, sizeof(struct in_addr)))
2837*b636d99dSDavid van Moolenbroek goto trunctlv;
2838*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr)));
2839*b636d99dSDavid van Moolenbroek tptr+=sizeof(struct in_addr);
2840*b636d99dSDavid van Moolenbroek tmp-=sizeof(struct in_addr);
2841*b636d99dSDavid van Moolenbroek
2842*b636d99dSDavid van Moolenbroek if (tmp < sizeof(struct in_addr))
2843*b636d99dSDavid van Moolenbroek break;
2844*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, sizeof(struct in_addr)))
2845*b636d99dSDavid van Moolenbroek goto trunctlv;
2846*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv4 neighbor address: %s", ipaddr_string(ndo, tptr)));
2847*b636d99dSDavid van Moolenbroek tptr+=sizeof(struct in_addr);
2848*b636d99dSDavid van Moolenbroek tmp-=sizeof(struct in_addr);
2849*b636d99dSDavid van Moolenbroek
2850*b636d99dSDavid van Moolenbroek while (tmp>=4) {
2851*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 4))
2852*b636d99dSDavid van Moolenbroek goto trunctlv;
2853*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)));
2854*b636d99dSDavid van Moolenbroek tptr+=4;
2855*b636d99dSDavid van Moolenbroek tmp-=4;
2856*b636d99dSDavid van Moolenbroek }
2857*b636d99dSDavid van Moolenbroek break;
2858*b636d99dSDavid van Moolenbroek
2859*b636d99dSDavid van Moolenbroek case ISIS_TLV_LSP:
2860*b636d99dSDavid van Moolenbroek tlv_lsp = (const struct isis_tlv_lsp *)tptr;
2861*b636d99dSDavid van Moolenbroek while(tmp>=sizeof(struct isis_tlv_lsp)) {
2862*b636d99dSDavid van Moolenbroek if (!ND_TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1]))
2863*b636d99dSDavid van Moolenbroek goto trunctlv;
2864*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t lsp-id: %s",
2865*b636d99dSDavid van Moolenbroek isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)));
2866*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_lsp->sequence_number, 4))
2867*b636d99dSDavid van Moolenbroek goto trunctlv;
2868*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", seq: 0x%08x", EXTRACT_32BITS(tlv_lsp->sequence_number)));
2869*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_lsp->remaining_lifetime, 2))
2870*b636d99dSDavid van Moolenbroek goto trunctlv;
2871*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", lifetime: %5ds", EXTRACT_16BITS(tlv_lsp->remaining_lifetime)));
2872*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(tlv_lsp->checksum, 2))
2873*b636d99dSDavid van Moolenbroek goto trunctlv;
2874*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", chksum: 0x%04x", EXTRACT_16BITS(tlv_lsp->checksum)));
2875*b636d99dSDavid van Moolenbroek tmp-=sizeof(struct isis_tlv_lsp);
2876*b636d99dSDavid van Moolenbroek tlv_lsp++;
2877*b636d99dSDavid van Moolenbroek }
2878*b636d99dSDavid van Moolenbroek break;
2879*b636d99dSDavid van Moolenbroek
2880*b636d99dSDavid van Moolenbroek case ISIS_TLV_CHECKSUM:
2881*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_CHECKSUM_MINLEN)
2882*b636d99dSDavid van Moolenbroek break;
2883*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN))
2884*b636d99dSDavid van Moolenbroek goto trunctlv;
2885*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)));
2886*b636d99dSDavid van Moolenbroek /* do not attempt to verify the checksum if it is zero
2887*b636d99dSDavid van Moolenbroek * most likely a HMAC-MD5 TLV is also present and
2888*b636d99dSDavid van Moolenbroek * to avoid conflicts the checksum TLV is zeroed.
2889*b636d99dSDavid van Moolenbroek * see rfc3358 for details
2890*b636d99dSDavid van Moolenbroek */
2891*b636d99dSDavid van Moolenbroek osi_print_cksum(ndo, optr, EXTRACT_16BITS(tptr), tptr-optr, length);
2892*b636d99dSDavid van Moolenbroek break;
2893*b636d99dSDavid van Moolenbroek
2894*b636d99dSDavid van Moolenbroek case ISIS_TLV_MT_SUPPORTED:
2895*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN)
2896*b636d99dSDavid van Moolenbroek break;
2897*b636d99dSDavid van Moolenbroek while (tmp>1) {
2898*b636d99dSDavid van Moolenbroek /* length can only be a multiple of 2, otherwise there is
2899*b636d99dSDavid van Moolenbroek something broken -> so decode down until length is 1 */
2900*b636d99dSDavid van Moolenbroek if (tmp!=1) {
2901*b636d99dSDavid van Moolenbroek mt_len = isis_print_mtid(ndo, tptr, "\n\t ");
2902*b636d99dSDavid van Moolenbroek if (mt_len == 0) /* did something go wrong ? */
2903*b636d99dSDavid van Moolenbroek goto trunctlv;
2904*b636d99dSDavid van Moolenbroek tptr+=mt_len;
2905*b636d99dSDavid van Moolenbroek tmp-=mt_len;
2906*b636d99dSDavid van Moolenbroek } else {
2907*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t malformed MT-ID"));
2908*b636d99dSDavid van Moolenbroek break;
2909*b636d99dSDavid van Moolenbroek }
2910*b636d99dSDavid van Moolenbroek }
2911*b636d99dSDavid van Moolenbroek break;
2912*b636d99dSDavid van Moolenbroek
2913*b636d99dSDavid van Moolenbroek case ISIS_TLV_RESTART_SIGNALING:
2914*b636d99dSDavid van Moolenbroek /* first attempt to decode the flags */
2915*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN)
2916*b636d99dSDavid van Moolenbroek break;
2917*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN))
2918*b636d99dSDavid van Moolenbroek goto trunctlv;
2919*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Flags [%s]",
2920*b636d99dSDavid van Moolenbroek bittok2str(isis_restart_flag_values, "none", *tptr)));
2921*b636d99dSDavid van Moolenbroek tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
2922*b636d99dSDavid van Moolenbroek tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
2923*b636d99dSDavid van Moolenbroek
2924*b636d99dSDavid van Moolenbroek /* is there anything other than the flags field? */
2925*b636d99dSDavid van Moolenbroek if (tmp == 0)
2926*b636d99dSDavid van Moolenbroek break;
2927*b636d99dSDavid van Moolenbroek
2928*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)
2929*b636d99dSDavid van Moolenbroek break;
2930*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN))
2931*b636d99dSDavid van Moolenbroek goto trunctlv;
2932*b636d99dSDavid van Moolenbroek
2933*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", Remaining holding time %us", EXTRACT_16BITS(tptr)));
2934*b636d99dSDavid van Moolenbroek tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
2935*b636d99dSDavid van Moolenbroek tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
2936*b636d99dSDavid van Moolenbroek
2937*b636d99dSDavid van Moolenbroek /* is there an additional sysid field present ?*/
2938*b636d99dSDavid van Moolenbroek if (tmp == SYSTEM_ID_LEN) {
2939*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, SYSTEM_ID_LEN))
2940*b636d99dSDavid van Moolenbroek goto trunctlv;
2941*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, ", for %s", isis_print_id(tptr,SYSTEM_ID_LEN)));
2942*b636d99dSDavid van Moolenbroek }
2943*b636d99dSDavid van Moolenbroek break;
2944*b636d99dSDavid van Moolenbroek
2945*b636d99dSDavid van Moolenbroek case ISIS_TLV_IDRP_INFO:
2946*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_IDRP_INFO_MINLEN)
2947*b636d99dSDavid van Moolenbroek break;
2948*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN))
2949*b636d99dSDavid van Moolenbroek goto trunctlv;
2950*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Inter-Domain Information Type: %s",
2951*b636d99dSDavid van Moolenbroek tok2str(isis_subtlv_idrp_values,
2952*b636d99dSDavid van Moolenbroek "Unknown (0x%02x)",
2953*b636d99dSDavid van Moolenbroek *tptr)));
2954*b636d99dSDavid van Moolenbroek switch (*tptr++) {
2955*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_IDRP_ASN:
2956*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 2)) /* fetch AS number */
2957*b636d99dSDavid van Moolenbroek goto trunctlv;
2958*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "AS Number: %u", EXTRACT_16BITS(tptr)));
2959*b636d99dSDavid van Moolenbroek break;
2960*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_IDRP_LOCAL:
2961*b636d99dSDavid van Moolenbroek case ISIS_SUBTLV_IDRP_RES:
2962*b636d99dSDavid van Moolenbroek default:
2963*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_len - 1))
2964*b636d99dSDavid van Moolenbroek return(0);
2965*b636d99dSDavid van Moolenbroek break;
2966*b636d99dSDavid van Moolenbroek }
2967*b636d99dSDavid van Moolenbroek break;
2968*b636d99dSDavid van Moolenbroek
2969*b636d99dSDavid van Moolenbroek case ISIS_TLV_LSP_BUFFERSIZE:
2970*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN)
2971*b636d99dSDavid van Moolenbroek break;
2972*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN))
2973*b636d99dSDavid van Moolenbroek goto trunctlv;
2974*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t LSP Buffersize: %u", EXTRACT_16BITS(tptr)));
2975*b636d99dSDavid van Moolenbroek break;
2976*b636d99dSDavid van Moolenbroek
2977*b636d99dSDavid van Moolenbroek case ISIS_TLV_PART_DIS:
2978*b636d99dSDavid van Moolenbroek while (tmp >= SYSTEM_ID_LEN) {
2979*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, SYSTEM_ID_LEN))
2980*b636d99dSDavid van Moolenbroek goto trunctlv;
2981*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s", isis_print_id(tptr, SYSTEM_ID_LEN)));
2982*b636d99dSDavid van Moolenbroek tptr+=SYSTEM_ID_LEN;
2983*b636d99dSDavid van Moolenbroek tmp-=SYSTEM_ID_LEN;
2984*b636d99dSDavid van Moolenbroek }
2985*b636d99dSDavid van Moolenbroek break;
2986*b636d99dSDavid van Moolenbroek
2987*b636d99dSDavid van Moolenbroek case ISIS_TLV_PREFIX_NEIGH:
2988*b636d99dSDavid van Moolenbroek if (tmp < sizeof(struct isis_metric_block))
2989*b636d99dSDavid van Moolenbroek break;
2990*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, sizeof(struct isis_metric_block)))
2991*b636d99dSDavid van Moolenbroek goto trunctlv;
2992*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Metric Block"));
2993*b636d99dSDavid van Moolenbroek isis_print_metric_block(ndo, (const struct isis_metric_block *)tptr);
2994*b636d99dSDavid van Moolenbroek tptr+=sizeof(struct isis_metric_block);
2995*b636d99dSDavid van Moolenbroek tmp-=sizeof(struct isis_metric_block);
2996*b636d99dSDavid van Moolenbroek
2997*b636d99dSDavid van Moolenbroek while(tmp>0) {
2998*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, 1))
2999*b636d99dSDavid van Moolenbroek goto trunctlv;
3000*b636d99dSDavid van Moolenbroek prefix_len=*tptr++; /* read out prefix length in semioctets*/
3001*b636d99dSDavid van Moolenbroek if (prefix_len < 2) {
3002*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\tAddress: prefix length %u < 2", prefix_len));
3003*b636d99dSDavid van Moolenbroek break;
3004*b636d99dSDavid van Moolenbroek }
3005*b636d99dSDavid van Moolenbroek tmp--;
3006*b636d99dSDavid van Moolenbroek if (tmp < prefix_len/2)
3007*b636d99dSDavid van Moolenbroek break;
3008*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, prefix_len / 2))
3009*b636d99dSDavid van Moolenbroek goto trunctlv;
3010*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\tAddress: %s/%u",
3011*b636d99dSDavid van Moolenbroek isonsap_string(tptr, prefix_len / 2), prefix_len * 4));
3012*b636d99dSDavid van Moolenbroek tptr+=prefix_len/2;
3013*b636d99dSDavid van Moolenbroek tmp-=prefix_len/2;
3014*b636d99dSDavid van Moolenbroek }
3015*b636d99dSDavid van Moolenbroek break;
3016*b636d99dSDavid van Moolenbroek
3017*b636d99dSDavid van Moolenbroek case ISIS_TLV_IIH_SEQNR:
3018*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN)
3019*b636d99dSDavid van Moolenbroek break;
3020*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */
3021*b636d99dSDavid van Moolenbroek goto trunctlv;
3022*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Sequence number: %u", EXTRACT_32BITS(tptr)));
3023*b636d99dSDavid van Moolenbroek break;
3024*b636d99dSDavid van Moolenbroek
3025*b636d99dSDavid van Moolenbroek case ISIS_TLV_VENDOR_PRIVATE:
3026*b636d99dSDavid van Moolenbroek if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN)
3027*b636d99dSDavid van Moolenbroek break;
3028*b636d99dSDavid van Moolenbroek if (!ND_TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */
3029*b636d99dSDavid van Moolenbroek goto trunctlv;
3030*b636d99dSDavid van Moolenbroek vendor_id = EXTRACT_24BITS(tptr);
3031*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Vendor: %s (%u)",
3032*b636d99dSDavid van Moolenbroek tok2str(oui_values, "Unknown", vendor_id),
3033*b636d99dSDavid van Moolenbroek vendor_id));
3034*b636d99dSDavid van Moolenbroek tptr+=3;
3035*b636d99dSDavid van Moolenbroek tmp-=3;
3036*b636d99dSDavid van Moolenbroek if (tmp > 0) /* hexdump the rest */
3037*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, tptr, "\n\t\t", tmp))
3038*b636d99dSDavid van Moolenbroek return(0);
3039*b636d99dSDavid van Moolenbroek break;
3040*b636d99dSDavid van Moolenbroek /*
3041*b636d99dSDavid van Moolenbroek * FIXME those are the defined TLVs that lack a decoder
3042*b636d99dSDavid van Moolenbroek * you are welcome to contribute code ;-)
3043*b636d99dSDavid van Moolenbroek */
3044*b636d99dSDavid van Moolenbroek
3045*b636d99dSDavid van Moolenbroek case ISIS_TLV_DECNET_PHASE4:
3046*b636d99dSDavid van Moolenbroek case ISIS_TLV_LUCENT_PRIVATE:
3047*b636d99dSDavid van Moolenbroek case ISIS_TLV_IPAUTH:
3048*b636d99dSDavid van Moolenbroek case ISIS_TLV_NORTEL_PRIVATE1:
3049*b636d99dSDavid van Moolenbroek case ISIS_TLV_NORTEL_PRIVATE2:
3050*b636d99dSDavid van Moolenbroek
3051*b636d99dSDavid van Moolenbroek default:
3052*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag <= 1) {
3053*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t\t", tlv_len))
3054*b636d99dSDavid van Moolenbroek return(0);
3055*b636d99dSDavid van Moolenbroek }
3056*b636d99dSDavid van Moolenbroek break;
3057*b636d99dSDavid van Moolenbroek }
3058*b636d99dSDavid van Moolenbroek /* do we want to see an additionally hexdump ? */
3059*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag> 1) {
3060*b636d99dSDavid van Moolenbroek if (!print_unknown_data(ndo, pptr, "\n\t ", tlv_len))
3061*b636d99dSDavid van Moolenbroek return(0);
3062*b636d99dSDavid van Moolenbroek }
3063*b636d99dSDavid van Moolenbroek
3064*b636d99dSDavid van Moolenbroek pptr += tlv_len;
3065*b636d99dSDavid van Moolenbroek packet_len -= tlv_len;
3066*b636d99dSDavid van Moolenbroek }
3067*b636d99dSDavid van Moolenbroek
3068*b636d99dSDavid van Moolenbroek if (packet_len != 0) {
3069*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %u straggler bytes", packet_len));
3070*b636d99dSDavid van Moolenbroek }
3071*b636d99dSDavid van Moolenbroek return (1);
3072*b636d99dSDavid van Moolenbroek
3073*b636d99dSDavid van Moolenbroek trunc:
3074*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "[|isis]"));
3075*b636d99dSDavid van Moolenbroek return (1);
3076*b636d99dSDavid van Moolenbroek
3077*b636d99dSDavid van Moolenbroek trunctlv:
3078*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
3079*b636d99dSDavid van Moolenbroek return(1);
3080*b636d99dSDavid van Moolenbroek }
3081*b636d99dSDavid van Moolenbroek
3082*b636d99dSDavid van Moolenbroek static void
osi_print_cksum(netdissect_options * ndo,const uint8_t * pptr,uint16_t checksum,u_int checksum_offset,u_int length)3083*b636d99dSDavid van Moolenbroek osi_print_cksum(netdissect_options *ndo,
3084*b636d99dSDavid van Moolenbroek const uint8_t *pptr, uint16_t checksum,
3085*b636d99dSDavid van Moolenbroek u_int checksum_offset, u_int length)
3086*b636d99dSDavid van Moolenbroek {
3087*b636d99dSDavid van Moolenbroek uint16_t calculated_checksum;
3088*b636d99dSDavid van Moolenbroek
3089*b636d99dSDavid van Moolenbroek /* do not attempt to verify the checksum if it is zero,
3090*b636d99dSDavid van Moolenbroek * if the total length is nonsense,
3091*b636d99dSDavid van Moolenbroek * if the offset is nonsense,
3092*b636d99dSDavid van Moolenbroek * or the base pointer is not sane
3093*b636d99dSDavid van Moolenbroek */
3094*b636d99dSDavid van Moolenbroek if (!checksum
3095*b636d99dSDavid van Moolenbroek || length > ndo->ndo_snaplen
3096*b636d99dSDavid van Moolenbroek || checksum_offset > ndo->ndo_snaplen
3097*b636d99dSDavid van Moolenbroek || checksum_offset > length) {
3098*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "(unverified)"));
3099*b636d99dSDavid van Moolenbroek } else {
3100*b636d99dSDavid van Moolenbroek const char *truncated = "trunc";
3101*b636d99dSDavid van Moolenbroek //printf("\nosi_print_cksum: %p %u %u %u\n", pptr, checksum_offset, length, ndo->ndo_snaplen);
3102*b636d99dSDavid van Moolenbroek //ND_TCHECK2(pptr, checksum_offset+length);
3103*b636d99dSDavid van Moolenbroek calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
3104*b636d99dSDavid van Moolenbroek if (checksum == calculated_checksum) {
3105*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " (correct)"));
3106*b636d99dSDavid van Moolenbroek } else {
3107*b636d99dSDavid van Moolenbroek truncated = "incorrect";
3108*b636d99dSDavid van Moolenbroek //trunc:
3109*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, " (%s should be 0x%04x)", truncated, calculated_checksum));
3110*b636d99dSDavid van Moolenbroek }
3111*b636d99dSDavid van Moolenbroek }
3112*b636d99dSDavid van Moolenbroek }
3113*b636d99dSDavid van Moolenbroek
3114*b636d99dSDavid van Moolenbroek /*
3115*b636d99dSDavid van Moolenbroek * Local Variables:
3116*b636d99dSDavid van Moolenbroek * c-style: whitesmith
3117*b636d99dSDavid van Moolenbroek * c-basic-offset: 8
3118*b636d99dSDavid van Moolenbroek * End:
3119*b636d99dSDavid van Moolenbroek */
3120