]> The Tcpdump Group git mirrors - tcpdump/blob - print-isoclns.c
We no longer use "packetp" for anything, so eliminate it. (If any
[tcpdump] / print-isoclns.c
1 /*
2 * Copyright (c) 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * Original code by Matt Thomas, Digital Equipment Corporation
22 *
23 * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
24 * complete IS-IS support.
25 */
26
27 #ifndef lint
28 static const char rcsid[] =
29 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.73 2002-12-11 07:14:04 guy Exp $ (LBL)";
30 #endif
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <tcpdump-stdinc.h>
37
38 #include <stdio.h>
39 #include <string.h>
40
41 #include "interface.h"
42 #include "addrtoname.h"
43 #include "ethertype.h"
44 #include "ether.h"
45 #include "extract.h"
46
47 #define NLPID_CLNS 129 /* 0x81 */
48 #define NLPID_ESIS 130 /* 0x82 */
49 #define NLPID_ISIS 131 /* 0x83 */
50 #define NLPID_IP6 0x8e
51 #define NLPID_IP 0xcc
52 #define NLPID_NULLNS 0
53
54 #define IPV4 1 /* AFI value */
55 #define IPV6 2 /* AFI value */
56
57 /*
58 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
59 */
60
61 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
62 #define NODE_ID_LEN SYSTEM_ID_LEN+1
63 #define LSP_ID_LEN SYSTEM_ID_LEN+2
64
65 #define ISIS_VERSION 1
66 #define PDU_TYPE_MASK 0x1F
67 #define PRIORITY_MASK 0x7F
68
69 #define L1_LAN_IIH 15
70 #define L2_LAN_IIH 16
71 #define PTP_IIH 17
72 #define L1_LSP 18
73 #define L2_LSP 20
74 #define L1_CSNP 24
75 #define L2_CSNP 25
76 #define L1_PSNP 26
77 #define L2_PSNP 27
78
79 static struct tok isis_pdu_values[] = {
80 { L1_LAN_IIH, "L1 Lan IIH"},
81 { L2_LAN_IIH, "L2 Lan IIH"},
82 { PTP_IIH, "p2p IIH"},
83 { L1_LSP, "L1 LSP"},
84 { L2_LSP, "L2 LSP"},
85 { L1_CSNP, "L1 CSNP"},
86 { L2_CSNP, "L2 CSNP"},
87 { L1_PSNP, "L1 PSNP"},
88 { L2_PSNP, "L2 PSNP"},
89 { 0, NULL}
90 };
91
92 /*
93 * A TLV is a tuple of a type, length and a value and is normally used for
94 * encoding information in all sorts of places. This is an enumeration of
95 * the well known types.
96 *
97 * list taken from rfc3359 plus some memory from veterans ;-)
98 */
99
100 #define TLV_AREA_ADDR 1 /* iso10589 */
101 #define TLV_IS_REACH 2 /* iso10589 */
102 #define TLV_ESNEIGH 3 /* iso10589 */
103 #define TLV_PART_DIS 4 /* iso10589 */
104 #define TLV_PREFIX_NEIGH 5 /* iso10589 */
105 #define TLV_ISNEIGH 6 /* iso10589 */
106 #define TLV_ISNEIGH_VARLEN 7 /* iso10589 */
107 #define TLV_PADDING 8 /* iso10589 */
108 #define TLV_LSP 9 /* iso10589 */
109 #define TLV_AUTH 10 /* iso10589, draft-ietf-isis-hmac-03 */
110 #define TLV_CHECKSUM 12 /* rfc3358 */
111 #define TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */
112 #define TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-04 */
113 #define TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */
114 #define TLV_DECNET_PHASE4 42
115 #define TLV_LUCENT_PRIVATE 66
116 #define TLV_IP_REACH 128 /* rfc1195, rfc2966 */
117 #define TLV_PROTOCOLS 129 /* rfc1195 */
118 #define TLV_IP_REACH_EXT 130 /* rfc1195, rfc2966 */
119 #define TLV_IDRP_INFO 131 /* rfc1195 */
120 #define TLV_IPADDR 132 /* rfc1195 */
121 #define TLV_IPAUTH 133 /* rfc1195 */
122 #define TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-04 */
123 #define TLV_EXT_IP_REACH 135 /* draft-ietf-isis-traffic-04 */
124 #define TLV_HOSTNAME 137 /* rfc2763 */
125 #define TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions-14 */
126 #define TLV_NORTEL_PRIVATE1 176
127 #define TLV_NORTEL_PRIVATE2 177
128 #define TLV_HOLDTIME 198 /* ES-IS */
129 #define TLV_RESTART_SIGNALING 211 /* draft-ietf-isis-restart-01 */
130 #define TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
131 #define TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
132 #define TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */
133 #define TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */
134 #define TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */
135 #define TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
136 #define TLV_PTP_ADJ 240 /* rfc3373 */
137 #define TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
138 #define TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */
139
140 static struct tok isis_tlv_values[] = {
141 { TLV_AREA_ADDR, "Area address(es)"},
142 { TLV_IS_REACH, "IS Reachability"},
143 { TLV_ESNEIGH, "ES Neighbor(s)"},
144 { TLV_PART_DIS, "Partition DIS"},
145 { TLV_PREFIX_NEIGH, "Prefix Neighbors"},
146 { TLV_ISNEIGH, "IS Neighbor(s)"},
147 { TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"},
148 { TLV_PADDING, "Padding"},
149 { TLV_LSP, "LSP entries"},
150 { TLV_AUTH, "Authentication"},
151 { TLV_CHECKSUM, "Checksum"},
152 { TLV_LSP_BUFFERSIZE, "LSP Buffersize"},
153 { TLV_EXT_IS_REACH, "Extended IS Reachability"},
154 { TLV_IS_ALIAS_ID, "IS Alias ID"},
155 { TLV_DECNET_PHASE4, "DECnet Phase IV"},
156 { TLV_LUCENT_PRIVATE, "Lucent Proprietary"},
157 { TLV_IP_REACH, "IPv4 Internal reachability"},
158 { TLV_PROTOCOLS, "Protocols supported"},
159 { TLV_IP_REACH_EXT, "IPv4 External reachability"},
160 { TLV_IDRP_INFO, "Inter-Domain Information Type"},
161 { TLV_IPADDR, "IPv4 Interface address(es)"},
162 { TLV_IPAUTH, "IPv4 authentication (deprecated)"},
163 { TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"},
164 { TLV_EXT_IP_REACH, "Extended IPv4 reachability"},
165 { TLV_HOSTNAME, "Hostname"},
166 { TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"},
167 { TLV_NORTEL_PRIVATE1, "Nortel Proprietary"},
168 { TLV_NORTEL_PRIVATE2, "Nortel Proprietary"},
169 { TLV_HOLDTIME, "Holdtime"},
170 { TLV_RESTART_SIGNALING, "Restart Signaling"},
171 { TLV_MT_IS_REACH, "Multi Topology IS Reachability"},
172 { TLV_MT_SUPPORTED, "Multi Topology"},
173 { TLV_IP6ADDR, "IPv6 Interface address(es)"},
174 { TLV_MT_IP_REACH, "Multi-Topology IPv4 reachability"},
175 { TLV_IP6_REACH, "IPv6 reachability"},
176 { TLV_MT_IP6_REACH, "Multi-Topology IP6 reachability"},
177 { TLV_PTP_ADJ, "Point-to-point Adjacency State"},
178 { TLV_IIH_SEQNR, "Hello PDU Sequence Number"},
179 { TLV_VENDOR_PRIVATE, "Vendor Private"},
180 { 0, NULL }
181 };
182
183 #define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3
184 #define SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID 4
185 #define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5
186 #define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6
187 #define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8
188 #define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9
189 #define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10
190 #define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11
191 #define SUBTLV_EXT_IS_REACH_TE_METRIC 18
192 #define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20
193 #define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21
194
195 #define SUBTLV_IP_REACH_ADMIN_TAG32 1
196 #define SUBTLV_IP_REACH_ADMIN_TAG64 2
197
198 #define SUBTLV_AUTH_SIMPLE 1
199 #define SUBTLV_AUTH_MD5 54
200 #define SUBTLV_AUTH_MD5_LEN 16
201 #define SUBTLV_AUTH_PRIVATE 255
202
203 static struct tok isis_subtlv_auth_values[] = {
204 { SUBTLV_AUTH_SIMPLE, "simple text password"},
205 { SUBTLV_AUTH_MD5, "HMAC-MD5 password"},
206 { SUBTLV_AUTH_PRIVATE, "Routing Domain private password"},
207 { 0, NULL }
208 };
209
210 #define SUBTLV_IDRP_RES 0
211 #define SUBTLV_IDRP_LOCAL 1
212 #define SUBTLV_IDRP_ASN 2
213
214 static struct tok isis_subtlv_idrp_values[] = {
215 { SUBTLV_IDRP_RES, "Reserved"},
216 { SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"},
217 { SUBTLV_IDRP_ASN, "AS Number Tag"},
218 { 0, NULL}
219 };
220
221 #define ISIS_8BIT_MASK(x) ((x)&0xff)
222
223 #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
224 #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
225 #define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
226 #define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
227 #define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
228 #define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
229 #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
230 #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
231
232 #define ISIS_MASK_MTID(x) ((x)&0xfff)
233 #define ISIS_MASK_MTSUB(x) ((x)&0x8000)
234 #define ISIS_MASK_MTATT(x) ((x)&0x4000)
235
236 #define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80)
237 #define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40)
238
239 #define ISIS_MASK_TLV_EXT_IP6_IE(x) ((x)&0x40)
240 #define ISIS_MASK_TLV_EXT_IP6_SUBTLV(x) ((x)&0x20)
241
242 #define ISIS_MASK_TLV_RESTART_RR(x) ((x)&0x1)
243 #define ISIS_MASK_TLV_RESTART_RA(x) ((x)&0x2)
244
245 #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
246 #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
247 #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
248 #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
249
250 #define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
251
252 static struct tok isis_gmpls_link_prot_values[] = {
253 { 0x01, "Extra Traffic"},
254 { 0x02, "Unprotected"},
255 { 0x04, "Shared"},
256 { 0x08, "Dedicated 1:1"},
257 { 0x10, "Dedicated 1+1"},
258 { 0x20, "Enhanced"},
259 { 0x40, "Reserved"},
260 { 0x80, "Reserved"},
261 { 0, NULL }
262 };
263
264 static struct tok isis_gmpls_sw_cap_values[] = {
265 { 1, "Packet-Switch Capable-1"},
266 { 2, "Packet-Switch Capable-2"},
267 { 3, "Packet-Switch Capable-3"},
268 { 4, "Packet-Switch Capable-4"},
269 { 51, "Layer-2 Switch Capable"},
270 { 100, "Time-Division-Multiplex"},
271 { 150, "Lambda-Switch Capable"},
272 { 200, "Fiber-Switch Capable"},
273 { 0, NULL }
274 };
275
276 static struct tok isis_gmpls_lsp_enc_values[] = {
277 { 1, "Packet"},
278 { 2, "Ethernet V2/DIX"},
279 { 3, "ANSI PDH"},
280 { 4, "ETSI PDH"},
281 { 5, "SDH ITU-T G.707"},
282 { 6, "SONET ANSI T1.105"},
283 { 7, "Digital Wrapper"},
284 { 8, "Lambda (photonic)"},
285 { 9, "Fiber"},
286 { 10, "Ethernet 802.3"},
287 { 11, "FiberChannel"},
288 { 0, NULL }
289 };
290
291 static struct tok isis_mt_values[] = {
292 { 0, "IPv4 unicast"},
293 { 1, "In-Band Management"},
294 { 2, "IPv6 unicast"},
295 { 3, "Multicast"},
296 { 4095, "Development, Experimental or Proprietary"},
297 { 0, NULL }
298 };
299
300 static struct tok isis_iih_circuit_type_values[] = {
301 { 1, "Level 1 only"},
302 { 2, "Level 2 only"},
303 { 3, "Level 1, Level 2"},
304 { 0, NULL}
305 };
306
307 #define ISIS_LSP_TYPE_UNUSED0 0
308 #define ISIS_LSP_TYPE_LEVEL_1 1
309 #define ISIS_LSP_TYPE_UNUSED2 2
310 #define ISIS_LSP_TYPE_LEVEL_2 3
311
312 static struct tok isis_lsp_istype_values[] = {
313 { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
314 { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
315 { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
316 { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"},
317 { 0, NULL }
318 };
319
320 static struct tok osi_nlpid_values[] = {
321 { NLPID_CLNS, "CLNS"},
322 { NLPID_IP, "IPv4"},
323 { NLPID_IP6, "IPv6"},
324 { 0, NULL }
325 };
326
327 /*
328 * Katz's point to point adjacency TLV uses codes to tell us the state of
329 * the remote adjacency. Enumerate them.
330 */
331
332 #define ISIS_PTP_ADJ_UP 0
333 #define ISIS_PTP_ADJ_INIT 1
334 #define ISIS_PTP_ADJ_DOWN 2
335
336
337 static struct tok isis_ptp_adjancey_values[] = {
338 { ISIS_PTP_ADJ_UP, "Up" },
339 { ISIS_PTP_ADJ_INIT, "Initializing" },
340 { ISIS_PTP_ADJ_DOWN, "Down" },
341 { 0, NULL}
342 };
343
344 struct isis_tlv_ptp_adj {
345 u_int8_t adjacency_state;
346 u_int8_t extd_local_circuit_id[4];
347 u_int8_t neighbor_sysid[SYSTEM_ID_LEN];
348 u_int8_t neighbor_extd_local_circuit_id[4];
349 };
350
351 static int osi_cksum(const u_int8_t *, u_int);
352 static void esis_print(const u_int8_t *, u_int);
353 static int isis_print(const u_int8_t *, u_int);
354
355 struct isis_metric_block {
356 u_int8_t metric_default;
357 u_int8_t metric_delay;
358 u_int8_t metric_expense;
359 u_int8_t metric_error;
360 };
361
362 struct isis_tlv_is_reach {
363 struct isis_metric_block isis_metric_block;
364 u_int8_t neighbor_nodeid[NODE_ID_LEN];
365 };
366
367 struct isis_tlv_es_reach {
368 struct isis_metric_block isis_metric_block;
369 u_int8_t neighbor_sysid[SYSTEM_ID_LEN];
370 };
371
372 struct isis_tlv_ip_reach {
373 struct isis_metric_block isis_metric_block;
374 u_int8_t prefix[4];
375 u_int8_t mask[4];
376 };
377
378 static struct tok isis_is_reach_virtual_values[] = {
379 { 0, "IsNotVirtual"},
380 { 1, "IsVirtual"},
381 { 0, NULL }
382 };
383
384 struct isis_common_header {
385 u_int8_t nlpid;
386 u_int8_t fixed_len;
387 u_int8_t version; /* Protocol version? */
388 u_int8_t id_length;
389 u_int8_t pdu_type; /* 3 MSbs are reserved */
390 u_int8_t pdu_version; /* Packet format version? */
391 u_int8_t reserved;
392 u_int8_t max_area;
393 };
394
395 struct isis_iih_lan_header {
396 u_int8_t circuit_type;
397 u_int8_t source_id[SYSTEM_ID_LEN];
398 u_int8_t holding_time[2];
399 u_int8_t pdu_len[2];
400 u_int8_t priority;
401 u_int8_t lan_id[NODE_ID_LEN];
402 };
403
404 struct isis_iih_ptp_header {
405 u_int8_t circuit_type;
406 u_int8_t source_id[SYSTEM_ID_LEN];
407 u_int8_t holding_time[2];
408 u_int8_t pdu_len[2];
409 u_int8_t circuit_id;
410 };
411
412 struct isis_lsp_header {
413 u_int8_t pdu_len[2];
414 u_int8_t remaining_lifetime[2];
415 u_int8_t lsp_id[LSP_ID_LEN];
416 u_int8_t sequence_number[4];
417 u_int8_t checksum[2];
418 u_int8_t typeblock;
419 };
420
421 struct isis_csnp_header {
422 u_int8_t pdu_len[2];
423 u_int8_t source_id[NODE_ID_LEN];
424 u_int8_t start_lsp_id[LSP_ID_LEN];
425 u_int8_t end_lsp_id[LSP_ID_LEN];
426 };
427
428 struct isis_psnp_header {
429 u_int8_t pdu_len[2];
430 u_int8_t source_id[NODE_ID_LEN];
431 };
432
433 struct isis_tlv_lsp {
434 u_int8_t remaining_lifetime[2];
435 u_int8_t lsp_id[LSP_ID_LEN];
436 u_int8_t sequence_number[4];
437 u_int8_t checksum[2];
438 };
439
440
441 /* allocate space for the following string
442 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx
443 * 32 bytes plus one termination byte */
444 static char *
445 print_nsap(register const u_int8_t *pptr, register int nsap_length)
446 {
447 int nsap_idx;
448 static char nsap_ascii_output[33];
449 char *junk_buf = nsap_ascii_output;
450
451 if (nsap_length < 1 || nsap_length > 13) {
452 junk_buf+=sprintf(junk_buf, "illegal length");
453 *(junk_buf) = '\0';
454 return (nsap_ascii_output);
455 }
456
457 for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) {
458 if (!TTEST2(*pptr, 1))
459 return (0);
460 junk_buf+=sprintf(junk_buf, "%02x", *pptr++);
461 if (((nsap_idx & 1) == 0) &&
462 (nsap_idx + 1 < nsap_length)) {
463 junk_buf+=sprintf(junk_buf, ".");
464 }
465 }
466 *(junk_buf) = '\0';
467 return (nsap_ascii_output);
468 }
469
470 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
471 #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
472 #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
473 #define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
474 #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
475 #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
476
477 void isoclns_print(const u_int8_t *p, u_int length, u_int caplen,
478 const u_int8_t *esrc, const u_int8_t *edst)
479 {
480 u_int8_t pdu_type;
481 const struct isis_common_header *header;
482
483 header = (const struct isis_common_header *)p;
484 pdu_type = header->pdu_type & PDU_TYPE_MASK;
485
486 printf("%sOSI ", caplen < 1 ? "|" : "");
487 if (!eflag && esrc != NULL && edst != NULL)
488 (void)printf("%s > %s, ",
489 etheraddr_string(esrc),
490 etheraddr_string(edst));
491
492 if (caplen < 1) /* enough bytes on the wire ? */
493 return;
494
495 switch (*p) {
496
497 case NLPID_CLNS:
498 (void)printf("CLNS, length: %u", length);
499 break;
500
501 case NLPID_ESIS:
502 esis_print(p, length);
503 return;
504
505 case NLPID_ISIS:
506 if (!isis_print(p, length))
507 print_unknown_data(p,"\n\t",caplen);
508 break;
509
510 case NLPID_NULLNS:
511 (void)printf("ISO NULLNS, length: %u", length);
512 break;
513
514 default:
515 (void)printf("Unknown NLPID 0x%02x, length: %u", p[0], length);
516 if (caplen > 1)
517 print_unknown_data(p,"\n\t",caplen);
518 break;
519 }
520 }
521
522 #define ESIS_REDIRECT 6
523 #define ESIS_ESH 2
524 #define ESIS_ISH 4
525
526 static struct tok esis_values[] = {
527 { ESIS_REDIRECT, "redirect"},
528 { ESIS_ESH, "ESH"},
529 { ESIS_ISH, "ISH"},
530 { 0, NULL }
531 };
532
533 struct esis_hdr {
534 u_int8_t version;
535 u_int8_t reserved;
536 u_int8_t type;
537 u_int8_t tmo[2];
538 u_int8_t cksum[2];
539 };
540
541 static void
542 esis_print(const u_int8_t *p, u_int length)
543 {
544 const u_int8_t *ep;
545 u_int li;
546 const struct esis_hdr *eh;
547
548 if (length <= 2) {
549 if (qflag)
550 printf(" bad pkt!");
551 else
552 printf(" no header at all!");
553 return;
554 }
555 li = p[1];
556 eh = (const struct esis_hdr *) &p[2];
557 ep = p + li;
558 if (li > length) {
559 if (qflag)
560 printf(" bad pkt!");
561 else
562 printf(" LI(%d) > PDU size (%d)!", li, length);
563 return;
564 }
565 if (li < sizeof(struct esis_hdr) + 2) {
566 if (qflag)
567 printf(" bad pkt!");
568 else {
569 printf(" too short for esis header %d:", li);
570 while (--length != 0)
571 printf("%02X", *p++);
572 }
573 return;
574 }
575
576 printf("ES-IS, %s, length: %u",
577 tok2str(esis_values,"unknown type: %u",eh->type & 0x1f),
578 length);
579
580 if(vflag < 1)
581 return;
582
583 if (vflag && osi_cksum(p, li)) {
584 printf(" bad cksum (got 0x%02x%02x)",
585 eh->cksum[1], eh->cksum[0]);
586 default_print(p, length);
587 return;
588 }
589 if (eh->version != 1) {
590 printf(" unsupported version %d", eh->version);
591 return;
592 }
593 p += sizeof(*eh) + 2;
594 li -= sizeof(*eh) + 2; /* protoid * li */
595
596 switch (eh->type & 0x1f) {
597 case ESIS_REDIRECT: {
598 const u_int8_t *dst, *snpa, *is;
599
600 dst = p; p += *p + 1;
601 if (p > snapend)
602 return;
603 printf("\n\t\t %s", isonsap_string(dst));
604 snpa = p; p += *p + 1;
605 is = p; p += *p + 1;
606 if (p > snapend)
607 return;
608 if (p > ep) {
609 printf(" [bad li]");
610 return;
611 }
612 if (is[0] == 0)
613 printf(" > %s", etheraddr_string(&snpa[1]));
614 else
615 printf(" > %s", isonsap_string(is));
616 li = ep - p;
617 break;
618 }
619
620 case ESIS_ESH:
621 break;
622
623 case ESIS_ISH: {
624 const u_int8_t *is;
625
626 is = p; p += *p + 1;
627 if (p > ep) {
628 printf(" [bad li]");
629 return;
630 }
631 if (p > snapend)
632 return;
633 if (!qflag)
634 printf("\n\tNET: %s", print_nsap(is+1,*is));
635 li = ep - p;
636 break;
637 }
638
639 default:
640 if (vflag <= 1) {
641 if (p < snapend)
642 print_unknown_data(p,"\n\t ",snapend-p);
643 }
644 return;
645 }
646
647 /* hexdump - FIXME ? */
648 if (vflag > 1) {
649 if (p < snapend)
650 print_unknown_data(p,"\n\t ",snapend-p);
651 }
652 if (vflag)
653 while (p < ep && li) {
654 u_int op, opli;
655 const u_int8_t *q;
656
657 if (snapend - p < 2)
658 return;
659 if (li < 2) {
660 printf(", bad opts/li");
661 return;
662 }
663 op = *p++;
664 opli = *p++;
665 li -= 2;
666 if (opli > li) {
667 printf(", opt (%d) too long", op);
668 return;
669 }
670 li -= opli;
671 q = p;
672 p += opli;
673
674 if (snapend < p)
675 return;
676
677 if (op == TLV_HOLDTIME && opli == 2) {
678 printf("\n\tholdtime: %us", EXTRACT_16BITS(q));
679 continue;
680 }
681
682 if (op == TLV_PROTOCOLS && opli >= 1) {
683 printf("\n\t%s (length: %u): %s",
684 tok2str(isis_tlv_values, "unknown", op),
685 opli,
686 tok2str(osi_nlpid_values,"Unknown 0x%02x",*q));
687 continue;
688 }
689
690 print_unknown_data(q,"\n\t ",opli);
691 }
692 }
693
694 /* allocate space for the following string
695 * xxxx.xxxx.xxxx
696 * 14 bytes plus one termination byte */
697 static char *
698 isis_print_sysid(const u_int8_t *cp, int sysid_len)
699 {
700 int i;
701 static char sysid[15];
702 char *pos = sysid;
703
704 for (i = 1; i <= sysid_len; i++) {
705 if (!TTEST2(*cp, 1))
706 return (0);
707 pos+=sprintf(pos, "%02x", *cp++);
708 if ((i==2)^(i==4)) {
709 pos+=sprintf(pos, ".");
710 }
711 }
712 *(pos) = '\0';
713 return (sysid);
714 }
715
716
717 /* allocate space for the following string
718 * xxxx.xxxx.xxxx.yy
719 * 17 bytes plus one termination byte */
720 static char *
721 isis_print_nodeid(const u_int8_t *cp)
722 {
723 int i;
724 static char nodeid[18];
725 char *pos = nodeid;
726
727 for (i = 1; i <= 7; i++) {
728 if (!TTEST2(*cp, 1))
729 return (0);
730 pos+=sprintf(pos, "%02x", *cp++);
731 if ((i & 1) == 0) {
732 pos+=sprintf(pos, ".");
733 }
734 }
735 *(pos) = '\0';
736 return (nodeid);
737 }
738
739 /* allocate space for the following string
740 * xxxx.xxxx.xxxx.yy-zz
741 * 20 bytes plus one termination byte */
742 static char *
743 isis_print_lspid(const u_int8_t *cp)
744 {
745 int i;
746 static char lspid[21];
747 char *pos = lspid;
748
749 for (i = 1; i <= 7; i++) {
750 pos+=sprintf(pos, "%02x", *cp++);
751 if ((i & 1) == 0)
752 pos+=sprintf(pos, ".");
753 }
754 pos+=sprintf(pos, "-%02x", *cp);
755 return (lspid);
756 }
757
758 /* print the 4-byte metric block which is common found in the old-style TLVs */
759
760 static int
761 isis_print_metric_block (const struct isis_metric_block *isis_metric_block)
762 {
763 printf(", Default Metric: %d, %s",
764 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default),
765 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal");
766 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay))
767 printf("\n\t\t Delay Metric: %d, %s",
768 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay),
769 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal");
770 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense))
771 printf("\n\t\t Expense Metric: %d, %s",
772 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense),
773 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal");
774 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error))
775 printf("\n\t\t Error Metric: %d, %s",
776 ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error),
777 ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal");
778
779 return(1); /* everything is ok */
780 }
781
782 static int
783 isis_print_tlv_ip_reach (const u_int8_t *cp, int length)
784 {
785 u_int bitmasks[33] = {
786 0x00000000,
787 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
788 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
789 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
790 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
791 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
792 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
793 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
794 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
795 };
796 u_int mask;
797 int prefix_len;
798 const struct isis_tlv_ip_reach *tlv_ip_reach;
799
800 tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
801
802 while (length > 0) {
803 if ((size_t)length < sizeof(*tlv_ip_reach)) {
804 printf("short IPv4 reachability (%d vs %lu)", length,
805 (unsigned long)sizeof(*tlv_ip_reach));
806 return (0);
807 }
808
809 if (!TTEST(*tlv_ip_reach))
810 return (0);
811
812 mask = EXTRACT_32BITS(tlv_ip_reach->mask);
813 prefix_len = 0;
814
815 /* lets see if we can transform the mask into a prefixlen */
816 while (prefix_len <= 33) {
817 if (bitmasks[prefix_len++] == mask) {
818 prefix_len--;
819 break;
820 }
821 }
822
823 /*
824 * 34 indicates no match -> must be a discontiguous netmask
825 * lets dump the mask, otherwise print the prefix_len
826 */
827 if (prefix_len == 34)
828 printf("\n\t\tIPv4 prefix: %s mask %s",
829 ipaddr_string((tlv_ip_reach->prefix)),
830 ipaddr_string((tlv_ip_reach->mask)));
831 else
832 printf("\n\t\tIPv4 prefix: %s/%u",
833 ipaddr_string((tlv_ip_reach->prefix)),
834 prefix_len);
835
836 printf("\n\t\t Default Metric: %02d, %s, Distribution: %s",
837 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default),
838 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal",
839 ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up");
840
841 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay))
842 printf("\n\t\t Delay Metric: %02d, %s",
843 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay),
844 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal");
845
846 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense))
847 printf("\n\t\t Expense Metric: %02d, %s",
848 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense),
849 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal");
850
851 if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error))
852 printf("\n\t\t Error Metric: %02d, %s",
853 ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error),
854 ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal");
855
856 length -= sizeof(struct isis_tlv_ip_reach);
857 tlv_ip_reach++;
858 }
859 return (1);
860 }
861
862 /*
863 * this is the common IP-REACH subTLV decoder it is called
864 * from various EXTD-IP REACH TLVs (135,235,236,237)
865 */
866
867 static int
868 isis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) {
869
870 switch(subt) {
871 case SUBTLV_IP_REACH_ADMIN_TAG32:
872 if (!TTEST2(*tptr,4))
873 goto trunctlv;
874 printf("%s32-Bit Administrative tag: 0x%08x",
875 ident,
876 EXTRACT_32BITS(tptr));
877 break;
878 case SUBTLV_IP_REACH_ADMIN_TAG64:
879 if (!TTEST2(*tptr,8))
880 goto trunctlv;
881 printf("%s64-Bit Administrative tag: 0x%08x%08x",
882 ident,
883 EXTRACT_32BITS(tptr),
884 EXTRACT_32BITS(tptr+4));
885 break;
886 default:
887 printf("%sunknown subTLV, type %d, length %d",
888 ident,
889 subt,
890 subl);
891 if(!print_unknown_data(tptr,"\n\t\t ",
892 subl))
893 return(0);
894 break;
895 }
896 return(1);
897
898 trunctlv:
899 printf("%spacket exceeded snapshot",ident);
900 return(0);
901 }
902
903 /*
904 * this is the common IS-REACH subTLV decoder it is called
905 * from isis_print_ext_is_reach()
906 */
907
908 static int
909 isis_print_is_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) {
910
911 int i;
912 union { /* int to float conversion buffer for several subTLVs */
913 float f;
914 u_int32_t i;
915 } bw;
916
917 switch(subt) {
918 case SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
919 if (!TTEST2(*tptr,4))
920 goto trunctlv;
921 printf("%sAdministrative groups: 0x%08x",
922 ident,
923 EXTRACT_32BITS(tptr));
924 break;
925 case SUBTLV_EXT_IS_REACH_LINK_LOCAL_ID:
926 if (!TTEST2(*tptr,4))
927 goto trunctlv;
928 printf("%sLink Local Identifier: 0x%08x",
929 ident,
930 EXTRACT_32BITS(tptr));
931 break;
932 case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
933 if (!TTEST2(*tptr,4))
934 goto trunctlv;
935 printf("%sLink Remote Identifier: 0x%08x",
936 ident,
937 EXTRACT_32BITS(tptr));
938 break;
939 case SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
940 if (!TTEST2(*tptr,4))
941 goto trunctlv;
942 bw.i = EXTRACT_32BITS(tptr);
943 printf("%sMaximum link bandwidth : %.3f Mbps",
944 ident,
945 bw.f*8/1000000 );
946 break;
947 case SUBTLV_EXT_IS_REACH_RESERVABLE_BW :
948 if (!TTEST2(*tptr,4))
949 goto trunctlv;
950 bw.i = EXTRACT_32BITS(tptr);
951 printf("%sReservable link bandwidth: %.3f Mbps",
952 ident,
953 bw.f*8/1000000 );
954 break;
955 case SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
956 printf("%sUnreserved bandwidth:",ident);
957 for (i = 0; i < 8; i++) {
958 if (!TTEST2(*(tptr+i*4),4))
959 goto trunctlv;
960 bw.i = EXTRACT_32BITS(tptr);
961 printf("%s priority level %d: %.3f Mbps",
962 ident,
963 i,
964 bw.f*8/1000000 );
965 }
966 break;
967 case SUBTLV_EXT_IS_REACH_TE_METRIC:
968 if (!TTEST2(*tptr,3))
969 goto trunctlv;
970 printf("%sTraffic Engineering Metric: %d",
971 ident,
972 EXTRACT_24BITS(tptr));
973 break;
974 case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
975 if (!TTEST2(*tptr,4))
976 goto trunctlv;
977 printf("%sIPv4 interface address: %s",
978 ident,
979 ipaddr_string(tptr));
980 break;
981 case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
982 if (!TTEST2(*tptr,4))
983 goto trunctlv;
984 printf("%sIPv4 neighbor address: %s",
985 ident,
986 ipaddr_string(tptr));
987 break;
988 case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
989 if (!TTEST2(*tptr,2))
990 goto trunctlv;
991 printf("%sLink Protection Type: %s, Priority %u",
992 ident,
993 bittok2str(isis_gmpls_link_prot_values, "none", *tptr),
994 *(tptr+1));
995 break;
996 case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
997 printf("%sInterface Switching Capability",ident);
998
999 if (!TTEST2(*tptr,1))
1000 goto trunctlv;
1001 printf("%s Interface Switching Capability:%s",
1002 ident,
1003 tok2str(isis_gmpls_sw_cap_values, "Unknown", *(tptr)));
1004
1005 if (!TTEST2(*(tptr+1),1))
1006 goto trunctlv;
1007 printf(", LSP Encoding: %s",
1008 tok2str(isis_gmpls_lsp_enc_values, "Unknown", *(tptr+1)));
1009
1010 if (!TTEST2(*(tptr+2),2)) /* skip 2 res. bytes */
1011 goto trunctlv;
1012
1013 printf("%s Max LSP Bandwidth:",ident);
1014 for (i = 0; i < 8; i++) {
1015 if (!TTEST2(*(tptr+(i*4)+4),4))
1016 goto trunctlv;
1017 bw.i = EXTRACT_32BITS(tptr);
1018 printf("%s priority level %d: %.3f Mbps",
1019 ident,
1020 i,
1021 bw.f*8/1000000 );
1022 }
1023 subl-=36;
1024 /* there is some optional stuff left to decode but this is as of yet
1025 not specified so just lets hexdump what is left */
1026 if(subl>0){
1027 if(!print_unknown_data(tptr,"\n\t\t ",
1028 subl-36))
1029 return(0);
1030 }
1031 break;
1032 case 250:
1033 case 251:
1034 case 252:
1035 case 253:
1036 case 254:
1037 printf("%sReserved for cisco specific extensions, type %d, length %d",
1038 ident,
1039 subt,
1040 subl);
1041 break;
1042 case 255:
1043 printf("%sReserved for future expansion, type %d, length %d",
1044 ident,
1045 subt,
1046 subl);
1047 break;
1048 default:
1049 printf("%sunknown subTLV, type %d, length %d",
1050 ident,
1051 subt,
1052 subl);
1053 if(!print_unknown_data(tptr,"\n\t\t ",
1054 subl))
1055 return(0);
1056 break;
1057 }
1058 return(1);
1059
1060 trunctlv:
1061 printf("%spacket exceeded snapshot",ident);
1062 return(0);
1063 }
1064
1065
1066 /*
1067 * this is the common IS-REACH decoder it is called
1068 * from various EXTD-IS REACH style TLVs (22,24,222)
1069 */
1070
1071 static int
1072 isis_print_ext_is_reach (const u_int8_t *tptr,const char *ident) {
1073
1074 char ident_buffer[20];
1075 int subt,subl,tslen;
1076 int proc_bytes = 0; /* how many bytes did we process ? */
1077
1078 if (!TTEST2(*tptr, NODE_ID_LEN))
1079 return(0);
1080
1081 printf("%sIS Neighbor: %s", ident, isis_print_nodeid(tptr));
1082 tptr+=(NODE_ID_LEN);
1083
1084 if (!TTEST2(*tptr, 3))
1085 return(0);
1086 printf(", Metric: %d",EXTRACT_24BITS(tptr));
1087 tptr+=3;
1088
1089 if (!TTEST2(*tptr, 1))
1090 return(0);
1091 tslen=*(tptr++); /* read out subTLV length */
1092 proc_bytes=NODE_ID_LEN+3+1;
1093 printf(", %ssub-TLVs present",tslen ? "" : "no ");
1094 if (tslen) {
1095 printf(" (%u)",tslen);
1096 while (tslen>0) {
1097 if (!TTEST2(*tptr,2))
1098 return(0);
1099 subt=*(tptr++);
1100 subl=*(tptr++);
1101 /* prepend the ident string */
1102 snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
1103 if(!isis_print_is_reach_subtlv(tptr,subt,subl,ident_buffer))
1104 return(0);
1105 tptr+=subl;
1106 tslen-=(subl+2);
1107 proc_bytes+=(subl+2);
1108 }
1109 }
1110 return(proc_bytes);
1111 }
1112
1113 /*
1114 * this is the common Multi Topology ID decoder
1115 * it is called from various MT-TLVs (222,229,235,237)
1116 */
1117
1118 static int
1119 isis_print_mtid (const u_int8_t *tptr,const char *ident) {
1120
1121 if (!TTEST2(*tptr, 2))
1122 return(0);
1123
1124 printf("%s%s",
1125 ident,
1126 tok2str(isis_mt_values,
1127 "Reserved for IETF Consensus",
1128 ISIS_MASK_MTID(EXTRACT_16BITS(tptr))));
1129
1130 printf(" Topology (0x%03x)%s%s",
1131 ISIS_MASK_MTID(EXTRACT_16BITS(tptr)),
1132 ISIS_MASK_MTSUB(EXTRACT_16BITS(tptr)) ? "" : ", no sub-TLVs present",
1133 ISIS_MASK_MTATT(EXTRACT_16BITS(tptr)) ? ", ATT bit set" : "" );
1134
1135 return(2);
1136 }
1137
1138 /*
1139 * this is the common extended IP reach decoder
1140 * it is called from TLVs (135,235,236,237)
1141 * we process the TLV and optional subTLVs and return
1142 * the amount of processed bytes
1143 */
1144
1145 static int
1146 isis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) {
1147
1148 char ident_buffer[20];
1149 u_int8_t prefix[14]; /* shared copy buffer for IPv4 and IPv6 prefixes */
1150 u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen;
1151
1152 if (!TTEST2(*tptr, 4))
1153 return (0);
1154 metric = EXTRACT_32BITS(tptr);
1155 processed=4;
1156 tptr+=4;
1157
1158 if (afi == IPV4) {
1159 if (!TTEST2(*tptr, 1)) /* fetch status byte */
1160 return (0);
1161 status_byte=*(tptr++);
1162 bit_length = status_byte&0x3f;
1163 processed++;
1164 #ifdef INET6
1165 } else if (afi == IPV6) {
1166 if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
1167 return (0);
1168 status_byte=*(tptr++);
1169 bit_length=*(tptr++);
1170 processed+=2;
1171 #endif
1172 } else
1173 return (0); /* somebody is fooling us */
1174
1175 byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
1176
1177 if (!TTEST2(*tptr, byte_length))
1178 return (0);
1179 memset(prefix, 0, 16); /* clear the copy buffer */
1180 memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */
1181 tptr+=byte_length;
1182 processed+=byte_length;
1183
1184 if (afi == IPV4)
1185 printf("%sIPv4 prefix: %s/%d",
1186 ident,
1187 ipaddr_string(prefix),
1188 bit_length);
1189 #ifdef INET6
1190 if (afi == IPV6)
1191 printf("%sIPv6 prefix: %s/%d",
1192 ident,
1193 ip6addr_string(prefix),
1194 bit_length);
1195 #endif
1196
1197 printf("%s Metric: %u, Distribution: %s",
1198 ident,
1199 metric,
1200 ISIS_MASK_TLV_EXT_IP_UPDOWN(status_byte) ? "down" : "up");
1201
1202 if (afi == IPV4)
1203 printf(", %ssub-TLVs present",
1204 ISIS_MASK_TLV_EXT_IP_SUBTLV(status_byte) ? "" : "no ");
1205 #ifdef INET6
1206 if (afi == IPV6)
1207 printf(", %s, %ssub-TLVs present",
1208 ISIS_MASK_TLV_EXT_IP6_IE(status_byte) ? "External" : "Internal",
1209 ISIS_MASK_TLV_EXT_IP6_SUBTLV(status_byte) ? "" : "no ");
1210 #endif
1211
1212 if ((ISIS_MASK_TLV_EXT_IP_SUBTLV(status_byte) && afi == IPV4) ||
1213 (ISIS_MASK_TLV_EXT_IP6_SUBTLV(status_byte) && afi == IPV6)) {
1214 /* assume that one prefix can hold more
1215 than one subTLV - therefore the first byte must reflect
1216 the aggregate bytecount of the subTLVs for this prefix
1217 */
1218 if (!TTEST2(*tptr, 1))
1219 return (0);
1220 sublen=*(tptr++);
1221 processed+=sublen;
1222 printf(" (%u)",sublen); /* print out subTLV length */
1223
1224 while (sublen>0) {
1225 if (!TTEST2(*tptr,2))
1226 return (0);
1227 subtlvtype=*(tptr++);
1228 subtlvlen=*(tptr++);
1229 /* prepend the ident string */
1230 snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
1231 if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer))
1232 return(0);
1233 tptr+=subtlvlen;
1234 sublen-=(subtlvlen+2);
1235 }
1236 }
1237 return (processed);
1238 }
1239
1240 /*
1241 * isis_print
1242 * Decode IS-IS packets. Return 0 on error.
1243 */
1244
1245 static int isis_print (const u_int8_t *p, u_int length)
1246 {
1247 const struct isis_common_header *header;
1248
1249 const struct isis_iih_lan_header *header_iih_lan;
1250 const struct isis_iih_ptp_header *header_iih_ptp;
1251 const struct isis_lsp_header *header_lsp;
1252 const struct isis_csnp_header *header_csnp;
1253 const struct isis_psnp_header *header_psnp;
1254
1255 const struct isis_tlv_lsp *tlv_lsp;
1256 const struct isis_tlv_ptp_adj *tlv_ptp_adj;
1257 const struct isis_tlv_is_reach *tlv_is_reach;
1258 const struct isis_tlv_es_reach *tlv_es_reach;
1259
1260 u_int8_t pdu_type, max_area, id_length, type, len, tmp, alen, lan_alen, prefix_len;
1261 u_int8_t ext_is_len, ext_ip_len, mt_len;
1262 const u_int8_t *optr, *pptr, *tptr;
1263 u_short packet_len,pdu_len,time_remain;
1264 u_int i,ra,rr;
1265
1266 packet_len=length;
1267 optr = p; /* initialize the _o_riginal pointer to the packet start -
1268 need it for parsing the checksum TLV */
1269 header = (const struct isis_common_header *)p;
1270 TCHECK(*header);
1271 pptr = p+(ISIS_COMMON_HEADER_SIZE);
1272 header_iih_lan = (const struct isis_iih_lan_header *)pptr;
1273 header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
1274 header_lsp = (const struct isis_lsp_header *)pptr;
1275 header_csnp = (const struct isis_csnp_header *)pptr;
1276 header_psnp = (const struct isis_psnp_header *)pptr;
1277
1278 /*
1279 * Sanity checking of the header.
1280 */
1281
1282 if (header->version != ISIS_VERSION) {
1283 printf(", version %d packet not supported", header->version);
1284 return (0);
1285 }
1286
1287 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
1288 printf(", system ID length of %d is not supported",
1289 header->id_length);
1290 return (0);
1291 }
1292
1293 if (header->pdu_version != ISIS_VERSION) {
1294 printf(", version %d packet not supported", header->pdu_version);
1295 return (0);
1296 }
1297
1298 max_area = header->max_area;
1299 switch(max_area) {
1300 case 0:
1301 max_area = 3; /* silly shit */
1302 break;
1303 case 255:
1304 printf(", bad packet -- 255 areas");
1305 return (0);
1306 default:
1307 break;
1308 }
1309
1310 id_length = header->id_length;
1311 switch(id_length) {
1312 case 0:
1313 id_length = 6; /* silly shit again */
1314 break;
1315 case 1: /* 1-8 are valid sys-ID lenghts */
1316 case 2:
1317 case 3:
1318 case 4:
1319 case 5:
1320 case 6:
1321 case 7:
1322 case 8:
1323 break;
1324 case 255:
1325 id_length = 0; /* entirely useless */
1326 break;
1327 default:
1328 printf(", bad packet -- illegal sys-ID length (%u)", id_length);
1329 return (0);
1330 break;
1331 }
1332
1333 pdu_type=header->pdu_type;
1334
1335 /* in non-verbose mode just lets print the basic PDU Type*/
1336 if (vflag < 1) {
1337 printf("IS-IS, %s, length: %u",
1338 tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type),
1339 length);
1340 return(1);
1341 }
1342
1343 /* ok they seem to want to know everything - lets fully decode it */
1344 printf("IS-IS, length: %u",length);
1345
1346 printf("\n\thlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
1347 header->fixed_len,
1348 header->version,
1349 header->pdu_version,
1350 id_length,
1351 header->id_length,
1352 max_area,
1353 header->max_area);
1354
1355 /* first lets see if we know the PDU name*/
1356 printf(", pdu-type: %s",
1357 tok2str(isis_pdu_values,
1358 "unknown, type %u",
1359 pdu_type));
1360
1361 if (vflag > 1) {
1362 if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */
1363 return(0); /* for optionally debugging the common header */
1364 }
1365
1366 switch (pdu_type) {
1367
1368 case L1_LAN_IIH:
1369 case L2_LAN_IIH:
1370 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
1371 printf(", bogus fixed header length %u should be %lu",
1372 header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE);
1373 return (0);
1374 }
1375
1376 pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
1377 if (packet_len>pdu_len) {
1378 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1379 length=pdu_len;
1380 }
1381
1382 TCHECK(*header_iih_lan);
1383 printf("\n\t source-id: %s, holding time: %u, %s",
1384 isis_print_sysid(header_iih_lan->source_id,SYSTEM_ID_LEN),
1385 EXTRACT_16BITS(header_iih_lan->holding_time),
1386 tok2str(isis_iih_circuit_type_values,
1387 "unknown circuit type 0x%02x",
1388 header_iih_lan->circuit_type));
1389
1390 printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
1391 isis_print_nodeid(header_iih_lan->lan_id),
1392 (header_iih_lan->priority) & PRIORITY_MASK,
1393 pdu_len);
1394
1395 if (vflag > 1) {
1396 if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE))
1397 return(0);
1398 }
1399
1400 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
1401 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
1402 break;
1403
1404 case PTP_IIH:
1405 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
1406 printf(", bogus fixed header length %u should be %lu",
1407 header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE);
1408 return (0);
1409 }
1410
1411 pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
1412 if (packet_len>pdu_len) {
1413 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1414 length=pdu_len;
1415 }
1416
1417 TCHECK(*header_iih_ptp);
1418 printf("\n\t source-id: %s, holding time: %us, circuit-id: 0x%02x, %s, PDU length: %u",
1419 isis_print_sysid(header_iih_ptp->source_id,SYSTEM_ID_LEN),
1420 EXTRACT_16BITS(header_iih_ptp->holding_time),
1421 header_iih_ptp->circuit_id,
1422 tok2str(isis_iih_circuit_type_values,
1423 "unknown circuit type 0x%02x",
1424 header_iih_ptp->circuit_type),
1425 pdu_len);
1426
1427 if (vflag > 1) {
1428 if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE))
1429 return(0);
1430 }
1431
1432 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
1433 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
1434 break;
1435
1436 case L1_LSP:
1437 case L2_LSP:
1438 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
1439 printf(", bogus fixed header length %u should be %lu",
1440 header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE);
1441 return (0);
1442 }
1443
1444 pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
1445 if (packet_len>pdu_len) {
1446 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1447 length=pdu_len;
1448 }
1449
1450 TCHECK(*header_lsp);
1451 printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us",
1452 isis_print_lspid(header_lsp->lsp_id),
1453 EXTRACT_32BITS(header_lsp->sequence_number),
1454 EXTRACT_16BITS(header_lsp->remaining_lifetime));
1455 /* verify the checksum -
1456 * checking starts at the lsp-id field
1457 * which is 12 bytes after the packet start*/
1458 printf("\n\t chksum: 0x%04x (%s), PDU length: %u",
1459 EXTRACT_16BITS(header_lsp->checksum),
1460 (osi_cksum(optr+12, length-12)) ? "incorrect" : "correct",
1461 pdu_len);
1462
1463 printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
1464
1465 if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
1466 printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
1467 printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
1468 printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
1469 printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
1470 printf("ATT bit set, ");
1471 }
1472 printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
1473 printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
1474
1475 if (vflag > 1) {
1476 if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE))
1477 return(0);
1478 }
1479
1480 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
1481 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
1482 break;
1483
1484 case L1_CSNP:
1485 case L2_CSNP:
1486 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
1487 printf(", bogus fixed header length %u should be %lu",
1488 header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE);
1489 return (0);
1490 }
1491
1492 pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
1493 if (packet_len>pdu_len) {
1494 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1495 length=pdu_len;
1496 }
1497
1498 TCHECK(*header_csnp);
1499 printf("\n\t source-id: %s, PDU length: %u",
1500 isis_print_nodeid(header_csnp->source_id),
1501 pdu_len);
1502 printf("\n\t start lsp-id: %s",
1503 isis_print_lspid(header_csnp->start_lsp_id));
1504 printf("\n\t end lsp-id: %s",
1505 isis_print_lspid(header_csnp->end_lsp_id));
1506
1507 if (vflag > 1) {
1508 if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE))
1509 return(0);
1510 }
1511
1512 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
1513 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
1514 break;
1515
1516 case L1_PSNP:
1517 case L2_PSNP:
1518 if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
1519 printf("- bogus fixed header length %u should be %lu",
1520 header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE);
1521 return (0);
1522 }
1523
1524 pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
1525 if (packet_len>pdu_len) {
1526 packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
1527 length=pdu_len;
1528 }
1529
1530 TCHECK(*header_psnp);
1531 printf("\n\t source-id: %s",
1532 isis_print_nodeid(header_psnp->source_id));
1533
1534 if (vflag > 1) {
1535 if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE))
1536 return(0);
1537 }
1538
1539 packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
1540 pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
1541 break;
1542
1543 default:
1544 if(!print_unknown_data(pptr,"\n\t ",length))
1545 return(0);
1546 return (0);
1547 }
1548
1549 /*
1550 * Now print the TLV's.
1551 */
1552
1553 while (packet_len >= 2) {
1554 if (pptr == snapend) {
1555 return (1);
1556 }
1557
1558 if (!TTEST2(*pptr, 2)) {
1559 printf("\n\t\t packet exceeded snapshot (%ld) bytes",
1560 (long)(pptr-snapend));
1561 return (1);
1562 }
1563 type = *pptr++;
1564 len = *pptr++;
1565 tmp =len; /* copy temporary len & pointer to packet data */
1566 tptr = pptr;
1567 packet_len -= 2;
1568 if (len > packet_len) {
1569 break;
1570 }
1571
1572 /* first lets see if we know the TLVs name*/
1573 printf("\n\t %s TLV #%u, length: %u",
1574 tok2str(isis_tlv_values,
1575 "unknown",
1576 type),
1577 type,
1578 len);
1579
1580 /* now check if we have a decoder otherwise do a hexdump at the end*/
1581 switch (type) {
1582 case TLV_AREA_ADDR:
1583 if (!TTEST2(*tptr, 1))
1584 goto trunctlv;
1585 alen = *tptr++;
1586 while (tmp && alen < tmp) {
1587 printf("\n\t\tArea address (length: %u): %s",
1588 alen,
1589 print_nsap(tptr, alen));
1590 tptr += alen;
1591 tmp -= alen + 1;
1592 if (tmp==0) /* if this is the last area address do not attemt a boundary check */
1593 break;
1594 if (!TTEST2(*tptr, 1))
1595 goto trunctlv;
1596 alen = *tptr++;
1597 }
1598 break;
1599 case TLV_ISNEIGH:
1600 while (tmp >= ETHER_ADDR_LEN) {
1601 if (!TTEST2(*tptr, ETHER_ADDR_LEN))
1602 goto trunctlv;
1603 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr,ETHER_ADDR_LEN));
1604 tmp -= ETHER_ADDR_LEN;
1605 tptr += ETHER_ADDR_LEN;
1606 }
1607 break;
1608
1609 case TLV_ISNEIGH_VARLEN:
1610 if (!TTEST2(*tptr, 1))
1611 goto trunctlv;
1612 lan_alen = *tptr++; /* LAN adress length */
1613 tmp --;
1614 printf("\n\t\tLAN address length %u bytes ",lan_alen);
1615 while (tmp >= lan_alen) {
1616 if (!TTEST2(*tptr, lan_alen))
1617 goto trunctlv;
1618 printf("\n\t\tIS Neighbor: %s",isis_print_sysid(tptr,lan_alen));
1619 tmp -= lan_alen;
1620 tptr +=lan_alen;
1621 }
1622 break;
1623
1624 case TLV_PADDING:
1625 break;
1626
1627 case TLV_MT_IS_REACH:
1628 while (tmp >= 2+NODE_ID_LEN+3+1) {
1629 mt_len = isis_print_mtid(tptr, "\n\t\t");
1630 if (mt_len == 0) /* did something go wrong ? */
1631 goto trunctlv;
1632 tptr+=mt_len;
1633 tmp-=mt_len;
1634
1635 ext_is_len = isis_print_ext_is_reach(tptr,"\n\t\t");
1636 if (ext_is_len == 0) /* did something go wrong ? */
1637 goto trunctlv;
1638
1639 tmp-=ext_is_len;
1640 tptr+=ext_is_len;
1641 }
1642 break;
1643
1644 case TLV_IS_ALIAS_ID:
1645 while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */
1646 ext_is_len = isis_print_ext_is_reach(tptr,"\n\t\t");
1647 if (ext_is_len == 0) /* did something go wrong ? */
1648 goto trunctlv;
1649 tmp-=ext_is_len;
1650 tptr+=ext_is_len;
1651 }
1652 break;
1653
1654 case TLV_EXT_IS_REACH:
1655 while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */
1656 ext_is_len = isis_print_ext_is_reach(tptr,"\n\t\t");
1657 if (ext_is_len == 0) /* did something go wrong ? */
1658 goto trunctlv;
1659 tmp-=ext_is_len;
1660 tptr+=ext_is_len;
1661 }
1662 break;
1663 case TLV_IS_REACH:
1664 if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
1665 goto trunctlv;
1666 printf("\n\t\t%s",
1667 tok2str(isis_is_reach_virtual_values,
1668 "bogus virtual flag 0x%02x",
1669 *tptr++));
1670 tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
1671 while (tmp >= sizeof(struct isis_tlv_is_reach)) {
1672 if (!TTEST(*tlv_is_reach))
1673 goto trunctlv;
1674 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tlv_is_reach->neighbor_nodeid));
1675 isis_print_metric_block(&tlv_is_reach->isis_metric_block);
1676 tmp -= sizeof(struct isis_tlv_is_reach);
1677 tlv_is_reach++;
1678 }
1679 break;
1680
1681 case TLV_ESNEIGH:
1682 tlv_es_reach = (const struct isis_tlv_es_reach *)tptr;
1683 while (tmp >= sizeof(struct isis_tlv_es_reach)) {
1684 if (!TTEST(*tlv_es_reach))
1685 goto trunctlv;
1686 printf("\n\t\tES Neighbor: %s",
1687 isis_print_sysid(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN));
1688 isis_print_metric_block(&tlv_es_reach->isis_metric_block);
1689 tmp -= sizeof(struct isis_tlv_es_reach);
1690 tlv_es_reach++;
1691 }
1692 break;
1693
1694 /* those two TLVs share the same format */
1695 case TLV_IP_REACH:
1696 case TLV_IP_REACH_EXT:
1697 if (!isis_print_tlv_ip_reach(pptr, len))
1698 return (1);
1699 break;
1700
1701 case TLV_EXT_IP_REACH:
1702 while (tmp>0) {
1703 ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t\t", IPV4);
1704 if (ext_ip_len == 0) /* did something go wrong ? */
1705 goto trunctlv;
1706 tptr+=ext_ip_len;
1707 tmp-=ext_ip_len;
1708 }
1709 break;
1710
1711 case TLV_MT_IP_REACH:
1712 while (tmp>0) {
1713 mt_len = isis_print_mtid(tptr, "\n\t\t");
1714 if (mt_len == 0) /* did something go wrong ? */
1715 goto trunctlv;
1716 tptr+=mt_len;
1717 tmp-=mt_len;
1718
1719 ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t\t", IPV4);
1720 if (ext_ip_len == 0) /* did something go wrong ? */
1721 goto trunctlv;
1722 tptr+=ext_ip_len;
1723 tmp-=ext_ip_len;
1724 }
1725 break;
1726
1727 #ifdef INET6
1728 case TLV_IP6_REACH:
1729 while (tmp>0) {
1730 ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t\t", IPV6);
1731 if (ext_ip_len == 0) /* did something go wrong ? */
1732 goto trunctlv;
1733 tptr+=ext_ip_len;
1734 tmp-=ext_ip_len;
1735 }
1736 break;
1737
1738 case TLV_MT_IP6_REACH:
1739 while (tmp>0) {
1740 mt_len = isis_print_mtid(tptr, "\n\t\t");
1741 if (mt_len == 0) /* did something go wrong ? */
1742 goto trunctlv;
1743 tptr+=mt_len;
1744 tmp-=mt_len;
1745
1746 ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t\t", IPV6);
1747 if (ext_ip_len == 0) /* did something go wrong ? */
1748 goto trunctlv;
1749 tptr+=ext_ip_len;
1750 tmp-=ext_ip_len;
1751 }
1752 break;
1753
1754 case TLV_IP6ADDR:
1755 while (tmp>0) {
1756 if (!TTEST2(*tptr, 16))
1757 goto trunctlv;
1758
1759 printf("\n\t\tIPv6 interface address: %s",
1760 ip6addr_string(tptr));
1761
1762 tptr += 16;
1763 tmp -= 16;
1764 }
1765 break;
1766 #endif
1767 case TLV_AUTH:
1768 if (!TTEST2(*tptr, 1))
1769 goto trunctlv;
1770
1771 printf("\n\t\t%s: ",
1772 tok2str(isis_subtlv_auth_values,
1773 "unknown Authentication type 0x%02x",
1774 *tptr));
1775
1776 switch (*tptr) {
1777 case SUBTLV_AUTH_SIMPLE:
1778 for(i=1;i<len;i++) {
1779 if (!TTEST2(*(tptr+i), 1))
1780 goto trunctlv;
1781 printf("%c",*(tptr+i));
1782 }
1783 break;
1784 case SUBTLV_AUTH_MD5:
1785 for(i=1;i<len;i++) {
1786 if (!TTEST2(*(tptr+i), 1))
1787 goto trunctlv;
1788 printf("%02x",*(tptr+i));
1789 }
1790 if (len != SUBTLV_AUTH_MD5_LEN+1)
1791 printf(", (malformed subTLV) ");
1792 break;
1793 case SUBTLV_AUTH_PRIVATE:
1794 default:
1795 if(!print_unknown_data(tptr+1,"\n\t\t ",len-1))
1796 return(0);
1797 break;
1798 }
1799 break;
1800
1801 case TLV_PTP_ADJ:
1802 tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
1803 if(tmp>=1) {
1804 if (!TTEST2(*tptr, 1))
1805 goto trunctlv;
1806 printf("\n\t\tAdjacency State: %s",
1807 tok2str(isis_ptp_adjancey_values, "0x%02x", *tptr));
1808 tmp--;
1809 }
1810 if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
1811 if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id,
1812 sizeof(tlv_ptp_adj->extd_local_circuit_id)))
1813 goto trunctlv;
1814 printf("\n\t\tExtended Local circuit ID: 0x%08x",
1815 EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id));
1816 tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
1817 }
1818 if(tmp>=SYSTEM_ID_LEN) {
1819 if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN))
1820 goto trunctlv;
1821 printf("\n\t\tNeighbor SystemID: %s",
1822 isis_print_sysid(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN));
1823 tmp-=SYSTEM_ID_LEN;
1824 }
1825 if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
1826 if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id,
1827 sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)))
1828 goto trunctlv;
1829 printf("\n\t\tNeighbor Extended Local circuit ID: 0x%08x",
1830 EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id));
1831 }
1832 break;
1833
1834 case TLV_PROTOCOLS:
1835 printf("\n\t\tNLPID(s): ");
1836 while (tmp>0) {
1837 if (!TTEST2(*(tptr), 1))
1838 goto trunctlv;
1839 printf("%s",
1840 tok2str(osi_nlpid_values,
1841 "Unknown 0x%02x",
1842 *tptr++));
1843 if (tmp>1) /* further NPLIDs ? - put comma */
1844 printf(", ");
1845 tmp--;
1846 }
1847 break;
1848
1849 case TLV_TE_ROUTER_ID:
1850 if (!TTEST2(*pptr, 4))
1851 goto trunctlv;
1852 printf("\n\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr));
1853 break;
1854
1855 case TLV_IPADDR:
1856 while (tmp>0) {
1857 if (!TTEST2(*tptr, 4))
1858 goto trunctlv;
1859 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1860 tptr += 4;
1861 tmp -= 4;
1862 }
1863 break;
1864
1865 case TLV_HOSTNAME:
1866 printf("\n\t\tHostname: ");
1867 while (tmp>0) {
1868 if (!TTEST2(*tptr, 1))
1869 goto trunctlv;
1870 printf("%c",*tptr++);
1871 tmp--;
1872 }
1873 break;
1874
1875 case TLV_SHARED_RISK_GROUP:
1876 if (!TTEST2(*tptr, NODE_ID_LEN))
1877 goto trunctlv;
1878 printf("\n\t\tIS Neighbor: %s", isis_print_nodeid(tptr));
1879 tptr+=(NODE_ID_LEN);
1880 len-=(NODE_ID_LEN);
1881
1882 if (!TTEST2(*tptr, 1))
1883 goto trunctlv;
1884 printf(", %s", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered");
1885 len--;
1886
1887 if (!TTEST2(*tptr,4))
1888 goto trunctlv;
1889 printf("\n\t\tIPv4 interface address: %s", ipaddr_string(tptr));
1890 tptr+=4;
1891 len-=4;
1892
1893 if (!TTEST2(*tptr,4))
1894 goto trunctlv;
1895 printf("\n\t\tIPv4 neighbor address: %s", ipaddr_string(tptr));
1896 tptr+=4;
1897 len-=4;
1898
1899 while (tmp>0) {
1900 if (!TTEST2(*tptr, 4))
1901 goto trunctlv;
1902 printf("\n\t\tLink-ID: 0x%08x", EXTRACT_32BITS(tptr));
1903 tptr+=4;
1904 len-=4;
1905 }
1906 break;
1907
1908 case TLV_LSP:
1909 tlv_lsp = (const struct isis_tlv_lsp *)tptr;
1910 while(tmp>0) {
1911 printf("\n\t\tlsp-id: %s",
1912 isis_print_nodeid(tlv_lsp->lsp_id));
1913 if (!TTEST((tlv_lsp->lsp_id)[NODE_ID_LEN]))
1914 goto trunctlv;
1915 printf("-%02x",(tlv_lsp->lsp_id)[NODE_ID_LEN]);
1916 if (!TTEST2(tlv_lsp->sequence_number, 4))
1917 goto trunctlv;
1918 printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number));
1919 if (!TTEST2(tlv_lsp->remaining_lifetime, 2))
1920 goto trunctlv;
1921 printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime));
1922 if (!TTEST2(tlv_lsp->checksum, 2))
1923 goto trunctlv;
1924 printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum));
1925 tmp-=sizeof(struct isis_tlv_lsp);
1926 tlv_lsp++;
1927 }
1928 break;
1929
1930 case TLV_CHECKSUM:
1931 if (!TTEST2(*tptr, 2))
1932 goto trunctlv;
1933 printf("\n\t\tchecksum: 0x%04x (%s)",
1934 EXTRACT_16BITS(tptr),
1935 (osi_cksum(optr, length)) ? "incorrect" : "correct");
1936 break;
1937
1938 case TLV_MT_SUPPORTED:
1939 while (tmp>1) {
1940 /* length can only be a multiple of 2, otherwise there is
1941 something broken -> so decode down until length is 1 */
1942 if (tmp!=1) {
1943 mt_len = isis_print_mtid(tptr, "\n\t\t");
1944 if (mt_len == 0) /* did something go wrong ? */
1945 goto trunctlv;
1946 tptr+=mt_len;
1947 tmp-=mt_len;
1948 } else {
1949 printf("\n\t\tmalformed MT-ID");
1950 break;
1951 }
1952 }
1953 break;
1954
1955 case TLV_RESTART_SIGNALING:
1956 if (!TTEST2(*tptr, 3))
1957 goto trunctlv;
1958 rr = ISIS_MASK_TLV_RESTART_RR(*tptr);
1959 ra = ISIS_MASK_TLV_RESTART_RA(*tptr);
1960 tptr++;
1961 time_remain = EXTRACT_16BITS(tptr);
1962 printf("\n\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\tRemaining holding time: %us",
1963 rr ? "set" : "clear", ra ? "set" : "clear", time_remain);
1964 break;
1965
1966 case TLV_IDRP_INFO:
1967 if (!TTEST2(*tptr, 1))
1968 goto trunctlv;
1969 printf("\n\t\tInter-Domain Information Type: %s",
1970 tok2str(isis_subtlv_idrp_values,
1971 "Unknown (0x%02x)",
1972 *tptr));
1973 switch (*tptr++) {
1974 case SUBTLV_IDRP_ASN:
1975 if (!TTEST2(*tptr, 2)) /* fetch AS number */
1976 goto trunctlv;
1977 printf("AS Number: %u",EXTRACT_16BITS(tptr));
1978 break;
1979 case SUBTLV_IDRP_LOCAL:
1980 case SUBTLV_IDRP_RES:
1981 default:
1982 if(!print_unknown_data(tptr,"\n\t\t",len-1))
1983 return(0);
1984 break;
1985 }
1986 break;
1987
1988 case TLV_LSP_BUFFERSIZE:
1989 if (!TTEST2(*tptr, 2))
1990 goto trunctlv;
1991 printf("LSP Buffersize: %u",EXTRACT_16BITS(tptr));
1992 break;
1993
1994 case TLV_PART_DIS:
1995 while (tmp >= SYSTEM_ID_LEN) {
1996 if (!TTEST2(*tptr, SYSTEM_ID_LEN))
1997 goto trunctlv;
1998 printf("%s",isis_print_sysid(tptr,SYSTEM_ID_LEN));
1999 tptr+=SYSTEM_ID_LEN;
2000 tmp-=SYSTEM_ID_LEN;
2001 }
2002 break;
2003
2004 case TLV_PREFIX_NEIGH:
2005 if (!TTEST2(*tptr, sizeof(struct isis_metric_block)))
2006 goto trunctlv;
2007 printf("Metric Block");
2008 isis_print_metric_block((const struct isis_metric_block *)tptr);
2009 tptr+=sizeof(struct isis_metric_block);
2010 tmp-=sizeof(struct isis_metric_block);
2011
2012 while(tmp>0) {
2013 if (!TTEST2(*tptr, 1))
2014 goto trunctlv;
2015 prefix_len=*tptr++; /* read out prefix length in semioctets*/
2016 tmp--;
2017 if (!TTEST2(*tptr, prefix_len/2))
2018 goto trunctlv;
2019 printf("\n\t\tAddress: %s/%u",
2020 print_nsap(tptr,prefix_len/2),
2021 prefix_len*4);
2022 tptr+=prefix_len/2;
2023 tmp-=prefix_len/2;
2024 }
2025 break;
2026
2027 case TLV_IIH_SEQNR:
2028 if (!TTEST2(*tptr, 4)) /* check if four bytes are on the wire */
2029 goto trunctlv;
2030 printf("\n\t\tSequence number: %u", EXTRACT_32BITS(tptr) );
2031 break;
2032
2033 case TLV_VENDOR_PRIVATE:
2034 if (!TTEST2(*tptr, 3)) /* check if enough byte for a full oui */
2035 goto trunctlv;
2036 printf("\n\t\tVendor OUI Code: 0x%06x", EXTRACT_24BITS(tptr) );
2037 tptr+=3;
2038 tmp-=3;
2039 if (tmp > 0) /* hexdump the rest */
2040 if(!print_unknown_data(tptr,"\n\t\t",tmp))
2041 return(0);
2042 break;
2043 /*
2044 * FIXME those are the defined TLVs that lack a decoder
2045 * you are welcome to contribute code ;-)
2046 */
2047
2048 case TLV_DECNET_PHASE4:
2049 case TLV_LUCENT_PRIVATE:
2050 case TLV_IPAUTH:
2051 case TLV_NORTEL_PRIVATE1:
2052 case TLV_NORTEL_PRIVATE2:
2053
2054 default:
2055 if (vflag <= 1) {
2056 if(!print_unknown_data(pptr,"\n\t\t",len))
2057 return(0);
2058 }
2059 break;
2060 }
2061 /* do we want to see an additionally hexdump ? */
2062 if (vflag> 1) {
2063 if(!print_unknown_data(pptr,"\n\t\t",len))
2064 return(0);
2065 }
2066
2067 pptr += len;
2068 packet_len -= len;
2069 }
2070
2071 if (packet_len != 0) {
2072 printf("\n\t\t %d straggler bytes", packet_len);
2073 }
2074 return (1);
2075
2076 trunc:
2077 fputs("[|isis]", stdout);
2078 return (1);
2079
2080 trunctlv:
2081 printf("\n\t\t packet exceeded snapshot");
2082 return(1);
2083 }
2084
2085 /*
2086 * Verify the checksum. See 8473-1, Appendix C, section C.4.
2087 */
2088
2089 static int
2090 osi_cksum(const u_int8_t *tptr, u_int len)
2091 {
2092 int32_t c0 = 0, c1 = 0;
2093
2094 while ((int)--len >= 0) {
2095 c0 += *tptr++;
2096 c0 %= 255;
2097 c1 += c0;
2098 c1 %= 255;
2099 }
2100 return (c0 | c1);
2101 }