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

Line Branch Exec Source
1
/*	$OpenBSD: print-fddi.c,v 1.17 2015/11/16 00:16:39 mmcc Exp $	*/
2
3
/*
4
 * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
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
24
#ifdef HAVE_FDDI
25
#include <sys/time.h>
26
#include <sys/socket.h>
27
#include <sys/file.h>
28
#include <sys/ioctl.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
#include <netinet/ip.h>
37
38
#include <ctype.h>
39
#include <netdb.h>
40
#include <pcap.h>
41
#include <stdio.h>
42
#include <string.h>
43
44
#include "interface.h"
45
#include "addrtoname.h"
46
#include "ethertype.h"
47
48
#include "fddi.h"
49
50
/*
51
 * Some FDDI interfaces use bit-swapped addresses.
52
 */
53
#if defined(ultrix) || defined(__alpha) || defined(__bsdi) || \
54
	defined(__NetBSD__) || defined(__OpenBSD__)
55
int	fddi_bitswap = 0;
56
#else
57
int	fddi_bitswap = 1;
58
#endif
59
60
/*
61
 * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
62
 *
63
 * Based in part on code by Van Jacobson, which bears this note:
64
 *
65
 * NOTE:  This is a very preliminary hack for FDDI support.
66
 * There are all sorts of wired in constants & nothing (yet)
67
 * to print SMT packets as anything other than hex dumps.
68
 * Most of the necessary changes are waiting on my redoing
69
 * the "header" that a kernel fddi driver supplies to bpf:  I
70
 * want it to look like one byte of 'direction' (0 or 1
71
 * depending on whether the packet was inbound or outbound),
72
 * two bytes of system/driver dependent data (anything an
73
 * implementor thinks would be useful to filter on and/or
74
 * save per-packet, then the real 21-byte FDDI header.
75
 * Steve McCanne & I have also talked about adding the
76
 * 'direction' byte to all bpf headers (e.g., in the two
77
 * bytes of padding on an ethernet header).  It's not clear
78
 * we could do this in a backwards compatible way & we hate
79
 * the idea of an incompatible bpf change.  Discussions are
80
 * proceeding.
81
 *
82
 * Also, to really support FDDI (and better support 802.2
83
 * over ethernet) we really need to re-think the rather simple
84
 * minded assumptions about fixed length & fixed format link
85
 * level headers made in gencode.c.  One day...
86
 *
87
 *  - vj
88
 */
89
90
#define FDDI_HDRLEN (sizeof(struct fddi_header))
91
92
static u_char fddi_bit_swap[] = {
93
	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
94
	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
95
	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
96
	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
97
	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
98
	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
99
	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
100
	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
101
	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
102
	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
103
	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
104
	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
105
	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
106
	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
107
	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
108
	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
109
	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
110
	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
111
	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
112
	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
113
	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
114
	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
115
	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
116
	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
117
	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
118
	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
119
	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
120
	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
121
	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
122
	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
123
	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
124
	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
125
};
126
127
/*
128
 * Print FDDI frame-control bits
129
 */
130
static inline void
131
print_fddi_fc(u_char fc)
132
{
133
	switch (fc) {
134
135
	case FDDIFC_VOID:                         /* Void frame */
136
		printf("void ");
137
		break;
138
139
	case FDDIFC_NRT:                          /* Nonrestricted token */
140
		printf("nrt ");
141
		break;
142
143
	case FDDIFC_RT:                           /* Restricted token */
144
		printf("rt ");
145
		break;
146
147
	case FDDIFC_SMT_INFO:                     /* SMT Info */
148
		printf("info ");
149
		break;
150
151
	case FDDIFC_SMT_NSA:                      /* SMT Next station adrs */
152
		printf("nsa ");
153
		break;
154
155
	case FDDIFC_MAC_BEACON:                   /* MAC Beacon frame */
156
		printf("beacon ");
157
		break;
158
159
	case FDDIFC_MAC_CLAIM:                    /* MAC Claim frame */
160
		printf("claim ");
161
		break;
162
163
	default:
164
		switch (fc & FDDIFC_CLFF) {
165
166
		case FDDIFC_MAC:
167
			printf("mac%1x ", fc & FDDIFC_ZZZZ);
168
			break;
169
170
		case FDDIFC_SMT:
171
			printf("smt%1x ", fc & FDDIFC_ZZZZ);
172
			break;
173
174
		case FDDIFC_LLC_ASYNC:
175
			printf("async%1x ", fc & FDDIFC_ZZZZ);
176
			break;
177
178
		case FDDIFC_LLC_SYNC:
179
			printf("sync%1x ", fc & FDDIFC_ZZZZ);
180
			break;
181
182
		case FDDIFC_IMP_ASYNC:
183
			printf("imp_async%1x ", fc & FDDIFC_ZZZZ);
184
			break;
185
186
		case FDDIFC_IMP_SYNC:
187
			printf("imp_sync%1x ", fc & FDDIFC_ZZZZ);
188
			break;
189
190
		default:
191
			printf("%02x ", fc);
192
			break;
193
		}
194
	}
195
}
196
197
/* Extract src, dst addresses */
198
static inline void
199
extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
200
{
201
	int i;
202
203
	if (fddi_bitswap) {
204
		/*
205
		 * bit-swap the fddi addresses (isn't the IEEE standards
206
		 * process wonderful!) then convert them to names.
207
		 */
208
		for (i = 0; i < 6; ++i)
209
			fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
210
		for (i = 0; i < 6; ++i)
211
			fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
212
	}
213
	else {
214
		memcpy(fdst, (char *)fddip->fddi_dhost, 6);
215
		memcpy(fsrc, (char *)fddip->fddi_shost, 6);
216
	}
217
}
218
219
/*
220
 * Print the FDDI MAC header
221
 */
