]> The Tcpdump Group git mirrors - tcpdump/blob - print-isoclns.c
Fix a typo.
[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
24 #ifndef lint
25 static const char rcsid[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.17 2000-07-01 03:39:06 assar Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <sys/types.h>
34 #include <sys/time.h>
35 #include <sys/socket.h>
36
37 struct mbuf;
38 struct rtentry;
39 #include <net/if.h>
40
41 #include <netinet/in.h>
42 #include <netinet/if_ether.h>
43
44 #include <stdio.h>
45
46 #include "interface.h"
47 #include "addrtoname.h"
48 #include "ethertype.h"
49
50 #define CLNS 129
51 #define ESIS 130
52 #define ISIS 131
53 #define NULLNS 0
54
55 static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
56 static void esis_print(const u_char *, u_int);
57
58 void
59 isoclns_print(const u_char *p, u_int length, u_int caplen,
60 const u_char *esrc, const u_char *edst)
61 {
62 if (caplen < 1) {
63 printf("[|iso-clns] ");
64 if (!eflag)
65 printf("%s > %s",
66 etheraddr_string(esrc),
67 etheraddr_string(edst));
68 return;
69 }
70
71 switch (*p) {
72
73 case CLNS:
74 /* esis_print(&p, &length); */
75 printf("iso-clns");
76 if (!eflag)
77 (void)printf(" %s > %s",
78 etheraddr_string(esrc),
79 etheraddr_string(edst));
80 break;
81
82 case ESIS:
83 printf("iso-esis");
84 if (!eflag)
85 (void)printf(" %s > %s",
86 etheraddr_string(esrc),
87 etheraddr_string(edst));
88 esis_print(p, length);
89 return;
90
91 case ISIS:
92 printf("iso-isis");
93 if (!eflag)
94 (void)printf(" %s > %s",
95 etheraddr_string(esrc),
96 etheraddr_string(edst));
97 /* isis_print(&p, &length); */
98 (void)printf(" len=%d ", length);
99 if (caplen > 1)
100 default_print_unaligned(p, caplen);
101 break;
102
103 case NULLNS:
104 printf("iso-nullns");
105 if (!eflag)
106 (void)printf(" %s > %s",
107 etheraddr_string(esrc),
108 etheraddr_string(edst));
109 break;
110
111 default:
112 printf("iso-clns %02x", p[0]);
113 if (!eflag)
114 (void)printf(" %s > %s",
115 etheraddr_string(esrc),
116 etheraddr_string(edst));
117 (void)printf(" len=%d ", length);
118 if (caplen > 1)
119 default_print_unaligned(p, caplen);
120 break;
121 }
122 }
123
124 #define ESIS_REDIRECT 6
125 #define ESIS_ESH 2
126 #define ESIS_ISH 4
127
128 struct esis_hdr {
129 u_char version;
130 u_char reserved;
131 u_char type;
132 u_char tmo[2];
133 u_char cksum[2];
134 };
135
136 static void
137 esis_print(const u_char *p, u_int length)
138 {
139 const u_char *ep;
140 int li = p[1];
141 const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
142 u_char cksum[2];
143 u_char off[2];
144
145 if (length == 2) {
146 if (qflag)
147 printf(" bad pkt!");
148 else
149 printf(" no header at all!");
150 return;
151 }
152 ep = p + li;
153 if (li > length) {
154 if (qflag)
155 printf(" bad pkt!");
156 else
157 printf(" LI(%d) > PDU size (%d)!", li, length);
158 return;
159 }
160 if (li < sizeof(struct esis_hdr) + 2) {
161 if (qflag)
162 printf(" bad pkt!");
163 else {
164 printf(" too short for esis header %d:", li);
165 while (--length != 0)
166 printf("%02X", *p++);
167 }
168 return;
169 }
170 switch (eh->type & 0x1f) {
171
172 case ESIS_REDIRECT:
173 printf(" redirect");
174 break;
175
176 case ESIS_ESH:
177 printf(" esh");
178 break;
179
180 case ESIS_ISH:
181 printf(" ish");
182 break;
183
184 default:
185 printf(" type %d", eh->type & 0x1f);
186 break;
187 }
188 off[0] = eh->cksum[0];
189 off[1] = eh->cksum[1];
190 if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
191 printf(" bad cksum (got %02x%02x want %02x%02x)",
192 eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
193 return;
194 }
195 if (eh->version != 1) {
196 printf(" unsupported version %d", eh->version);
197 return;
198 }
199 p += sizeof(*eh) + 2;
200 li -= sizeof(*eh) + 2; /* protoid * li */
201
202 switch (eh->type & 0x1f) {
203 case ESIS_REDIRECT: {
204 const u_char *dst, *snpa, *is;
205
206 dst = p; p += *p + 1;
207 if (p > snapend)
208 return;
209 printf(" %s", isonsap_string(dst));
210 snpa = p; p += *p + 1;
211 is = p; p += *p + 1;
212 if (p > snapend)
213 return;
214 if (p > ep) {
215 printf(" [bad li]");
216 return;
217 }
218 if (is[0] == 0)
219 printf(" > %s", etheraddr_string(&snpa[1]));
220 else
221 printf(" > %s", isonsap_string(is));
222 li = ep - p;
223 break;
224 }
225 #if 0
226 case ESIS_ESH:
227 printf(" esh");
228 break;
229 #endif
230 case ESIS_ISH: {
231 const u_char *is;
232
233 is = p; p += *p + 1;
234 if (p > ep) {
235 printf(" [bad li]");
236 return;
237 }
238 if (p > snapend)
239 return;
240 printf(" %s", isonsap_string(is));
241 li = ep - p;
242 break;
243 }
244
245 default:
246 (void)printf(" len=%d", length);
247 if (length && p < snapend) {
248 length = snapend - p;
249 default_print(p, length);
250 }
251 return;
252 }
253 if (vflag)
254 while (p < ep && li) {
255 int op, opli;
256 const u_char *q;
257
258 if (snapend - p < 2)
259 return;
260 if (li < 2) {
261 printf(" bad opts/li");
262 return;
263 }
264 op = *p++;
265 opli = *p++;
266 li -= 2;
267 if (opli > li) {
268 printf(" opt (%d) too long", op);
269 return;
270 }
271 li -= opli;
272 q = p;
273 p += opli;
274 if (snapend < p)
275 return;
276 if (op == 198 && opli == 2) {
277 printf(" tmo=%d", q[0] * 256 + q[1]);
278 continue;
279 }
280 printf (" %d:<", op);
281 while (--opli >= 0)
282 printf("%02x", *q++);
283 printf (">");
284 }
285 }
286
287 static int
288 osi_cksum(register const u_char *p, register u_int len,
289 const u_char *toff, u_char *cksum, u_char *off)
290 {
291 int x, y, f = (len - ((toff - p) + 1));
292 int32_t c0 = 0, c1 = 0;
293
294 if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
295 return 0;
296
297 off[0] = off[1] = 0;
298 while ((int)--len >= 0) {
299 c0 += *p++;
300 c1 += c0;
301 c0 %= 255;
302 c1 %= 255;
303 }
304 x = (c0 * f - c1);
305 if (x < 0)
306 x = 255 - (-x % 255);
307 else
308 x %= 255;
309 y = -1 * (x + c0);
310 if (y < 0)
311 y = 255 - (-y % 255);
312 else
313 y %= 255;
314
315 off[0] = x;
316 off[1] = y;
317
318 return (off[0] != cksum[0] || off[1] != cksum[1]);
319 }