2 * Copyright (c) 1992, 1993, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
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
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.
21 * Original code by Matt Thomas, Digital Equipment Corporation
27 static const char rcsid[] =
28 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.22 2000/10/11 04:04:33 guy Exp $ (LBL)";
35 #include <sys/types.h>
37 #include <sys/socket.h>
39 #include <netinet/in.h>
43 #include "interface.h"
44 #include "addrtoname.h"
45 #include "ethertype.h"
49 #define NLPID_CLNS 129 /* 0x81 */
50 #define NLPID_ESIS 130 /* 0x82 */
51 #define NLPID_ISIS 131 /* 0x83 */
52 #define NLPID_NULLNS 0
56 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
59 #define SYSTEM_ID_LEN ETHER_ADDR_LEN
60 #define ISIS_VERSION 1
61 #define PDU_TYPE_MASK 0x1F
62 #define PRIORITY_MASK 0x7F
69 #define L1_COMPLETE_SEQ_PDU 24
70 #define L2_COMPLETE_SEQ_PDU 25
73 * A TLV is a tuple of a type, length and a value and is normally used for
74 * encoding information in all sorts of places. This is an enumeration of
75 * the well known types.
78 #define TLV_AREA_ADDR 1
79 #define TLV_IS_REACH 2
80 #define TLV_ES_REACH 3
85 #define TLV_AUTHENT 10
86 #define TLV_IP_REACH 128
87 #define TLV_PROTOCOLS 129
88 #define TLV_IP_EXTERN 130
89 #define TLV_IDRP_INFO 131
90 #define TLV_IPADDR 132
91 #define TLV_IPAUTH 133
92 #define TLV_PTP_ADJ 240
95 * Katz's point to point adjacency TLV uses codes to tell us the state of
96 * the remote adjacency. Enumerate them.
99 #define ISIS_PTP_ADJ_UP 0
100 #define ISIS_PTP_ADJ_INIT 1
101 #define ISIS_PTP_ADJ_DOWN 2
103 static int osi_cksum(const u_char *, int, u_char *);
104 static void esis_print(const u_char *, u_int);
105 static int isis_print(const u_char *, u_int);
108 struct isis_ptp_adjancey_values {
113 static struct isis_ptp_adjancey_values isis_ptp_adjancey_values[] = {
114 { ISIS_PTP_ADJ_UP, "UP" },
115 { ISIS_PTP_ADJ_INIT, "INIT" },
116 { ISIS_PTP_ADJ_DOWN, "DOWN" }
119 struct isis_common_header {
122 u_char version; /* Protocol version? */
124 u_char enc_pdu_type; /* 3 MSbs are reserved */
125 u_char pkt_version; /* Packet format version? */
133 u_char version; /* Protocol version? */
135 u_char enc_pdu_type; /* 3 MSbs are reserved */
136 u_char pkt_version; /* Packet format version? */
140 u_char enc_source_id[SYSTEM_ID_LEN];
141 u_char enc_holding_time[2];
142 u_char enc_packet_len[2];
144 u_char enc_lan_id[SYSTEM_ID_LEN+1];
146 struct isis_lan_header {
148 u_char enc_source_id[SYSTEM_ID_LEN];
149 u_char enc_holding_time[2];
150 u_char enc_packet_len[2];
152 u_char enc_lan_id[SYSTEM_ID_LEN+1];
155 struct isis_ptp_header {
157 u_char enc_source_id[SYSTEM_ID_LEN];
158 u_char enc_holding_time[2];
159 u_char enc_packet_len[2];
160 u_char loc_circuit_id;
163 #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
164 #define ISIS_HEADER_SIZE (15+(SYSTEM_ID_LEN<<1))
165 #define ISIS_PTP_HEADER_SIZE (14+SYSTEM_ID_LEN)
166 #define L1_LS_PDU_HEADER_SIZE (21+SYSTEM_ID_LEN)
167 #define L2_LS_PDU_HEADER_SIZE L1_LS_PDU_HEADER_SIZE
168 #define L1_COMPLETE_SEQ_PDU_HEADER_SIZE 33
169 #define L2_COMPLETE_SEQ_PDU_HEADER_SIZE L1_COMPLETE_SEQ_PDU_HEADER_SIZE
174 isoclns_print(const u_char *p, u_int length, u_int caplen,
175 const u_char *esrc, const u_char *edst)
178 struct isis_header *header;
180 header = (struct isis_header *)p;
181 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
184 printf("[|iso-clns] ");
187 etheraddr_string(esrc),
188 etheraddr_string(edst));
197 (void)printf(" %s > %s",
198 etheraddr_string(esrc),
199 etheraddr_string(edst));
205 (void)printf(" %s > %s",
206 etheraddr_string(esrc),
207 etheraddr_string(edst));
208 esis_print(p, length);
214 if(pdu_type != PTP_IIH)
215 (void)printf(" %s > %s",
216 etheraddr_string(esrc),
217 etheraddr_string(edst));
219 (void)printf(" len=%d ", length);
220 if (!isis_print(p, length))
221 default_print_unaligned(p, caplen);
225 printf("iso nullns");
227 (void)printf(" %s > %s",
228 etheraddr_string(esrc),
229 etheraddr_string(edst));
233 printf("iso clns %02x", p[0]);
235 (void)printf(" %s > %s",
236 etheraddr_string(esrc),
237 etheraddr_string(edst));
238 (void)printf(" len=%d ", length);
240 default_print_unaligned(p, caplen);
245 #define ESIS_REDIRECT 6
258 esis_print(const u_char *p, u_int length)
262 const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
269 printf(" no header at all!");
277 printf(" LI(%d) > PDU size (%d)!", li, length);
280 if (li < sizeof(struct esis_hdr) + 2) {
284 printf(" too short for esis header %d:", li);
285 while (--length != 0)
286 printf("%02X", *p++);
290 switch (eh->type & 0x1f) {
305 printf(" type %d", eh->type & 0x1f);
308 off[0] = eh->cksum[0];
309 off[1] = eh->cksum[1];
310 if (vflag && osi_cksum(p, li, off)) {
311 printf(" bad cksum (got %02x%02x)",
312 eh->cksum[1], eh->cksum[0]);
313 default_print(p, length);
316 if (eh->version != 1) {
317 printf(" unsupported version %d", eh->version);
320 p += sizeof(*eh) + 2;
321 li -= sizeof(*eh) + 2; /* protoid * li */
323 switch (eh->type & 0x1f) {
324 case ESIS_REDIRECT: {
325 const u_char *dst, *snpa, *is;
327 dst = p; p += *p + 1;
330 printf("\n\t\t\t %s", isonsap_string(dst));
331 snpa = p; p += *p + 1;
340 printf(" > %s", etheraddr_string(&snpa[1]));
342 printf(" > %s", isonsap_string(is));
362 printf("\n\t\t\t %s", isonsap_string(is));
368 (void)printf(" len=%d", length);
369 if (length && p < snapend) {
370 length = snapend - p;
371 default_print(p, length);
376 while (p < ep && li) {
383 printf(" bad opts/li");
390 printf(" opt (%d) too long", op);
398 if (op == 198 && opli == 2) {
399 printf(" tmo=%d", q[0] * 256 + q[1]);
402 printf (" %d:<", op);
404 printf("%02x", *q++);
415 print_nsap (register const u_char *cp, register int length)
419 for (i = 0; i < length; i++) {
420 printf("%02x", *cp++);
421 if (((i & 1) == 0) && (i + 1 < length)) {
430 * Decode IS-IS packets. Return 0 on error.
432 * So far, this is only smart enough to print IIH's. Someday...
436 isis_print (const u_char *p, u_int length)
438 struct isis_header *header;
439 struct isis_ptp_header *header_ptp;
440 u_char pdu_type, max_area, priority, type, len, tmp, alen;
441 const u_char *pptr, *tptr;
442 u_short packet_len, holding_time;
445 header = (struct isis_header *)p;
446 header_ptp = (struct isis_ptp_header *)header;
450 * Sanity checking of the header.
452 if (header->nlpid != NLPID_ISIS) {
453 printf(" coding error!");
457 if (header->version != ISIS_VERSION) {
458 printf(" version %d packet not supported", header->version);
462 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
463 printf(" system ID length of %d is not supported",
468 if ((header->fixed_len != ISIS_HEADER_SIZE) &&
469 (header->fixed_len != ISIS_PTP_HEADER_SIZE) &&
470 (header->fixed_len != L1_LS_PDU_HEADER_SIZE) &&
471 (header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) {
472 printf(" bogus fixed header length %u",
477 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
478 if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH) &&
479 (pdu_type != PTP_IIH) &&
480 (pdu_type != L1_COMPLETE_SEQ_PDU) &&
481 (pdu_type != L2_COMPLETE_SEQ_PDU) ) {
482 printf(" PDU type (%d) not supported", pdu_type);
486 if (header->pkt_version != ISIS_VERSION) {
487 printf(" version %d packet not supported", header->pkt_version);
491 max_area = header->enc_max_area;
494 max_area = 3; /* silly shit */
497 printf(" bad packet -- 255 areas");
503 switch (header->circuit) {
505 printf(" PDU with circuit type 0");
508 if (pdu_type == L2_LAN_IIH) {
509 printf(" L2 IIH on an L1 only circuit");
514 if (pdu_type == L1_LAN_IIH) {
515 printf(" L1 IIH on an L2 only circuit");
522 printf(" unknown circuit type");
526 holding_time = EXTRACT_16BITS(header->enc_holding_time);
528 packet_len = EXTRACT_16BITS(header->enc_packet_len);
529 if ((packet_len < ISIS_HEADER_SIZE) ||
530 (packet_len > length)) {
531 printf(" bogus packet length %d, real length %d", packet_len,
536 if(pdu_type != PTP_IIH)
537 priority = header->enc_priority & PRIORITY_MASK;
540 * Now print the fixed header.
544 printf(" L1 lan iih, ");
547 printf(" L2 lan iih, ");
550 printf(" PTP iih, ");
555 switch (header->circuit) {
567 printf ("holding time %d ", holding_time);
568 printf ("\n\t\t\t source %s, length %d",
569 etheraddr_string(header->enc_source_id), packet_len);
570 if((pdu_type==L1_LAN_IIH)||(pdu_type==L2_LAN_IIH))
571 printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id),
572 header->enc_lan_id[SYSTEM_ID_LEN]);
575 * Now print the TLV's.
577 if(pdu_type==PTP_IIH) {
578 packet_len -= ISIS_PTP_HEADER_SIZE;
579 pptr = p + ISIS_PTP_HEADER_SIZE;
581 packet_len -= ISIS_HEADER_SIZE;
582 pptr = p + ISIS_HEADER_SIZE;
584 while (packet_len >= 2) {
585 if (pptr >= snapend) {
586 printf("\n\t\t\t packet exceeded snapshot");
592 if (len > packet_len) {
598 printf("\n\t\t\t area addresses");
602 while (tmp && alen < tmp) {
604 print_nsap(tptr, alen);
605 printf(" (%d)", alen);
612 printf("\n\t\t\t neighbor addresses");
615 while (tmp >= ETHER_ADDR_LEN) {
616 printf("\n\t\t\t %s", etheraddr_string(tptr));
617 tmp -= ETHER_ADDR_LEN;
618 tptr += ETHER_ADDR_LEN;
622 printf("\n\t\t\t padding for %d bytes", len);
625 printf("\n\t\t\t authentication data");
626 default_print(pptr, len);
629 printf("\n\t\t\t PTP adjacency status %s",
630 isis_ptp_adjancey_values[*pptr].name);
633 printf("\n\t\t\t Supports protocols %s", (len>1)? "are":"is");
635 printf(" %02X", (u_char)*(pptr+i));
638 printf("\n\t\t\t IP address: %s", ipaddr_string(pptr));
641 printf("\n\t\t\t unknown TLV, type %d, length %d", type, len);
649 if (packet_len != 0) {
650 printf("\n\t\t\t %d straggler bytes", packet_len);
656 * Verify the checksum. See 8473-1, Appendix C, section C.4.
660 osi_cksum(register const u_char *p, register int len, u_char *off)
662 int32_t c0 = 0, c1 = 0;
664 if ((off[0] == 0) && (off[1] == 0))
668 while ((int)--len >= 0) {