GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-isoclns.c Lines: 0 165 0.0 %
Date: 2017-11-07 Branches: 0 108 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-isoclns.c,v 1.13 2015/11/16 00:16:39 mmcc Exp $	*/
2
3
/*
4
 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that: (1) source code distributions
9
 * retain the above copyright notice and this paragraph in its entirety, (2)
10
 * distributions including binary code include the above copyright notice and
11
 * this paragraph in its entirety in the documentation or other materials
12
 * provided with the distribution, and (3) all advertising materials mentioning
13
 * features or use of this software display the following acknowledgement:
14
 * ``This product includes software developed by the University of California,
15
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16
 * the University nor the names of its contributors may be used to endorse
17
 * or promote products derived from this software without specific prior
18
 * written permission.
19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
 *
23
 * Original code by Matt Thomas, Digital Equipment Corporation
24
 */
25
26
#include <sys/types.h>
27
#include <sys/time.h>
28
#include <sys/socket.h>
29
30
struct mbuf;
31
struct rtentry;
32
#include <net/if.h>
33
34
#include <netinet/in.h>
35
#include <netinet/if_ether.h>
36
37
#include <stdio.h>
38
39
#include "interface.h"
40
#include "addrtoname.h"
41
#include "ethertype.h"
42
43
#define	CLNS	129
44
#define	ESIS	130
45
#define	ISIS	131
46
#define	NULLNS	0
47
48
static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
49
static void esis_print(const u_char *, u_int);
50
51
void
52
isoclns_print(const u_char *p, u_int length, u_int caplen,
53
	      const u_char *esrc, const u_char *edst)