222
static inline void
223
fddi_print(const struct fddi_header *fddip, u_int length,
224
	   const u_char *fsrc, const u_char *fdst)
225
{
226
	char *srcname, *dstname;
227
228
	srcname = etheraddr_string(fsrc);
229
	dstname = etheraddr_string(fdst);
230
231
	if (vflag)
232
		(void) printf("%02x %s %s %d: ",
233
		       fddip->fddi_fc,
234
		       srcname, dstname,
235
		       length);
236
	else if (qflag)
237
		printf("%s %s %d: ", srcname, dstname, length);
238
	else {
239
		(void) print_fddi_fc(fddip->fddi_fc);
240
		(void) printf("%s %s %d: ", srcname, dstname, length);
241
	}
242
}
243
244
static inline void
245
fddi_smt_print(const u_char *p, u_int length)
246
{
247
	printf("<SMT printer not yet implemented>");
248
}
249
250
/*
251
 * This is the top level routine of the printer.  'sp' is the points
252
 * to the FDDI header of the packet, 'tvp' is the timestamp,
253
 * 'length' is the length of the packet off the wire, and 'caplen'
254
 * is the number of bytes actually captured.
255
 */
256
void
257
fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
258
	      const u_char *p)
259
{
260
	u_int caplen = h->caplen;
261
	u_int length = h->len;
262
	u_short extracted_ethertype;
263
	const struct fddi_header *fddip = (struct fddi_header *)p;
264
	struct ether_header ehdr;
265
266
	ts_print(&h->ts);
267
268
	if (caplen < FDDI_HDRLEN) {
269
		printf("[|fddi]");
270
		goto out;
271
	}
272
	/*
273
	 * Get the FDDI addresses into a canonical form
274
	 */
275
	extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
276
	/*
277
	 * Some printers want to get back at the link level addresses,
278
	 * and/or check that they're not walking off the end of the packet.
279
	 * Rather than pass them all the way down, we set these globals.
280
	 */
281
	snapend = p + caplen;
282
	/*
283
	 * Actually, the only printer that uses packetp is print-bootp.c,
284
	 * and it assumes that packetp points to an Ethernet header.  The
285
	 * right thing to do is to fix print-bootp.c to know which link
286
	 * type is in use when it excavates. XXX
287
	 */
288
	packetp = (u_char *)&ehdr;
289
290
	if (eflag)
291
		fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
292
293
	/* Skip over FDDI MAC header */
294
	length -= FDDI_HDRLEN;
295
	p += FDDI_HDRLEN;
296
	caplen -= FDDI_HDRLEN;
297
298
	/* Frame Control field determines interpretation of packet */
299
	extracted_ethertype = 0;
300
	if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
301
		/* Try to print the LLC-layer header & higher layers */
302
		if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr))
303
		    == 0) {
304
			/*
305
			 * Some kinds of LLC packet we cannot
306
			 * handle intelligently
307
			 */
308
			if (!eflag)
309
				fddi_print(fddip, length,
310
				    ESRC(&ehdr), EDST(&ehdr));
311
			if (extracted_ethertype) {
312
				printf("(LLC %s) ",
313
			etherproto_string(htons(extracted_ethertype)));
314
			}
315
			if (!xflag && !qflag)
316
				default_print(p, caplen);
317
		}
318
	} else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
319
		fddi_smt_print(p, caplen);
320
	else {
321
		/* Some kinds of FDDI packet we cannot handle intelligently */
322
		if (!eflag)
323
			fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
324
		if (!xflag && !qflag)
325
			default_print(p, caplen);
326
	}
327
	if (xflag)
328
		default_print(p, caplen);
329
out:
330
	putchar('\n');
331
}
332
#else
333
#include <sys/types.h>
334
#include <sys/time.h>
335
336
#include <stdio.h>
337
338
#include "interface.h"
339
void
340
fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
341
	      const u_char *p)
342
{
343
344
	error("not configured for fddi");
345
	/* NOTREACHED */
346
}
347
#endif