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