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