Deleted Added
full compact
print-isoclns.c (32149) print-isoclns.c (39300)
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
24#ifndef lint
25static const char rcsid[] =
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
24#ifndef lint
25static const char rcsid[] =
26 "@(#) $Header: print-isoclns.c,v 1.14 96/12/10 23:26:56 leres Exp $ (LBL)";
26 "@(#) $Header: print-isoclns.c,v 1.15 96/12/31 21:27:41 leres Exp $ (LBL)";
27#endif
28
29#include <sys/types.h>
30#include <sys/time.h>
31#include <sys/socket.h>
32
33#if __STDC__
34struct mbuf;
35struct rtentry;
36#endif
37#include <net/if.h>
38
39#include <netinet/in.h>
40#include <net/ethernet.h>
41
42#include <stdio.h>
43
44#include "interface.h"
45#include "addrtoname.h"
46#include "ethertype.h"
47#include "extract.h"
48
49#define NLPID_CLNS 129 /* 0x81 */
50#define NLPID_ESIS 130 /* 0x82 */
51#define NLPID_ISIS 131 /* 0x83 */
52#define NLPID_NULLNS 0
53
54
55/*
56 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
57 */
58
59#define SYSTEM_ID_LEN sizeof(struct ether_addr)
60#define ISIS_VERSION 1
61#define PDU_TYPE_MASK 0x1F
62#define PRIORITY_MASK 0x7F
63
64#define L1_LAN_IIH 15
65#define L2_LAN_IIH 16
66#define PTP_IIH 17
67#define L1_LS_PDU 18
68#define L2_LS_PDU 19
69#define L1_COMPLETE_SEQ_PDU 24
70#define L2_COMPLETE_SEQ_PDU 25
71
72/*
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.
76 */
77
78#define TLV_AREA_ADDR 1
79#define TLV_IS_REACH 2
80#define TLV_ES_REACH 3
81#define TLV_SUMMARY 5
82#define TLV_ISNEIGH 6
83#define TLV_PADDING 8
84#define TLV_LSP 9
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
93
94/*
95 * Katz's point to point adjacency TLV uses codes to tell us the state of
96 * the remote adjacency. Enumerate them.
97 */
98
99#define ISIS_PTP_ADJ_UP 0
100#define ISIS_PTP_ADJ_INIT 1
101#define ISIS_PTP_ADJ_DOWN 2
102
103static int osi_cksum(const u_char *, int, u_char *);
104static void esis_print(const u_char *, u_int);
105static int isis_print(const u_char *, u_int);
106
107
108struct isis_ptp_adjancey_values {
109 u_char id;
110 char *name;
111};
112
113static 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"
117};
118
119struct isis_common_header {
120 u_char nlpid;
121 u_char fixed_len;
122 u_char version; /* Protocol version? */
123 u_char id_length;
124 u_char enc_pdu_type; /* 3 MSbs are reserved */
125 u_char pkt_version; /* Packet format version? */
126 u_char reserved;
127 u_char enc_max_area;
128};
129
130struct isis_header {
131 u_char nlpid;
132 u_char fixed_len;
133 u_char version; /* Protocol version? */
134 u_char id_length;
135 u_char enc_pdu_type; /* 3 MSbs are reserved */
136 u_char pkt_version; /* Packet format version? */
137 u_char reserved;
138 u_char enc_max_area;
139 u_char circuit;
140 u_char enc_source_id[SYSTEM_ID_LEN];
141 u_char enc_holding_time[2];
142 u_char enc_packet_len[2];
143 u_char enc_priority;
144 u_char enc_lan_id[SYSTEM_ID_LEN+1];
145};
146struct isis_lan_header {
147 u_char circuit;
148 u_char enc_source_id[SYSTEM_ID_LEN];
149 u_char enc_holding_time[2];
150 u_char enc_packet_len[2];
151 u_char enc_priority;
152 u_char enc_lan_id[SYSTEM_ID_LEN+1];
153};
154
155struct isis_ptp_header {
156 u_char circuit;
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;
161};
162
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
170
171
172
173void
174isoclns_print(const u_char *p, u_int length, u_int caplen,
175 const u_char *esrc, const u_char *edst)
176{
177 u_char pdu_type;
178 struct isis_header *header;
179
180 header = (struct isis_header *)p;
181 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
182
183 if (caplen < 1) {
184 printf("[|iso-clns] ");
185 if (!eflag)
186 printf("%s > %s",
187 etheraddr_string(esrc),
188 etheraddr_string(edst));
189 return;
190 }
191
192 switch (*p) {
193
194 case NLPID_CLNS:
195 printf("iso clns");
196 if (!eflag)
197 (void)printf(" %s > %s",
198 etheraddr_string(esrc),
199 etheraddr_string(edst));
200 break;
201
202 case NLPID_ESIS:
203 printf("iso esis");
204 if (!eflag)
205 (void)printf(" %s > %s",
206 etheraddr_string(esrc),
207 etheraddr_string(edst));
208 esis_print(p, length);
209 return;
210
211 case NLPID_ISIS:
212 printf("iso isis");
213 if (!eflag) {
214 if(pdu_type != PTP_IIH)
215 (void)printf(" %s > %s",
216 etheraddr_string(esrc),
217 etheraddr_string(edst));
218 }
219 (void)printf(" len=%d ", length);
220 if (!isis_print(p, length))
221 default_print_unaligned(p, caplen);
222 break;
223
224 case NLPID_NULLNS:
225 printf("iso nullns");
226 if (!eflag)
227 (void)printf(" %s > %s",
228 etheraddr_string(esrc),
229 etheraddr_string(edst));
230 break;
231
232 default:
233 printf("iso clns %02x", p[0]);
234 if (!eflag)
235 (void)printf(" %s > %s",
236 etheraddr_string(esrc),
237 etheraddr_string(edst));
238 (void)printf(" len=%d ", length);
239 if (caplen > 1)
240 default_print_unaligned(p, caplen);
241 break;
242 }
243}
244
245#define ESIS_REDIRECT 6
246#define ESIS_ESH 2
247#define ESIS_ISH 4
248
249struct esis_hdr {
250 u_char version;
251 u_char reserved;
252 u_char type;
253 u_char tmo[2];
254 u_char cksum[2];
255};
256
257static void
258esis_print(const u_char *p, u_int length)
259{
260 const u_char *ep;
261 int li = p[1];
262 const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
263 u_char cksum[2];
264 u_char off[2];
265
266 if (length == 2) {
267 if (qflag)
268 printf(" bad pkt!");
269 else
270 printf(" no header at all!");
271 return;
272 }
273 ep = p + li;
274 if (li > length) {
275 if (qflag)
276 printf(" bad pkt!");
277 else
278 printf(" LI(%d) > PDU size (%d)!", li, length);
279 return;
280 }
281 if (li < sizeof(struct esis_hdr) + 2) {
282 if (qflag)
283 printf(" bad pkt!");
284 else {
285 printf(" too short for esis header %d:", li);
27#endif
28
29#include <sys/types.h>
30#include <sys/time.h>
31#include <sys/socket.h>
32
33#if __STDC__
34struct mbuf;
35struct rtentry;
36#endif
37#include <net/if.h>
38
39#include <netinet/in.h>
40#include <net/ethernet.h>
41
42#include <stdio.h>
43
44#include "interface.h"
45#include "addrtoname.h"
46#include "ethertype.h"
47#include "extract.h"
48
49#define NLPID_CLNS 129 /* 0x81 */
50#define NLPID_ESIS 130 /* 0x82 */
51#define NLPID_ISIS 131 /* 0x83 */
52#define NLPID_NULLNS 0
53
54
55/*
56 * IS-IS is defined in ISO 10589. Look there for protocol definitions.
57 */
58
59#define SYSTEM_ID_LEN sizeof(struct ether_addr)
60#define ISIS_VERSION 1
61#define PDU_TYPE_MASK 0x1F
62#define PRIORITY_MASK 0x7F
63
64#define L1_LAN_IIH 15
65#define L2_LAN_IIH 16
66#define PTP_IIH 17
67#define L1_LS_PDU 18
68#define L2_LS_PDU 19
69#define L1_COMPLETE_SEQ_PDU 24
70#define L2_COMPLETE_SEQ_PDU 25
71
72/*
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.
76 */
77
78#define TLV_AREA_ADDR 1
79#define TLV_IS_REACH 2
80#define TLV_ES_REACH 3
81#define TLV_SUMMARY 5
82#define TLV_ISNEIGH 6
83#define TLV_PADDING 8
84#define TLV_LSP 9
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
93
94/*
95 * Katz's point to point adjacency TLV uses codes to tell us the state of
96 * the remote adjacency. Enumerate them.
97 */
98
99#define ISIS_PTP_ADJ_UP 0
100#define ISIS_PTP_ADJ_INIT 1
101#define ISIS_PTP_ADJ_DOWN 2
102
103static int osi_cksum(const u_char *, int, u_char *);
104static void esis_print(const u_char *, u_int);
105static int isis_print(const u_char *, u_int);
106
107
108struct isis_ptp_adjancey_values {
109 u_char id;
110 char *name;
111};
112
113static 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"
117};
118
119struct isis_common_header {
120 u_char nlpid;
121 u_char fixed_len;
122 u_char version; /* Protocol version? */
123 u_char id_length;
124 u_char enc_pdu_type; /* 3 MSbs are reserved */
125 u_char pkt_version; /* Packet format version? */
126 u_char reserved;
127 u_char enc_max_area;
128};
129
130struct isis_header {
131 u_char nlpid;
132 u_char fixed_len;
133 u_char version; /* Protocol version? */
134 u_char id_length;
135 u_char enc_pdu_type; /* 3 MSbs are reserved */
136 u_char pkt_version; /* Packet format version? */
137 u_char reserved;
138 u_char enc_max_area;
139 u_char circuit;
140 u_char enc_source_id[SYSTEM_ID_LEN];
141 u_char enc_holding_time[2];
142 u_char enc_packet_len[2];
143 u_char enc_priority;
144 u_char enc_lan_id[SYSTEM_ID_LEN+1];
145};
146struct isis_lan_header {
147 u_char circuit;
148 u_char enc_source_id[SYSTEM_ID_LEN];
149 u_char enc_holding_time[2];
150 u_char enc_packet_len[2];
151 u_char enc_priority;
152 u_char enc_lan_id[SYSTEM_ID_LEN+1];
153};
154
155struct isis_ptp_header {
156 u_char circuit;
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;
161};
162
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
170
171
172
173void
174isoclns_print(const u_char *p, u_int length, u_int caplen,
175 const u_char *esrc, const u_char *edst)
176{
177 u_char pdu_type;
178 struct isis_header *header;
179
180 header = (struct isis_header *)p;
181 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
182
183 if (caplen < 1) {
184 printf("[|iso-clns] ");
185 if (!eflag)
186 printf("%s > %s",
187 etheraddr_string(esrc),
188 etheraddr_string(edst));
189 return;
190 }
191
192 switch (*p) {
193
194 case NLPID_CLNS:
195 printf("iso clns");
196 if (!eflag)
197 (void)printf(" %s > %s",
198 etheraddr_string(esrc),
199 etheraddr_string(edst));
200 break;
201
202 case NLPID_ESIS:
203 printf("iso esis");
204 if (!eflag)
205 (void)printf(" %s > %s",
206 etheraddr_string(esrc),
207 etheraddr_string(edst));
208 esis_print(p, length);
209 return;
210
211 case NLPID_ISIS:
212 printf("iso isis");
213 if (!eflag) {
214 if(pdu_type != PTP_IIH)
215 (void)printf(" %s > %s",
216 etheraddr_string(esrc),
217 etheraddr_string(edst));
218 }
219 (void)printf(" len=%d ", length);
220 if (!isis_print(p, length))
221 default_print_unaligned(p, caplen);
222 break;
223
224 case NLPID_NULLNS:
225 printf("iso nullns");
226 if (!eflag)
227 (void)printf(" %s > %s",
228 etheraddr_string(esrc),
229 etheraddr_string(edst));
230 break;
231
232 default:
233 printf("iso clns %02x", p[0]);
234 if (!eflag)
235 (void)printf(" %s > %s",
236 etheraddr_string(esrc),
237 etheraddr_string(edst));
238 (void)printf(" len=%d ", length);
239 if (caplen > 1)
240 default_print_unaligned(p, caplen);
241 break;
242 }
243}
244
245#define ESIS_REDIRECT 6
246#define ESIS_ESH 2
247#define ESIS_ISH 4
248
249struct esis_hdr {
250 u_char version;
251 u_char reserved;
252 u_char type;
253 u_char tmo[2];
254 u_char cksum[2];
255};
256
257static void
258esis_print(const u_char *p, u_int length)
259{
260 const u_char *ep;
261 int li = p[1];
262 const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
263 u_char cksum[2];
264 u_char off[2];
265
266 if (length == 2) {
267 if (qflag)
268 printf(" bad pkt!");
269 else
270 printf(" no header at all!");
271 return;
272 }
273 ep = p + li;
274 if (li > length) {
275 if (qflag)
276 printf(" bad pkt!");
277 else
278 printf(" LI(%d) > PDU size (%d)!", li, length);
279 return;
280 }
281 if (li < sizeof(struct esis_hdr) + 2) {
282 if (qflag)
283 printf(" bad pkt!");
284 else {
285 printf(" too short for esis header %d:", li);
286 while (--length >= 0)
286 while (--length != 0)
287 printf("%02X", *p++);
288 }
289 return;
290 }
291 switch (eh->type & 0x1f) {
292
293 case ESIS_REDIRECT:
294 printf(" redirect");
295 break;
296
297 case ESIS_ESH:
298 printf(" esh");
299 break;
300
301 case ESIS_ISH:
302 printf(" ish");
303 break;
304
305 default:
306 printf(" type %d", eh->type & 0x1f);
307 break;
308 }
309 off[0] = eh->cksum[0];
310 off[1] = eh->cksum[1];
311 if (vflag && osi_cksum(p, li, off)) {
312 printf(" bad cksum (got %02x%02x)",
313 eh->cksum[1], eh->cksum[0]);
314 default_print(p, length);
315 return;
316 }
317 if (eh->version != 1) {
318 printf(" unsupported version %d", eh->version);
319 return;
320 }
321 p += sizeof(*eh) + 2;
322 li -= sizeof(*eh) + 2; /* protoid * li */
323
324 switch (eh->type & 0x1f) {
325 case ESIS_REDIRECT: {
326 const u_char *dst, *snpa, *is;
327
328 dst = p; p += *p + 1;
329 if (p > snapend)
330 return;
331 printf("\n\t\t\t %s", isonsap_string(dst));
332 snpa = p; p += *p + 1;
333 is = p; p += *p + 1;
334 if (p > snapend)
335 return;
336 if (p > ep) {
337 printf(" [bad li]");
338 return;
339 }
340 if (is[0] == 0)
341 printf(" > %s", etheraddr_string(&snpa[1]));
342 else
343 printf(" > %s", isonsap_string(is));
344 li = ep - p;
345 break;
346 }
347#if 0
348 case ESIS_ESH:
349 printf(" esh");
350 break;
351#endif
352 case ESIS_ISH: {
353 const u_char *is;
354
355 is = p; p += *p + 1;
356 if (p > ep) {
357 printf(" [bad li]");
358 return;
359 }
360 if (p > snapend)
361 return;
362 if (!qflag)
363 printf("\n\t\t\t %s", isonsap_string(is));
364 li = ep - p;
365 break;
366 }
367
368 default:
369 (void)printf(" len=%d", length);
370 if (length && p < snapend) {
371 length = snapend - p;
372 default_print(p, length);
373 }
374 return;
375 }
376 if (vflag)
377 while (p < ep && li) {
378 int op, opli;
379 const u_char *q;
380
381 if (snapend - p < 2)
382 return;
383 if (li < 2) {
384 printf(" bad opts/li");
385 return;
386 }
387 op = *p++;
388 opli = *p++;
389 li -= 2;
390 if (opli > li) {
391 printf(" opt (%d) too long", op);
392 return;
393 }
394 li -= opli;
395 q = p;
396 p += opli;
397 if (snapend < p)
398 return;
399 if (op == 198 && opli == 2) {
400 printf(" tmo=%d", q[0] * 256 + q[1]);
401 continue;
402 }
403 printf (" %d:<", op);
404 while (--opli >= 0)
405 printf("%02x", *q++);
406 printf (">");
407 }
408}
409
410/*
411 * print_nsap
412 * Print out an NSAP.
413 */
414
415void
416print_nsap (register const u_char *cp, register int length)
417{
418 int i;
419
420 for (i = 0; i < length; i++) {
421 printf("%02x", *cp++);
422 if (((i & 1) == 0) && (i + 1 < length)) {
423 printf(".");
424 }
425
426 }
427}
428
429/*
430 * isis_print
431 * Decode IS-IS packets. Return 0 on error.
432 *
433 * So far, this is only smart enough to print IIH's. Someday...
434 */
435
436static int
437isis_print (const u_char *p, u_int length)
438{
439 struct isis_header *header;
440 struct isis_ptp_header *header_ptp;
441 u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen;
442 u_short packet_len, holding_time;
443 int i;
444
445 header_ptp = (struct isis_ptp_header *)header = (struct isis_header *)p;
446 printf("\n\t\t\t");
447
448 /*
449 * Sanity checking of the header.
450 */
451 if (header->nlpid != NLPID_ISIS) {
452 printf(" coding error!");
453 return(0);
454 }
455
456 if (header->version != ISIS_VERSION) {
457 printf(" version %d packet not supported", header->version);
458 return(0);
459 }
460
461 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
462 printf(" system ID length of %d is not supported",
463 header->id_length);
464 return(0);
465 }
466
467 if ((header->fixed_len != ISIS_HEADER_SIZE) &&
468 (header->fixed_len != ISIS_PTP_HEADER_SIZE) &&
469 (header->fixed_len != L1_LS_PDU_HEADER_SIZE) &&
470 (header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) {
471 printf(" bogus fixed header length",
472 header->fixed_len);
473 return(0);
474 }
475
476 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
477 if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH) &&
478 (pdu_type != PTP_IIH) &&
479 (pdu_type != L1_COMPLETE_SEQ_PDU) &&
480 (pdu_type != L2_COMPLETE_SEQ_PDU) ) {
481 printf(" PDU type (%d) not supported", pdu_type);
482 return;
483 }
484
485 if (header->pkt_version != ISIS_VERSION) {
486 printf(" version %d packet not supported", header->pkt_version);
487 return;
488 }
489
490 max_area = header->enc_max_area;
491 switch(max_area) {
492 case 0:
493 max_area = 3; /* silly shit */
494 break;
495 case 255:
496 printf(" bad packet -- 255 areas");
497 return(0);
498 default:
499 break;
500 }
501
502 switch (header->circuit) {
503 case 0:
504 printf(" PDU with circuit type 0");
505 return(0);
506 case 1:
507 if (pdu_type == L2_LAN_IIH) {
508 printf(" L2 IIH on an L1 only circuit");
509 return(0);
510 }
511 break;
512 case 2:
513 if (pdu_type == L1_LAN_IIH) {
514 printf(" L1 IIH on an L2 only circuit");
515 return(0);
516 }
517 break;
518 case 3:
519 break;
520 default:
521 printf(" unknown circuit type");
522 return(0);
523 }
524
525 holding_time = EXTRACT_16BITS(header->enc_holding_time);
526
527 packet_len = EXTRACT_16BITS(header->enc_packet_len);
528 if ((packet_len < ISIS_HEADER_SIZE) ||
529 (packet_len > length)) {
530 printf(" bogus packet length %d, real length %d", packet_len,
531 length);
532 return(0);
533 }
534
535 if(pdu_type != PTP_IIH)
536 priority = header->enc_priority & PRIORITY_MASK;
537
538 /*
539 * Now print the fixed header.
540 */
541 switch (pdu_type) {
542 case L1_LAN_IIH:
543 printf(" L1 lan iih, ");
544 break;
545 case L2_LAN_IIH:
546 printf(" L2 lan iih, ");
547 break;
548 case PTP_IIH:
549 printf(" PTP iih, ");
550 break;
551 }
552
553 printf("circuit ");
554 switch (header->circuit) {
555 case 1:
556 printf("l1 only, ");
557 break;
558 case 2:
559 printf("l2 only, ");
560 break;
561 case 3:
562 printf("l1-l2, ");
563 break;
564 }
565
566 printf ("holding time %d ", holding_time);
567 printf ("\n\t\t\t source %s, length %d",
568 etheraddr_string(header->enc_source_id), packet_len);
569 if((pdu_type==L1_LAN_IIH)||(pdu_type==L2_LAN_IIH))
570 printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id),
571 header->enc_lan_id[SYSTEM_ID_LEN]);
572
573 /*
574 * Now print the TLV's.
575 */
576 if(pdu_type==PTP_IIH) {
577 packet_len -= ISIS_PTP_HEADER_SIZE;
578 pptr = (char *)p + ISIS_PTP_HEADER_SIZE;
579 } else {
580 packet_len -= ISIS_HEADER_SIZE;
581 pptr = (char *)p + ISIS_HEADER_SIZE;
582 }
583 while (packet_len >= 2) {
584 if (pptr >= snapend) {
585 printf("\n\t\t\t packet exceeded snapshot");
586 return(1);
587 }
588 type = *pptr++;
589 len = *pptr++;
590 packet_len -= 2;
591 if (len > packet_len) {
592 break;
593 }
594
595 switch (type) {
596 case TLV_AREA_ADDR:
597 printf("\n\t\t\t area addresses");
598 tmp = len;
599 tptr = pptr;
600 alen = *tptr++;
601 while (tmp && alen < tmp) {
602 printf("\n\t\t\t ");
603 print_nsap(tptr, alen);
604 printf(" (%d)", alen);
605 tptr += alen;
606 tmp -= alen + 1;
607 alen = *tptr++;
608 }
609 break;
610 case TLV_ISNEIGH:
611 printf("\n\t\t\t neighbor addresses");
612 tmp = len;
613 tptr = pptr;
614 while (tmp >= sizeof(struct ether_addr)) {
615 printf("\n\t\t\t %s", etheraddr_string(tptr));
616 tmp -= sizeof(struct ether_addr);
617 tptr += sizeof(struct ether_addr);
618 }
619 break;
620 case TLV_PADDING:
621 printf("\n\t\t\t padding for %d bytes", len);
622 break;
623 case TLV_AUTHENT:
624 printf("\n\t\t\t authentication data");
625 default_print(pptr, len);
626 break;
627 case TLV_PTP_ADJ:
628 printf("\n\t\t\t PTP adjacency status %s",
629 isis_ptp_adjancey_values[*pptr].name);
630 break;
631 case TLV_PROTOCOLS:
632 printf("\n\t\t\t Supports protocols %s", (len>1)? "are":"is");
633 for(i=0;i<len;i++)
634 printf(" %02X", (u_char)*(pptr+i));
635 break;
636 case TLV_IPADDR:
637 printf("\n\t\t\t IP address: %s", ipaddr_string(pptr));
638 break;
639 default:
640 printf("\n\t\t\t unknown TLV, type %d, length %d", type, len);
641 break;
642 }
643
644 pptr += len;
645 packet_len -= len;
646 }
647
648 if (packet_len != 0) {
649 printf("\n\t\t\t %d straggler bytes", packet_len);
650 }
651 return(1);
652}
653
654/*
655 * Verify the checksum. See 8473-1, Appendix C, section C.4.
656 */
657
658static int
659osi_cksum(register const u_char *p, register int len, u_char *off)
660{
661 int32_t c0 = 0, c1 = 0;
662
663 if ((off[0] == 0) && (off[1] == 0))
664 return 0;
665
287 printf("%02X", *p++);
288 }
289 return;
290 }
291 switch (eh->type & 0x1f) {
292
293 case ESIS_REDIRECT:
294 printf(" redirect");
295 break;
296
297 case ESIS_ESH:
298 printf(" esh");
299 break;
300
301 case ESIS_ISH:
302 printf(" ish");
303 break;
304
305 default:
306 printf(" type %d", eh->type & 0x1f);
307 break;
308 }
309 off[0] = eh->cksum[0];
310 off[1] = eh->cksum[1];
311 if (vflag && osi_cksum(p, li, off)) {
312 printf(" bad cksum (got %02x%02x)",
313 eh->cksum[1], eh->cksum[0]);
314 default_print(p, length);
315 return;
316 }
317 if (eh->version != 1) {
318 printf(" unsupported version %d", eh->version);
319 return;
320 }
321 p += sizeof(*eh) + 2;
322 li -= sizeof(*eh) + 2; /* protoid * li */
323
324 switch (eh->type & 0x1f) {
325 case ESIS_REDIRECT: {
326 const u_char *dst, *snpa, *is;
327
328 dst = p; p += *p + 1;
329 if (p > snapend)
330 return;
331 printf("\n\t\t\t %s", isonsap_string(dst));
332 snpa = p; p += *p + 1;
333 is = p; p += *p + 1;
334 if (p > snapend)
335 return;
336 if (p > ep) {
337 printf(" [bad li]");
338 return;
339 }
340 if (is[0] == 0)
341 printf(" > %s", etheraddr_string(&snpa[1]));
342 else
343 printf(" > %s", isonsap_string(is));
344 li = ep - p;
345 break;
346 }
347#if 0
348 case ESIS_ESH:
349 printf(" esh");
350 break;
351#endif
352 case ESIS_ISH: {
353 const u_char *is;
354
355 is = p; p += *p + 1;
356 if (p > ep) {
357 printf(" [bad li]");
358 return;
359 }
360 if (p > snapend)
361 return;
362 if (!qflag)
363 printf("\n\t\t\t %s", isonsap_string(is));
364 li = ep - p;
365 break;
366 }
367
368 default:
369 (void)printf(" len=%d", length);
370 if (length && p < snapend) {
371 length = snapend - p;
372 default_print(p, length);
373 }
374 return;
375 }
376 if (vflag)
377 while (p < ep && li) {
378 int op, opli;
379 const u_char *q;
380
381 if (snapend - p < 2)
382 return;
383 if (li < 2) {
384 printf(" bad opts/li");
385 return;
386 }
387 op = *p++;
388 opli = *p++;
389 li -= 2;
390 if (opli > li) {
391 printf(" opt (%d) too long", op);
392 return;
393 }
394 li -= opli;
395 q = p;
396 p += opli;
397 if (snapend < p)
398 return;
399 if (op == 198 && opli == 2) {
400 printf(" tmo=%d", q[0] * 256 + q[1]);
401 continue;
402 }
403 printf (" %d:<", op);
404 while (--opli >= 0)
405 printf("%02x", *q++);
406 printf (">");
407 }
408}
409
410/*
411 * print_nsap
412 * Print out an NSAP.
413 */
414
415void
416print_nsap (register const u_char *cp, register int length)
417{
418 int i;
419
420 for (i = 0; i < length; i++) {
421 printf("%02x", *cp++);
422 if (((i & 1) == 0) && (i + 1 < length)) {
423 printf(".");
424 }
425
426 }
427}
428
429/*
430 * isis_print
431 * Decode IS-IS packets. Return 0 on error.
432 *
433 * So far, this is only smart enough to print IIH's. Someday...
434 */
435
436static int
437isis_print (const u_char *p, u_int length)
438{
439 struct isis_header *header;
440 struct isis_ptp_header *header_ptp;
441 u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen;
442 u_short packet_len, holding_time;
443 int i;
444
445 header_ptp = (struct isis_ptp_header *)header = (struct isis_header *)p;
446 printf("\n\t\t\t");
447
448 /*
449 * Sanity checking of the header.
450 */
451 if (header->nlpid != NLPID_ISIS) {
452 printf(" coding error!");
453 return(0);
454 }
455
456 if (header->version != ISIS_VERSION) {
457 printf(" version %d packet not supported", header->version);
458 return(0);
459 }
460
461 if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
462 printf(" system ID length of %d is not supported",
463 header->id_length);
464 return(0);
465 }
466
467 if ((header->fixed_len != ISIS_HEADER_SIZE) &&
468 (header->fixed_len != ISIS_PTP_HEADER_SIZE) &&
469 (header->fixed_len != L1_LS_PDU_HEADER_SIZE) &&
470 (header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) {
471 printf(" bogus fixed header length",
472 header->fixed_len);
473 return(0);
474 }
475
476 pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
477 if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH) &&
478 (pdu_type != PTP_IIH) &&
479 (pdu_type != L1_COMPLETE_SEQ_PDU) &&
480 (pdu_type != L2_COMPLETE_SEQ_PDU) ) {
481 printf(" PDU type (%d) not supported", pdu_type);
482 return;
483 }
484
485 if (header->pkt_version != ISIS_VERSION) {
486 printf(" version %d packet not supported", header->pkt_version);
487 return;
488 }
489
490 max_area = header->enc_max_area;
491 switch(max_area) {
492 case 0:
493 max_area = 3; /* silly shit */
494 break;
495 case 255:
496 printf(" bad packet -- 255 areas");
497 return(0);
498 default:
499 break;
500 }
501
502 switch (header->circuit) {
503 case 0:
504 printf(" PDU with circuit type 0");
505 return(0);
506 case 1:
507 if (pdu_type == L2_LAN_IIH) {
508 printf(" L2 IIH on an L1 only circuit");
509 return(0);
510 }
511 break;
512 case 2:
513 if (pdu_type == L1_LAN_IIH) {
514 printf(" L1 IIH on an L2 only circuit");
515 return(0);
516 }
517 break;
518 case 3:
519 break;
520 default:
521 printf(" unknown circuit type");
522 return(0);
523 }
524
525 holding_time = EXTRACT_16BITS(header->enc_holding_time);
526
527 packet_len = EXTRACT_16BITS(header->enc_packet_len);
528 if ((packet_len < ISIS_HEADER_SIZE) ||
529 (packet_len > length)) {
530 printf(" bogus packet length %d, real length %d", packet_len,
531 length);
532 return(0);
533 }
534
535 if(pdu_type != PTP_IIH)
536 priority = header->enc_priority & PRIORITY_MASK;
537
538 /*
539 * Now print the fixed header.
540 */
541 switch (pdu_type) {
542 case L1_LAN_IIH:
543 printf(" L1 lan iih, ");
544 break;
545 case L2_LAN_IIH:
546 printf(" L2 lan iih, ");
547 break;
548 case PTP_IIH:
549 printf(" PTP iih, ");
550 break;
551 }
552
553 printf("circuit ");
554 switch (header->circuit) {
555 case 1:
556 printf("l1 only, ");
557 break;
558 case 2:
559 printf("l2 only, ");
560 break;
561 case 3:
562 printf("l1-l2, ");
563 break;
564 }
565
566 printf ("holding time %d ", holding_time);
567 printf ("\n\t\t\t source %s, length %d",
568 etheraddr_string(header->enc_source_id), packet_len);
569 if((pdu_type==L1_LAN_IIH)||(pdu_type==L2_LAN_IIH))
570 printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id),
571 header->enc_lan_id[SYSTEM_ID_LEN]);
572
573 /*
574 * Now print the TLV's.
575 */
576 if(pdu_type==PTP_IIH) {
577 packet_len -= ISIS_PTP_HEADER_SIZE;
578 pptr = (char *)p + ISIS_PTP_HEADER_SIZE;
579 } else {
580 packet_len -= ISIS_HEADER_SIZE;
581 pptr = (char *)p + ISIS_HEADER_SIZE;
582 }
583 while (packet_len >= 2) {
584 if (pptr >= snapend) {
585 printf("\n\t\t\t packet exceeded snapshot");
586 return(1);
587 }
588 type = *pptr++;
589 len = *pptr++;
590 packet_len -= 2;
591 if (len > packet_len) {
592 break;
593 }
594
595 switch (type) {
596 case TLV_AREA_ADDR:
597 printf("\n\t\t\t area addresses");
598 tmp = len;
599 tptr = pptr;
600 alen = *tptr++;
601 while (tmp && alen < tmp) {
602 printf("\n\t\t\t ");
603 print_nsap(tptr, alen);
604 printf(" (%d)", alen);
605 tptr += alen;
606 tmp -= alen + 1;
607 alen = *tptr++;
608 }
609 break;
610 case TLV_ISNEIGH:
611 printf("\n\t\t\t neighbor addresses");
612 tmp = len;
613 tptr = pptr;
614 while (tmp >= sizeof(struct ether_addr)) {
615 printf("\n\t\t\t %s", etheraddr_string(tptr));
616 tmp -= sizeof(struct ether_addr);
617 tptr += sizeof(struct ether_addr);
618 }
619 break;
620 case TLV_PADDING:
621 printf("\n\t\t\t padding for %d bytes", len);
622 break;
623 case TLV_AUTHENT:
624 printf("\n\t\t\t authentication data");
625 default_print(pptr, len);
626 break;
627 case TLV_PTP_ADJ:
628 printf("\n\t\t\t PTP adjacency status %s",
629 isis_ptp_adjancey_values[*pptr].name);
630 break;
631 case TLV_PROTOCOLS:
632 printf("\n\t\t\t Supports protocols %s", (len>1)? "are":"is");
633 for(i=0;i<len;i++)
634 printf(" %02X", (u_char)*(pptr+i));
635 break;
636 case TLV_IPADDR:
637 printf("\n\t\t\t IP address: %s", ipaddr_string(pptr));
638 break;
639 default:
640 printf("\n\t\t\t unknown TLV, type %d, length %d", type, len);
641 break;
642 }
643
644 pptr += len;
645 packet_len -= len;
646 }
647
648 if (packet_len != 0) {
649 printf("\n\t\t\t %d straggler bytes", packet_len);
650 }
651 return(1);
652}
653
654/*
655 * Verify the checksum. See 8473-1, Appendix C, section C.4.
656 */
657
658static int
659osi_cksum(register const u_char *p, register int len, u_char *off)
660{
661 int32_t c0 = 0, c1 = 0;
662
663 if ((off[0] == 0) && (off[1] == 0))
664 return 0;
665
666 while (--len >= 0) {
666 off[0] = off[1] = 0;
667 while ((int)--len >= 0) {
667 c0 += *p++;
668 c0 %= 255;
669 c1 += c0;
670 c1 %= 255;
671 }
672 return (c0 | c1);
673}
668 c0 += *p++;
669 c0 %= 255;
670 c1 += c0;
671 c1 %= 255;
672 }
673 return (c0 | c1);
674}