xref: /freebsd/contrib/tcpdump/print-fddi.c (revision 3c602fabf9b894ff79f08a80cbb7ad3b1eb84e62)
14edb46e9SPaul Traina /*
2699fc314SBill Fenner  * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
34edb46e9SPaul Traina  *	The Regents of the University of California.  All rights reserved.
44edb46e9SPaul Traina  *
54edb46e9SPaul Traina  * Redistribution and use in source and binary forms, with or without
64edb46e9SPaul Traina  * modification, are permitted provided that: (1) source code distributions
74edb46e9SPaul Traina  * retain the above copyright notice and this paragraph in its entirety, (2)
84edb46e9SPaul Traina  * distributions including binary code include the above copyright notice and
94edb46e9SPaul Traina  * this paragraph in its entirety in the documentation or other materials
104edb46e9SPaul Traina  * provided with the distribution, and (3) all advertising materials mentioning
114edb46e9SPaul Traina  * features or use of this software display the following acknowledgement:
124edb46e9SPaul Traina  * ``This product includes software developed by the University of California,
134edb46e9SPaul Traina  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
144edb46e9SPaul Traina  * the University nor the names of its contributors may be used to endorse
154edb46e9SPaul Traina  * or promote products derived from this software without specific prior
164edb46e9SPaul Traina  * written permission.
174edb46e9SPaul Traina  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
184edb46e9SPaul Traina  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
194edb46e9SPaul Traina  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20a88113a8SBill Fenner  *
21a88113a8SBill Fenner  * $FreeBSD$
224edb46e9SPaul Traina  */
234edb46e9SPaul Traina 
24*3c602fabSXin LI #define NETDISSECT_REWORKED
25a88113a8SBill Fenner #ifdef HAVE_CONFIG_H
26a88113a8SBill Fenner #include "config.h"
27a88113a8SBill Fenner #endif
28a88113a8SBill Fenner 
29cc391cceSBruce M Simpson #include <tcpdump-stdinc.h>
304edb46e9SPaul Traina 
314edb46e9SPaul Traina #include <string.h>
324edb46e9SPaul Traina 
334edb46e9SPaul Traina #include "interface.h"
344edb46e9SPaul Traina #include "addrtoname.h"
35943ee2b1SBill Fenner #include "ether.h"
36*3c602fabSXin LI 
37*3c602fabSXin LI /*
38*3c602fabSXin LI  * Based on Ultrix if_fddi.h
39*3c602fabSXin LI  */
40*3c602fabSXin LI 
41*3c602fabSXin LI struct fddi_header {
42*3c602fabSXin LI 	u_char  fddi_fc;		/* frame control */
43*3c602fabSXin LI 	u_char  fddi_dhost[6];
44*3c602fabSXin LI 	u_char  fddi_shost[6];
45*3c602fabSXin LI };
46*3c602fabSXin LI 
47*3c602fabSXin LI /*
48*3c602fabSXin LI  * Length of an FDDI header; note that some compilers may pad
49*3c602fabSXin LI  * "struct fddi_header" to a multiple of 4 bytes, for example, so
50*3c602fabSXin LI  * "sizeof (struct fddi_header)" may not give the right
51*3c602fabSXin LI  * answer.
52*3c602fabSXin LI  */
53*3c602fabSXin LI #define FDDI_HDRLEN 13
54*3c602fabSXin LI 
55*3c602fabSXin LI /* Useful values for fddi_fc (frame control) field */
56*3c602fabSXin LI 
57*3c602fabSXin LI /*
58*3c602fabSXin LI  * FDDI Frame Control bits
59*3c602fabSXin LI  */
60*3c602fabSXin LI #define	FDDIFC_C		0x80		/* Class bit */
61*3c602fabSXin LI #define	FDDIFC_L		0x40		/* Address length bit */
62*3c602fabSXin LI #define	FDDIFC_F		0x30		/* Frame format bits */
63*3c602fabSXin LI #define	FDDIFC_Z		0x0f		/* Control bits */
64*3c602fabSXin LI 
65*3c602fabSXin LI /*
66*3c602fabSXin LI  * FDDI Frame Control values. (48-bit addressing only).
67*3c602fabSXin LI  */
68*3c602fabSXin LI #define	FDDIFC_VOID		0x40		/* Void frame */
69*3c602fabSXin LI #define	FDDIFC_NRT		0x80		/* Nonrestricted token */
70*3c602fabSXin LI #define	FDDIFC_RT		0xc0		/* Restricted token */
71*3c602fabSXin LI #define	FDDIFC_SMT_INFO		0x41		/* SMT Info */
72*3c602fabSXin LI #define	FDDIFC_SMT_NSA		0x4F		/* SMT Next station adrs */
73*3c602fabSXin LI #define	FDDIFC_MAC_BEACON	0xc2		/* MAC Beacon frame */
74*3c602fabSXin LI #define	FDDIFC_MAC_CLAIM	0xc3		/* MAC Claim frame */
75*3c602fabSXin LI #define	FDDIFC_LLC_ASYNC	0x50		/* Async. LLC frame */
76*3c602fabSXin LI #define	FDDIFC_LLC_SYNC		0xd0		/* Sync. LLC frame */
77*3c602fabSXin LI #define	FDDIFC_IMP_ASYNC	0x60		/* Implementor Async. */
78*3c602fabSXin LI #define	FDDIFC_IMP_SYNC		0xe0		/* Implementor Synch. */
79*3c602fabSXin LI #define FDDIFC_SMT		0x40		/* SMT frame */
80*3c602fabSXin LI #define FDDIFC_MAC		0xc0		/* MAC frame */
81*3c602fabSXin LI 
82*3c602fabSXin LI #define	FDDIFC_CLFF		0xF0		/* Class/Length/Format bits */
83*3c602fabSXin LI #define	FDDIFC_ZZZZ		0x0F		/* Control bits */
844edb46e9SPaul Traina 
854edb46e9SPaul Traina /*
864edb46e9SPaul Traina  * Some FDDI interfaces use bit-swapped addresses.
874edb46e9SPaul Traina  */
88a1c2090eSBill Fenner #if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__)
894edb46e9SPaul Traina int	fddi_bitswap = 0;
904edb46e9SPaul Traina #else
914edb46e9SPaul Traina int	fddi_bitswap = 1;
924edb46e9SPaul Traina #endif
934edb46e9SPaul Traina 
944edb46e9SPaul Traina /*
954edb46e9SPaul Traina  * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
964edb46e9SPaul Traina  *
974edb46e9SPaul Traina  * Based in part on code by Van Jacobson, which bears this note:
984edb46e9SPaul Traina  *
994edb46e9SPaul Traina  * NOTE:  This is a very preliminary hack for FDDI support.
1004edb46e9SPaul Traina  * There are all sorts of wired in constants & nothing (yet)
1014edb46e9SPaul Traina  * to print SMT packets as anything other than hex dumps.
1024edb46e9SPaul Traina  * Most of the necessary changes are waiting on my redoing
1034edb46e9SPaul Traina  * the "header" that a kernel fddi driver supplies to bpf:  I
1044edb46e9SPaul Traina  * want it to look like one byte of 'direction' (0 or 1
1054edb46e9SPaul Traina  * depending on whether the packet was inbound or outbound),
1064edb46e9SPaul Traina  * two bytes of system/driver dependent data (anything an
1074edb46e9SPaul Traina  * implementor thinks would be useful to filter on and/or
1084edb46e9SPaul Traina  * save per-packet, then the real 21-byte FDDI header.
1094edb46e9SPaul Traina  * Steve McCanne & I have also talked about adding the
1104edb46e9SPaul Traina  * 'direction' byte to all bpf headers (e.g., in the two
1114edb46e9SPaul Traina  * bytes of padding on an ethernet header).  It's not clear
1124edb46e9SPaul Traina  * we could do this in a backwards compatible way & we hate
1134edb46e9SPaul Traina  * the idea of an incompatible bpf change.  Discussions are
1144edb46e9SPaul Traina  * proceeding.
1154edb46e9SPaul Traina  *
1164edb46e9SPaul Traina  * Also, to really support FDDI (and better support 802.2
1174edb46e9SPaul Traina  * over ethernet) we really need to re-think the rather simple
1184edb46e9SPaul Traina  * minded assumptions about fixed length & fixed format link
1194edb46e9SPaul Traina  * level headers made in gencode.c.  One day...
1204edb46e9SPaul Traina  *
1214edb46e9SPaul Traina  *  - vj
1224edb46e9SPaul Traina  */
1234edb46e9SPaul Traina 
124*3c602fabSXin LI static const u_char fddi_bit_swap[] = {
1254edb46e9SPaul Traina 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1264edb46e9SPaul Traina 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1274edb46e9SPaul Traina 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1284edb46e9SPaul Traina 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1294edb46e9SPaul Traina 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1304edb46e9SPaul Traina 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1314edb46e9SPaul Traina 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1324edb46e9SPaul Traina 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1334edb46e9SPaul Traina 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1344edb46e9SPaul Traina 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1354edb46e9SPaul Traina 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1364edb46e9SPaul Traina 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1374edb46e9SPaul Traina 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1384edb46e9SPaul Traina 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1394edb46e9SPaul Traina 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1404edb46e9SPaul Traina 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1414edb46e9SPaul Traina 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1424edb46e9SPaul Traina 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1434edb46e9SPaul Traina 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1444edb46e9SPaul Traina 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1454edb46e9SPaul Traina 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1464edb46e9SPaul Traina 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1474edb46e9SPaul Traina 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1484edb46e9SPaul Traina 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1494edb46e9SPaul Traina 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1504edb46e9SPaul Traina 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1514edb46e9SPaul Traina 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1524edb46e9SPaul Traina 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1534edb46e9SPaul Traina 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1544edb46e9SPaul Traina 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1554edb46e9SPaul Traina 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1564edb46e9SPaul Traina 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
1574edb46e9SPaul Traina };
1584edb46e9SPaul Traina 
1594edb46e9SPaul Traina /*
1604edb46e9SPaul Traina  * Print FDDI frame-control bits
1614edb46e9SPaul Traina  */
1624edb46e9SPaul Traina static inline void
163*3c602fabSXin LI print_fddi_fc(netdissect_options *ndo, u_char fc)
1644edb46e9SPaul Traina {
1654edb46e9SPaul Traina 	switch (fc) {
1664edb46e9SPaul Traina 
1674edb46e9SPaul Traina 	case FDDIFC_VOID:                         /* Void frame */
168*3c602fabSXin LI 		ND_PRINT((ndo, "void "));
1694edb46e9SPaul Traina 		break;
1704edb46e9SPaul Traina 
1714edb46e9SPaul Traina 	case FDDIFC_NRT:                          /* Nonrestricted token */
172*3c602fabSXin LI 		ND_PRINT((ndo, "nrt "));
1734edb46e9SPaul Traina 		break;
1744edb46e9SPaul Traina 
1754edb46e9SPaul Traina 	case FDDIFC_RT:                           /* Restricted token */
176*3c602fabSXin LI 		ND_PRINT((ndo, "rt "));
1774edb46e9SPaul Traina 		break;
1784edb46e9SPaul Traina 
1794edb46e9SPaul Traina 	case FDDIFC_SMT_INFO:                     /* SMT Info */
180*3c602fabSXin LI 		ND_PRINT((ndo, "info "));
1814edb46e9SPaul Traina 		break;
1824edb46e9SPaul Traina 
1834edb46e9SPaul Traina 	case FDDIFC_SMT_NSA:                      /* SMT Next station adrs */
184*3c602fabSXin LI 		ND_PRINT((ndo, "nsa "));
1854edb46e9SPaul Traina 		break;
1864edb46e9SPaul Traina 
1874edb46e9SPaul Traina 	case FDDIFC_MAC_BEACON:                   /* MAC Beacon frame */
188*3c602fabSXin LI 		ND_PRINT((ndo, "beacon "));
1894edb46e9SPaul Traina 		break;
1904edb46e9SPaul Traina 
1914edb46e9SPaul Traina 	case FDDIFC_MAC_CLAIM:                    /* MAC Claim frame */
192*3c602fabSXin LI 		ND_PRINT((ndo, "claim "));
1934edb46e9SPaul Traina 		break;
1944edb46e9SPaul Traina 
1954edb46e9SPaul Traina 	default:
1964edb46e9SPaul Traina 		switch (fc & FDDIFC_CLFF) {
1974edb46e9SPaul Traina 
1984edb46e9SPaul Traina 		case FDDIFC_MAC:
199*3c602fabSXin LI 			ND_PRINT((ndo, "mac%1x ", fc & FDDIFC_ZZZZ));
2004edb46e9SPaul Traina 			break;
2014edb46e9SPaul Traina 
2024edb46e9SPaul Traina 		case FDDIFC_SMT:
203*3c602fabSXin LI 			ND_PRINT((ndo, "smt%1x ", fc & FDDIFC_ZZZZ));
2044edb46e9SPaul Traina 			break;
2054edb46e9SPaul Traina 
2064edb46e9SPaul Traina 		case FDDIFC_LLC_ASYNC:
207*3c602fabSXin LI 			ND_PRINT((ndo, "async%1x ", fc & FDDIFC_ZZZZ));
2084edb46e9SPaul Traina 			break;
2094edb46e9SPaul Traina 
2104edb46e9SPaul Traina 		case FDDIFC_LLC_SYNC:
211*3c602fabSXin LI 			ND_PRINT((ndo, "sync%1x ", fc & FDDIFC_ZZZZ));
2124edb46e9SPaul Traina 			break;
2134edb46e9SPaul Traina 
2144edb46e9SPaul Traina 		case FDDIFC_IMP_ASYNC:
215*3c602fabSXin LI 			ND_PRINT((ndo, "imp_async%1x ", fc & FDDIFC_ZZZZ));
2164edb46e9SPaul Traina 			break;
2174edb46e9SPaul Traina 
2184edb46e9SPaul Traina 		case FDDIFC_IMP_SYNC:
219*3c602fabSXin LI 			ND_PRINT((ndo, "imp_sync%1x ", fc & FDDIFC_ZZZZ));
2204edb46e9SPaul Traina 			break;
2214edb46e9SPaul Traina 
2224edb46e9SPaul Traina 		default:
223*3c602fabSXin LI 			ND_PRINT((ndo, "%02x ", fc));
2244edb46e9SPaul Traina 			break;
2254edb46e9SPaul Traina 		}
2264edb46e9SPaul Traina 	}
2274edb46e9SPaul Traina }
2284edb46e9SPaul Traina 
2294edb46e9SPaul Traina /* Extract src, dst addresses */
2304edb46e9SPaul Traina static inline void
2314edb46e9SPaul Traina extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
2324edb46e9SPaul Traina {
2334edb46e9SPaul Traina 	register int i;
2344edb46e9SPaul Traina 
2354edb46e9SPaul Traina 	if (fddi_bitswap) {
2364edb46e9SPaul Traina 		/*
2374edb46e9SPaul Traina 		 * bit-swap the fddi addresses (isn't the IEEE standards
2384edb46e9SPaul Traina 		 * process wonderful!) then convert them to names.
2394edb46e9SPaul Traina 		 */
2404edb46e9SPaul Traina 		for (i = 0; i < 6; ++i)
2414edb46e9SPaul Traina 			fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
2424edb46e9SPaul Traina 		for (i = 0; i < 6; ++i)
2434edb46e9SPaul Traina 			fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
2444edb46e9SPaul Traina 	}
2454edb46e9SPaul Traina 	else {
246a1c2090eSBill Fenner 		memcpy(fdst, (const char *)fddip->fddi_dhost, 6);
247a1c2090eSBill Fenner 		memcpy(fsrc, (const char *)fddip->fddi_shost, 6);
2484edb46e9SPaul Traina 	}
2494edb46e9SPaul Traina }
2504edb46e9SPaul Traina 
2514edb46e9SPaul Traina /*
2524edb46e9SPaul Traina  * Print the FDDI MAC header
2534edb46e9SPaul Traina  */
2544edb46e9SPaul Traina static inline void
255*3c602fabSXin LI fddi_hdr_print(netdissect_options *ndo,
256*3c602fabSXin LI                register const struct fddi_header *fddip, register u_int length,
2574edb46e9SPaul Traina                register const u_char *fsrc, register const u_char *fdst)
2584edb46e9SPaul Traina {
259a1c2090eSBill Fenner 	const char *srcname, *dstname;
2604edb46e9SPaul Traina 
261*3c602fabSXin LI 	srcname = etheraddr_string(ndo, fsrc);
262*3c602fabSXin LI 	dstname = etheraddr_string(ndo, fdst);
2634edb46e9SPaul Traina 
264*3c602fabSXin LI 	if (ndo->ndo_vflag)
265*3c602fabSXin LI 		ND_PRINT((ndo, "%02x %s %s %d: ",
2664edb46e9SPaul Traina 		       fddip->fddi_fc,
2674edb46e9SPaul Traina 		       srcname, dstname,
268*3c602fabSXin LI 		       length));
269*3c602fabSXin LI 	else if (ndo->ndo_qflag)
270*3c602fabSXin LI 		ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length));
2714edb46e9SPaul Traina 	else {
272*3c602fabSXin LI 		print_fddi_fc(ndo, fddip->fddi_fc);
273*3c602fabSXin LI 		ND_PRINT((ndo, "%s %s %d: ", srcname, dstname, length));
2744edb46e9SPaul Traina 	}
2754edb46e9SPaul Traina }
2764edb46e9SPaul Traina 
2774edb46e9SPaul Traina static inline void
278*3c602fabSXin LI fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_)
2794edb46e9SPaul Traina {
280*3c602fabSXin LI 	ND_PRINT((ndo, "<SMT printer not yet implemented>"));
2814edb46e9SPaul Traina }
2824edb46e9SPaul Traina 
2834edb46e9SPaul Traina void
284*3c602fabSXin LI fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
2854edb46e9SPaul Traina {
286a1c2090eSBill Fenner 	const struct fddi_header *fddip = (const struct fddi_header *)p;
2874edb46e9SPaul Traina 	struct ether_header ehdr;
288a88113a8SBill Fenner 	u_short extracted_ethertype;
2894edb46e9SPaul Traina 
2904edb46e9SPaul Traina 	if (caplen < FDDI_HDRLEN) {
291*3c602fabSXin LI 		ND_PRINT((ndo, "[|fddi]"));
292cc391cceSBruce M Simpson 		return;
2934edb46e9SPaul Traina 	}
294cc391cceSBruce M Simpson 
2954edb46e9SPaul Traina 	/*
2964edb46e9SPaul Traina 	 * Get the FDDI addresses into a canonical form
2974edb46e9SPaul Traina 	 */
2984edb46e9SPaul Traina 	extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
2994edb46e9SPaul Traina 
300*3c602fabSXin LI 	if (ndo->ndo_eflag)
301*3c602fabSXin LI 		fddi_hdr_print(ndo, fddip, length, ESRC(&ehdr), EDST(&ehdr));
3024edb46e9SPaul Traina 
3034edb46e9SPaul Traina 	/* Skip over FDDI MAC header */
3044edb46e9SPaul Traina 	length -= FDDI_HDRLEN;
3054edb46e9SPaul Traina 	p += FDDI_HDRLEN;
3064edb46e9SPaul Traina 	caplen -= FDDI_HDRLEN;
3074edb46e9SPaul Traina 
3084edb46e9SPaul Traina 	/* Frame Control field determines interpretation of packet */
3094edb46e9SPaul Traina 	if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
3104edb46e9SPaul Traina 		/* Try to print the LLC-layer header & higher layers */
311*3c602fabSXin LI 		if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
312943ee2b1SBill Fenner 		    &extracted_ethertype) == 0) {
3134edb46e9SPaul Traina 			/*
3144edb46e9SPaul Traina 			 * Some kinds of LLC packet we cannot
3154edb46e9SPaul Traina 			 * handle intelligently
3164edb46e9SPaul Traina 			 */
317*3c602fabSXin LI 			if (!ndo->ndo_eflag)
318*3c602fabSXin LI 				fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN,
3194edb46e9SPaul Traina 				    ESRC(&ehdr), EDST(&ehdr));
3204edb46e9SPaul Traina 			if (extracted_ethertype) {
321*3c602fabSXin LI 				ND_PRINT((ndo, "(LLC %s) ",
322*3c602fabSXin LI 			etherproto_string(htons(extracted_ethertype))));
3234edb46e9SPaul Traina 			}
324*3c602fabSXin LI 			if (!ndo->ndo_suppress_default_print)
325*3c602fabSXin LI 				ND_DEFAULTPRINT(p, caplen);
3264edb46e9SPaul Traina 		}
3274edb46e9SPaul Traina 	} else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
328*3c602fabSXin LI 		fddi_smt_print(ndo, p, caplen);
3294edb46e9SPaul Traina 	else {
3304edb46e9SPaul Traina 		/* Some kinds of FDDI packet we cannot handle intelligently */
331*3c602fabSXin LI 		if (!ndo->ndo_eflag)
332*3c602fabSXin LI 			fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, ESRC(&ehdr),
333943ee2b1SBill Fenner 			    EDST(&ehdr));
334*3c602fabSXin LI 		if (!ndo->ndo_suppress_default_print)
335*3c602fabSXin LI 			ND_DEFAULTPRINT(p, caplen);
3364edb46e9SPaul Traina 	}
337cc391cceSBruce M Simpson }
338cc391cceSBruce M Simpson 
339cc391cceSBruce M Simpson /*
340cc391cceSBruce M Simpson  * This is the top level routine of the printer.  'p' points
341cc391cceSBruce M Simpson  * to the FDDI header of the packet, 'h->ts' is the timestamp,
342c1ad1296SSam Leffler  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
343cc391cceSBruce M Simpson  * is the number of bytes actually captured.
344cc391cceSBruce M Simpson  */
345cc391cceSBruce M Simpson u_int
346*3c602fabSXin LI fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
347cc391cceSBruce M Simpson {
348*3c602fabSXin LI 	fddi_print(ndo, p, h->len, h->caplen);
349cc391cceSBruce M Simpson 
350cc391cceSBruce M Simpson 	return (FDDI_HDRLEN);
3514edb46e9SPaul Traina }
352