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