xref: /freebsd/contrib/tcpdump/print-fddi.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
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.
204edb46e9SPaul Traina  */
214edb46e9SPaul Traina 
223340d773SGleb Smirnoff /* \summary: Fiber Distributed Data Interface (FDDI) printer */
233340d773SGleb Smirnoff 
24ee67461eSJoseph Mingrone #include <config.h>
25a88113a8SBill Fenner 
26ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
274edb46e9SPaul Traina 
284edb46e9SPaul Traina #include <string.h>
294edb46e9SPaul Traina 
303340d773SGleb Smirnoff #include "netdissect.h"
31ee67461eSJoseph Mingrone #include "extract.h"
324edb46e9SPaul Traina #include "addrtoname.h"
333c602fabSXin LI 
343c602fabSXin LI /*
353c602fabSXin LI  * Based on Ultrix if_fddi.h
363c602fabSXin LI  */
373c602fabSXin LI 
383c602fabSXin LI struct fddi_header {
39ee67461eSJoseph Mingrone 	nd_uint8_t  fddi_fc;		/* frame control */
40ee67461eSJoseph Mingrone 	nd_mac_addr fddi_dhost;
41ee67461eSJoseph Mingrone 	nd_mac_addr fddi_shost;
423c602fabSXin LI };
433c602fabSXin LI 
443c602fabSXin LI /*
453c602fabSXin LI  * Length of an FDDI header; note that some compilers may pad
463c602fabSXin LI  * "struct fddi_header" to a multiple of 4 bytes, for example, so
473c602fabSXin LI  * "sizeof (struct fddi_header)" may not give the right
483c602fabSXin LI  * answer.
493c602fabSXin LI  */
503c602fabSXin LI #define FDDI_HDRLEN 13
513c602fabSXin LI 
523c602fabSXin LI /* Useful values for fddi_fc (frame control) field */
533c602fabSXin LI 
543c602fabSXin LI /*
553c602fabSXin LI  * FDDI Frame Control bits
563c602fabSXin LI  */
573c602fabSXin LI #define	FDDIFC_C		0x80		/* Class bit */
583c602fabSXin LI #define	FDDIFC_L		0x40		/* Address length bit */
593c602fabSXin LI #define	FDDIFC_F		0x30		/* Frame format bits */
603c602fabSXin LI #define	FDDIFC_Z		0x0f		/* Control bits */
613c602fabSXin LI 
623c602fabSXin LI /*
633c602fabSXin LI  * FDDI Frame Control values. (48-bit addressing only).
643c602fabSXin LI  */
653c602fabSXin LI #define	FDDIFC_VOID		0x40		/* Void frame */
663c602fabSXin LI #define	FDDIFC_NRT		0x80		/* Nonrestricted token */
673c602fabSXin LI #define	FDDIFC_RT		0xc0		/* Restricted token */
683c602fabSXin LI #define	FDDIFC_SMT_INFO		0x41		/* SMT Info */
693c602fabSXin LI #define	FDDIFC_SMT_NSA		0x4F		/* SMT Next station adrs */
703c602fabSXin LI #define	FDDIFC_MAC_BEACON	0xc2		/* MAC Beacon frame */
713c602fabSXin LI #define	FDDIFC_MAC_CLAIM	0xc3		/* MAC Claim frame */
723c602fabSXin LI #define	FDDIFC_LLC_ASYNC	0x50		/* Async. LLC frame */
733c602fabSXin LI #define	FDDIFC_LLC_SYNC		0xd0		/* Sync. LLC frame */
743c602fabSXin LI #define	FDDIFC_IMP_ASYNC	0x60		/* Implementor Async. */
753c602fabSXin LI #define	FDDIFC_IMP_SYNC		0xe0		/* Implementor Synch. */
763c602fabSXin LI #define FDDIFC_SMT		0x40		/* SMT frame */
773c602fabSXin LI #define FDDIFC_MAC		0xc0		/* MAC frame */
783c602fabSXin LI 
793c602fabSXin LI #define	FDDIFC_CLFF		0xF0		/* Class/Length/Format bits */
803c602fabSXin LI #define	FDDIFC_ZZZZ		0x0F		/* Control bits */
814edb46e9SPaul Traina 
824edb46e9SPaul Traina /*
834edb46e9SPaul Traina  * Some FDDI interfaces use bit-swapped addresses.
844edb46e9SPaul Traina  */
85a1c2090eSBill Fenner #if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__)
863340d773SGleb Smirnoff static int fddi_bitswap = 0;
874edb46e9SPaul Traina #else
883340d773SGleb Smirnoff static int fddi_bitswap = 1;
894edb46e9SPaul Traina #endif
904edb46e9SPaul Traina 
914edb46e9SPaul Traina /*
924edb46e9SPaul Traina  * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
934edb46e9SPaul Traina  *
944edb46e9SPaul Traina  * Based in part on code by Van Jacobson, which bears this note:
954edb46e9SPaul Traina  *
964edb46e9SPaul Traina  * NOTE:  This is a very preliminary hack for FDDI support.
974edb46e9SPaul Traina  * There are all sorts of wired in constants & nothing (yet)
984edb46e9SPaul Traina  * to print SMT packets as anything other than hex dumps.
994edb46e9SPaul Traina  * Most of the necessary changes are waiting on my redoing
1004edb46e9SPaul Traina  * the "header" that a kernel fddi driver supplies to bpf:  I
1014edb46e9SPaul Traina  * want it to look like one byte of 'direction' (0 or 1
1024edb46e9SPaul Traina  * depending on whether the packet was inbound or outbound),
1034edb46e9SPaul Traina  * two bytes of system/driver dependent data (anything an
1044edb46e9SPaul Traina  * implementor thinks would be useful to filter on and/or
1054edb46e9SPaul Traina  * save per-packet, then the real 21-byte FDDI header.
1064edb46e9SPaul Traina  * Steve McCanne & I have also talked about adding the
1074edb46e9SPaul Traina  * 'direction' byte to all bpf headers (e.g., in the two
1084edb46e9SPaul Traina  * bytes of padding on an ethernet header).  It's not clear
1094edb46e9SPaul Traina  * we could do this in a backwards compatible way & we hate
1104edb46e9SPaul Traina  * the idea of an incompatible bpf change.  Discussions are
1114edb46e9SPaul Traina  * proceeding.
1124edb46e9SPaul Traina  *
1134edb46e9SPaul Traina  * Also, to really support FDDI (and better support 802.2
1144edb46e9SPaul Traina  * over ethernet) we really need to re-think the rather simple
1154edb46e9SPaul Traina  * minded assumptions about fixed length & fixed format link
1164edb46e9SPaul Traina  * level headers made in gencode.c.  One day...
1174edb46e9SPaul Traina  *
1184edb46e9SPaul Traina  *  - vj
1194edb46e9SPaul Traina  */
1204edb46e9SPaul Traina 
1213c602fabSXin LI static const u_char fddi_bit_swap[] = {
1224edb46e9SPaul Traina 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1234edb46e9SPaul Traina 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1244edb46e9SPaul Traina 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1254edb46e9SPaul Traina 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1264edb46e9SPaul Traina 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1274edb46e9SPaul Traina 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1284edb46e9SPaul Traina 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1294edb46e9SPaul Traina 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1304edb46e9SPaul Traina 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1314edb46e9SPaul Traina 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1324edb46e9SPaul Traina 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1334edb46e9SPaul Traina 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1344edb46e9SPaul Traina 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1354edb46e9SPaul Traina 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1364edb46e9SPaul Traina 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1374edb46e9SPaul Traina 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1384edb46e9SPaul Traina 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1394edb46e9SPaul Traina 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1404edb46e9SPaul Traina 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1414edb46e9SPaul Traina 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1424edb46e9SPaul Traina 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1434edb46e9SPaul Traina 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1444edb46e9SPaul Traina 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1454edb46e9SPaul Traina 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1464edb46e9SPaul Traina 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1474edb46e9SPaul Traina 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1484edb46e9SPaul Traina 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1494edb46e9SPaul Traina 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1504edb46e9SPaul Traina 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1514edb46e9SPaul Traina 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1524edb46e9SPaul Traina 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1534edb46e9SPaul Traina 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
1544edb46e9SPaul Traina };
1554edb46e9SPaul Traina 
1564edb46e9SPaul Traina /*
1574edb46e9SPaul Traina  * Print FDDI frame-control bits
1584edb46e9SPaul Traina  */
159ee67461eSJoseph Mingrone static void
print_fddi_fc(netdissect_options * ndo,u_char fc)1603c602fabSXin LI print_fddi_fc(netdissect_options *ndo, u_char fc)
1614edb46e9SPaul Traina {
1624edb46e9SPaul Traina 	switch (fc) {
1634edb46e9SPaul Traina 
1644edb46e9SPaul Traina 	case FDDIFC_VOID:                         /* Void frame */
165ee67461eSJoseph Mingrone 		ND_PRINT("void ");
1664edb46e9SPaul Traina 		break;
1674edb46e9SPaul Traina 
1684edb46e9SPaul Traina 	case FDDIFC_NRT:                          /* Nonrestricted token */
169ee67461eSJoseph Mingrone 		ND_PRINT("nrt ");
1704edb46e9SPaul Traina 		break;
1714edb46e9SPaul Traina 
1724edb46e9SPaul Traina 	case FDDIFC_RT:                           /* Restricted token */
173ee67461eSJoseph Mingrone 		ND_PRINT("rt ");
1744edb46e9SPaul Traina 		break;
1754edb46e9SPaul Traina 
1764edb46e9SPaul Traina 	case FDDIFC_SMT_INFO:                     /* SMT Info */
177ee67461eSJoseph Mingrone 		ND_PRINT("info ");
1784edb46e9SPaul Traina 		break;
1794edb46e9SPaul Traina 
1804edb46e9SPaul Traina 	case FDDIFC_SMT_NSA:                      /* SMT Next station adrs */
181ee67461eSJoseph Mingrone 		ND_PRINT("nsa ");
1824edb46e9SPaul Traina 		break;
1834edb46e9SPaul Traina 
1844edb46e9SPaul Traina 	case FDDIFC_MAC_BEACON:                   /* MAC Beacon frame */
185ee67461eSJoseph Mingrone 		ND_PRINT("beacon ");
1864edb46e9SPaul Traina 		break;
1874edb46e9SPaul Traina 
1884edb46e9SPaul Traina 	case FDDIFC_MAC_CLAIM:                    /* MAC Claim frame */
189ee67461eSJoseph Mingrone 		ND_PRINT("claim ");
1904edb46e9SPaul Traina 		break;
1914edb46e9SPaul Traina 
1924edb46e9SPaul Traina 	default:
1934edb46e9SPaul Traina 		switch (fc & FDDIFC_CLFF) {
1944edb46e9SPaul Traina 
1954edb46e9SPaul Traina 		case FDDIFC_MAC:
196ee67461eSJoseph Mingrone 			ND_PRINT("mac%1x ", fc & FDDIFC_ZZZZ);
1974edb46e9SPaul Traina 			break;
1984edb46e9SPaul Traina 
1994edb46e9SPaul Traina 		case FDDIFC_SMT:
200ee67461eSJoseph Mingrone 			ND_PRINT("smt%1x ", fc & FDDIFC_ZZZZ);
2014edb46e9SPaul Traina 			break;
2024edb46e9SPaul Traina 
2034edb46e9SPaul Traina 		case FDDIFC_LLC_ASYNC:
204ee67461eSJoseph Mingrone 			ND_PRINT("async%1x ", fc & FDDIFC_ZZZZ);
2054edb46e9SPaul Traina 			break;
2064edb46e9SPaul Traina 
2074edb46e9SPaul Traina 		case FDDIFC_LLC_SYNC:
208ee67461eSJoseph Mingrone 			ND_PRINT("sync%1x ", fc & FDDIFC_ZZZZ);
2094edb46e9SPaul Traina 			break;
2104edb46e9SPaul Traina 
2114edb46e9SPaul Traina 		case FDDIFC_IMP_ASYNC:
212ee67461eSJoseph Mingrone 			ND_PRINT("imp_async%1x ", fc & FDDIFC_ZZZZ);
2134edb46e9SPaul Traina 			break;
2144edb46e9SPaul Traina 
2154edb46e9SPaul Traina 		case FDDIFC_IMP_SYNC:
216ee67461eSJoseph Mingrone 			ND_PRINT("imp_sync%1x ", fc & FDDIFC_ZZZZ);
2174edb46e9SPaul Traina 			break;
2184edb46e9SPaul Traina 
2194edb46e9SPaul Traina 		default:
220ee67461eSJoseph Mingrone 			ND_PRINT("%02x ", fc);
2214edb46e9SPaul Traina 			break;
2224edb46e9SPaul Traina 		}
2234edb46e9SPaul Traina 	}
2244edb46e9SPaul Traina }
2254edb46e9SPaul Traina 
2264edb46e9SPaul Traina /* Extract src, dst addresses */
227ee67461eSJoseph Mingrone static void
extract_fddi_addrs(const struct fddi_header * fddip,char * fsrc,char * fdst)2284edb46e9SPaul Traina extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
2294edb46e9SPaul Traina {
230ee67461eSJoseph Mingrone 	int i;
2314edb46e9SPaul Traina 
2324edb46e9SPaul Traina 	if (fddi_bitswap) {
2334edb46e9SPaul Traina 		/*
2344edb46e9SPaul Traina 		 * bit-swap the fddi addresses (isn't the IEEE standards
2354edb46e9SPaul Traina 		 * process wonderful!) then convert them to names.
2364edb46e9SPaul Traina 		 */
2374edb46e9SPaul Traina 		for (i = 0; i < 6; ++i)
2384edb46e9SPaul Traina 			fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
2394edb46e9SPaul Traina 		for (i = 0; i < 6; ++i)
2404edb46e9SPaul Traina 			fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
241*0a7e5f1fSJoseph Mingrone 	} else {
242a1c2090eSBill Fenner 		memcpy(fdst, (const char *)fddip->fddi_dhost, 6);
243a1c2090eSBill Fenner 		memcpy(fsrc, (const char *)fddip->fddi_shost, 6);
2444edb46e9SPaul Traina 	}
2454edb46e9SPaul Traina }
2464edb46e9SPaul Traina 
2474edb46e9SPaul Traina /*
2484edb46e9SPaul Traina  * Print the FDDI MAC header
2494edb46e9SPaul Traina  */
250ee67461eSJoseph Mingrone static void
fddi_hdr_print(netdissect_options * ndo,const struct fddi_header * fddip,u_int length,const u_char * fsrc,const u_char * fdst)2513c602fabSXin LI fddi_hdr_print(netdissect_options *ndo,
252ee67461eSJoseph Mingrone                const struct fddi_header *fddip, u_int length,
253ee67461eSJoseph Mingrone                const u_char *fsrc, const u_char *fdst)
2544edb46e9SPaul Traina {
255a1c2090eSBill Fenner 	const char *srcname, *dstname;
2564edb46e9SPaul Traina 
2573c602fabSXin LI 	srcname = etheraddr_string(ndo, fsrc);
2583c602fabSXin LI 	dstname = etheraddr_string(ndo, fdst);
2594edb46e9SPaul Traina 
2603340d773SGleb Smirnoff 	if (!ndo->ndo_qflag)
261ee67461eSJoseph Mingrone 		print_fddi_fc(ndo, GET_U_1(fddip->fddi_fc));
262ee67461eSJoseph Mingrone 	ND_PRINT("%s > %s, length %u: ",
2634edb46e9SPaul Traina 	       srcname, dstname,
264ee67461eSJoseph Mingrone 	       length);
2654edb46e9SPaul Traina }
2664edb46e9SPaul Traina 
267ee67461eSJoseph Mingrone static void
fddi_smt_print(netdissect_options * ndo,const u_char * p _U_,u_int length _U_)2683c602fabSXin LI fddi_smt_print(netdissect_options *ndo, const u_char *p _U_, u_int length _U_)
2694edb46e9SPaul Traina {
270ee67461eSJoseph Mingrone 	ND_PRINT("<SMT printer not yet implemented>");
2714edb46e9SPaul Traina }
2724edb46e9SPaul Traina 
2733340d773SGleb Smirnoff u_int
fddi_print(netdissect_options * ndo,const u_char * p,u_int length,u_int caplen)2743c602fabSXin LI fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
2754edb46e9SPaul Traina {
276a1c2090eSBill Fenner 	const struct fddi_header *fddip = (const struct fddi_header *)p;
277ee67461eSJoseph Mingrone 	uint8_t fc;
278ee67461eSJoseph Mingrone 	nd_mac_addr srcmac, dstmac;
2793340d773SGleb Smirnoff 	struct lladdr_info src, dst;
2803340d773SGleb Smirnoff 	int llc_hdrlen;
2814edb46e9SPaul Traina 
282ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "fddi";
2834edb46e9SPaul Traina 	if (caplen < FDDI_HDRLEN) {
284ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
2853340d773SGleb Smirnoff 		return (caplen);
2864edb46e9SPaul Traina 	}
287cc391cceSBruce M Simpson 
288ee67461eSJoseph Mingrone 	fc = GET_U_1(fddip->fddi_fc);
289ee67461eSJoseph Mingrone 
2904edb46e9SPaul Traina 	/*
2914edb46e9SPaul Traina 	 * Get the FDDI addresses into a canonical form
2924edb46e9SPaul Traina 	 */
293ee67461eSJoseph Mingrone 	extract_fddi_addrs(fddip, (char *)srcmac, (char *)dstmac);
2944edb46e9SPaul Traina 
2953c602fabSXin LI 	if (ndo->ndo_eflag)
296ee67461eSJoseph Mingrone 		fddi_hdr_print(ndo, fddip, length, srcmac, dstmac);
2974edb46e9SPaul Traina 
298ee67461eSJoseph Mingrone 	src.addr = srcmac;
2993340d773SGleb Smirnoff 	src.addr_string = etheraddr_string;
300ee67461eSJoseph Mingrone 	dst.addr = dstmac;
3013340d773SGleb Smirnoff 	dst.addr_string = etheraddr_string;
3023340d773SGleb Smirnoff 
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 */
309ee67461eSJoseph Mingrone 	if ((fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
3104edb46e9SPaul Traina 		/* Try to print the LLC-layer header & higher layers */
3113340d773SGleb Smirnoff 		llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
3123340d773SGleb Smirnoff 		if (llc_hdrlen < 0) {
3134edb46e9SPaul Traina 			/*
3144edb46e9SPaul Traina 			 * Some kinds of LLC packet we cannot
3154edb46e9SPaul Traina 			 * handle intelligently
3164edb46e9SPaul Traina 			 */
3173c602fabSXin LI 			if (!ndo->ndo_suppress_default_print)
3183c602fabSXin LI 				ND_DEFAULTPRINT(p, caplen);
3193340d773SGleb Smirnoff 			llc_hdrlen = -llc_hdrlen;
3204edb46e9SPaul Traina 		}
321ee67461eSJoseph Mingrone 	} else if ((fc & FDDIFC_CLFF) == FDDIFC_SMT) {
3223c602fabSXin LI 		fddi_smt_print(ndo, p, caplen);
3233340d773SGleb Smirnoff 		llc_hdrlen = 0;
3243340d773SGleb Smirnoff 	} else {
3254edb46e9SPaul Traina 		/* Some kinds of FDDI packet we cannot handle intelligently */
3263c602fabSXin LI 		if (!ndo->ndo_eflag)
327ee67461eSJoseph Mingrone 			fddi_hdr_print(ndo, fddip, length + FDDI_HDRLEN, srcmac,
328ee67461eSJoseph Mingrone 			    dstmac);
3293c602fabSXin LI 		if (!ndo->ndo_suppress_default_print)
3303c602fabSXin LI 			ND_DEFAULTPRINT(p, caplen);
3313340d773SGleb Smirnoff 		llc_hdrlen = 0;
3324edb46e9SPaul Traina 	}
3333340d773SGleb Smirnoff 	return (FDDI_HDRLEN + llc_hdrlen);
334cc391cceSBruce M Simpson }
335cc391cceSBruce M Simpson 
336cc391cceSBruce M Simpson /*
337cc391cceSBruce M Simpson  * This is the top level routine of the printer.  'p' points
338cc391cceSBruce M Simpson  * to the FDDI header of the packet, 'h->ts' is the timestamp,
339c1ad1296SSam Leffler  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
340cc391cceSBruce M Simpson  * is the number of bytes actually captured.
341cc391cceSBruce M Simpson  */
342ee67461eSJoseph Mingrone void
fddi_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)343ee67461eSJoseph Mingrone fddi_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
344cc391cceSBruce M Simpson {
345ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "fddi";
346ee67461eSJoseph Mingrone 	ndo->ndo_ll_hdr_len += fddi_print(ndo, p, h->len, h->caplen);
3474edb46e9SPaul Traina }
348