54
{
55
	if (caplen < 1) {
56
		printf("[|iso-clns] ");
57
		if (!eflag)
58
			printf("%s > %s",
59
			       etheraddr_string(esrc),
60
			       etheraddr_string(edst));
61
		return;
62
	}
63
64
	switch (*p) {
65
66
	case CLNS:
67
		/* esis_print(&p, &length); */
68
		printf("iso-clns");
69
		if (!eflag)
70
			(void)printf(" %s > %s",
71
				     etheraddr_string(esrc),
72
				     etheraddr_string(edst));
73
		break;
74
75
	case ESIS:
76
		printf("iso-esis");
77
		if (!eflag)
78
			(void)printf(" %s > %s",
79
				     etheraddr_string(esrc),
80
				     etheraddr_string(edst));
81
		esis_print(p, length);
82
		return;
83
84
	case ISIS:
85
		printf("iso-isis");
86
		if (!eflag)
87
			(void)printf(" %s > %s",
88
				     etheraddr_string(esrc),
89
				     etheraddr_string(edst));
90
		/* isis_print(&p, &length); */
91
		(void)printf(" len=%d ", length);
92
		if (caplen > 1)
93
			default_print_unaligned(p, caplen);
94
		break;
95
96
	case NULLNS:
97
		printf("iso-nullns");
98
		if (!eflag)
99
			(void)printf(" %s > %s",
100
				     etheraddr_string(esrc),
101
				     etheraddr_string(edst));
102
		break;
103
104
	default:
105
		printf("iso-clns %02x", p[0]);
106
		if (!eflag)
107
			(void)printf(" %s > %s",
108
				     etheraddr_string(esrc),
109
				     etheraddr_string(edst));
110
		(void)printf(" len=%d ", length);
111
		if (caplen > 1)
112
			default_print_unaligned(p, caplen);
113
		break;
114
	}
115
}
116
117
#define	ESIS_REDIRECT	6
118
#define	ESIS_ESH	2
119
#define	ESIS_ISH	4
120
121
struct esis_hdr {
122
	u_char version;
123
	u_char reserved;
124
	u_char type;
125
	u_char tmo[2];
126
	u_char cksum[2];
127
};
128
129
static void
130
esis_print(const u_char *p, u_int length)
131
{
132
	const u_char *ep;
133
	int li = p[1];
134
	const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
135
	u_char cksum[2];
136
	u_char off[2];
137
138
	if (length == 2) {
139
		if (qflag)
140
			printf(" bad pkt!");
141
		else
142
			printf(" no header at all!");
143
		return;
144
	}
145
	ep = p + li;
146
	if (li > length) {
147
		if (qflag)
148
			printf(" bad pkt!");
149
		else
150
			printf(" LI(%d) > PDU size (%d)!", li, length);
151
		return;
152
	}
153
	if (li < sizeof(struct esis_hdr) + 2) {
154
		if (qflag)
155
			printf(" bad pkt!");
156
		else {
157
			printf(" too short for esis header %d:", li);
158
			while (--length != 0)
159
				printf("%02X", *p++);
160
		}
161
		return;
162
	}
163
	switch (eh->type & 0x1f) {
164
165
	case ESIS_REDIRECT:
166
		printf(" redirect");
167
		break;
168
169
	case ESIS_ESH:
170
		printf(" esh");
171
		break;
172
173
	case ESIS_ISH:
174
		printf(" ish");
175
		break;
176
177
	default:
178
		printf(" type %d", eh->type & 0x1f);
179
		break;
180
	}
181
	off[0] = eh->cksum[0];
182
	off[1] = eh->cksum[1];
183
	if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
184
		printf(" bad cksum (got %02x%02x want %02x%02x)",
185
		       eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
186
		return;
187
	}
188
	if (eh->version != 1) {
189
		printf(" unsupported version %d", eh->version);
190
		return;
191
	}
192
	p += sizeof(*eh) + 2;
193
	li -= sizeof(*eh) + 2;	/* protoid * li */
194
195
	switch (eh->type & 0x1f) {
196
	case ESIS_REDIRECT: {
197
		const u_char *dst, *snpa, *is;
198
199
		dst = p; p += *p + 1;
200
		if (p > snapend)
201
			return;
202
		printf(" %s", isonsap_string(dst));
203
		snpa = p; p += *p + 1;
204
		is = p;   p += *p + 1;
205
		if (p > snapend)
206
			return;
207
		if (p > ep) {
208
			printf(" [bad li]");
209
			return;
210
		}
211
		if (is[0] == 0)
212
			printf(" > %s", etheraddr_string(&snpa[1]));
213
		else
214
			printf(" > %s", isonsap_string(is));
215
		li = ep - p;
216
		break;
217
	}
218
	case ESIS_ESH: {
219
		const u_char *nsap;
220
		int i, nnsaps;
221
222
		nnsaps = *p++;
223
224
		/* print NSAPs */
225
		for (i = 0; i < nnsaps; i++) {
226
			nsap = p;
227
			p += *p + 1;
228
			if (p > ep) {
229
				printf(" [bad li]");
230
				return;
231
			}
232
			if (p > snapend)
233
				return;
234
			printf(" nsap %s", isonsap_string(nsap));
235
		}
236
		li = ep - p;
237
		break;
238
	}
239
	case ESIS_ISH: {
240
		const u_char *is;
241
242
		is = p; p += *p + 1;
243
		if (p > ep) {
244
			printf(" [bad li]");
245
			return;
246
		}
247
		if (p > snapend)
248
			return;
249
		printf(" net %s", isonsap_string(is));
250
		li = ep - p;
251
		break;
252
	}
253
254
	default:
255
		(void)printf(" len=%d", length);
256
		if (length && p < snapend) {
257
			length = snapend - p;
258
			default_print(p, length);
259
		}
260
		return;
261
	}
262
	if (vflag)
263
		while (p < ep && li) {
264
			int op, opli;
265
			const u_char *q;
266
267
			if (snapend - p < 2)
268
				return;
269
			if (li < 2) {
270
				printf(" bad opts/li");
271
				return;
272
			}
273
			op = *p++;
274
			opli = *p++;
275
			li -= 2;
276
			if (opli > li) {
277
				printf(" opt (%d) too long", op);
278
				return;
279
			}
280
			li -= opli;
281
			q = p;
282
			p += opli;
283
			if (snapend < p)
284
				return;
285
			if (op == 198 && opli == 2) {
286
				printf(" tmo=%d", q[0] * 256 + q[1]);
287
				continue;
288
			}
289
			printf (" %d:<", op);
290
			while (--opli >= 0)
291
				printf("%02x", *q++);
292
			printf (">");
293
		}
294
}
295
296
static int
297
osi_cksum(const u_char *p, u_int len,
298
	  const u_char *toff, u_char *cksum, u_char *off)
299
{
300
	const u_char *ep;
301
	int c0, c1;
302
	int n;
303
304
	if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
305
		return 0;
306
307
	n = toff - p + 1;
308
	c0 = c1 = 0;
309
	ep = p + len;
310
	for (; p < toff; p++) {
311
		c0 = (c0 + *p);
312
		c1 += c0;
313
	}
314
315
	/* skip cksum bytes */
316
	p += 2;
317
	c1 += c0; c1 += c0;
318
319
	for (; p < ep; p++) {
320
		c0 = (c0 + *p);
321
		c1 += c0;
322
	}
323
324
	c1 = (((c0 * (len - n)) - c1) % 255);
325
	cksum[0] = (u_char) ((c1 < 0) ? c1 + 255 : c1);
326
	c1 = (-(int) (c1 + c0)) % 255;
327
	cksum[1] = (u_char) (c1 < 0 ? c1 + 255 : c1);
328
329
	return (off[0] != cksum[0] || off[1] != cksum[1]);
330
}