xref: /freebsd/contrib/tcpdump/print-token.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
1722012ccSJulian Elischer /*
2722012ccSJulian Elischer  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
3722012ccSJulian Elischer  *	The Regents of the University of California.  All rights reserved.
4722012ccSJulian Elischer  *
5722012ccSJulian Elischer  * Redistribution and use in source and binary forms, with or without
6722012ccSJulian Elischer  * modification, are permitted provided that: (1) source code distributions
7722012ccSJulian Elischer  * retain the above copyright notice and this paragraph in its entirety, (2)
8722012ccSJulian Elischer  * distributions including binary code include the above copyright notice and
9722012ccSJulian Elischer  * this paragraph in its entirety in the documentation or other materials
10722012ccSJulian Elischer  * provided with the distribution, and (3) all advertising materials mentioning
11722012ccSJulian Elischer  * features or use of this software display the following acknowledgement:
12722012ccSJulian Elischer  * ``This product includes software developed by the University of California,
13722012ccSJulian Elischer  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14722012ccSJulian Elischer  * the University nor the names of its contributors may be used to endorse
15722012ccSJulian Elischer  * or promote products derived from this software without specific prior
16722012ccSJulian Elischer  * written permission.
17722012ccSJulian Elischer  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18722012ccSJulian Elischer  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19722012ccSJulian Elischer  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20722012ccSJulian Elischer  *
21722012ccSJulian Elischer  * Hacked version of print-ether.c  Larry Lile <lile@stdio.com>
22a88113a8SBill Fenner  *
23a1c2090eSBill Fenner  * Further tweaked to more closely resemble print-fddi.c
24a1c2090eSBill Fenner  *	Guy Harris <guy@alum.mit.edu>
25722012ccSJulian Elischer  */
26a1c2090eSBill Fenner 
273340d773SGleb Smirnoff /* \summary: Token Ring printer */
283340d773SGleb Smirnoff 
29*ee67461eSJoseph Mingrone #include <config.h>
30722012ccSJulian Elischer 
31*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
32722012ccSJulian Elischer 
33a1c2090eSBill Fenner #include <string.h>
34722012ccSJulian Elischer 
353340d773SGleb Smirnoff #include "netdissect.h"
3627df3f5dSRui Paulo #include "extract.h"
37722012ccSJulian Elischer #include "addrtoname.h"
383c602fabSXin LI 
393c602fabSXin LI /*
403c602fabSXin LI  * Copyright (c) 1998, Larry Lile
413c602fabSXin LI  * All rights reserved.
423c602fabSXin LI  *
433c602fabSXin LI  * Redistribution and use in source and binary forms, with or without
443c602fabSXin LI  * modification, are permitted provided that the following conditions
453c602fabSXin LI  * are met:
463c602fabSXin LI  * 1. Redistributions of source code must retain the above copyright
473c602fabSXin LI  *    notice unmodified, this list of conditions, and the following
483c602fabSXin LI  *    disclaimer.
493c602fabSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
503c602fabSXin LI  *    notice, this list of conditions and the following disclaimer in the
513c602fabSXin LI  *    documentation and/or other materials provided with the distribution.
523c602fabSXin LI  *
533c602fabSXin LI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
543c602fabSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
553c602fabSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
563c602fabSXin LI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
573c602fabSXin LI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
583c602fabSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
593c602fabSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
603c602fabSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
613c602fabSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
623c602fabSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
633c602fabSXin LI  * SUCH DAMAGE.
643c602fabSXin LI  *
653c602fabSXin LI  */
663c602fabSXin LI 
673c602fabSXin LI #define TOKEN_HDRLEN		14
683c602fabSXin LI #define ROUTING_SEGMENT_MAX	16
693c602fabSXin LI #define IS_SOURCE_ROUTED(trp)	((trp)->token_shost[0] & 0x80)
70*ee67461eSJoseph Mingrone #define FRAME_TYPE(trp)		((GET_U_1((trp)->token_fc) & 0xC0) >> 6)
713c602fabSXin LI #define TOKEN_FC_LLC		1
723c602fabSXin LI 
73*ee67461eSJoseph Mingrone #define BROADCAST(trp)		((GET_BE_U_2((trp)->token_rcf) & 0xE000) >> 13)
74*ee67461eSJoseph Mingrone #define RIF_LENGTH(trp)		((GET_BE_U_2((trp)->token_rcf) & 0x1f00) >> 8)
75*ee67461eSJoseph Mingrone #define DIRECTION(trp)		((GET_BE_U_2((trp)->token_rcf) & 0x0080) >> 7)
76*ee67461eSJoseph Mingrone #define LARGEST_FRAME(trp)	((GET_BE_U_2((trp)->token_rcf) & 0x0070) >> 4)
77*ee67461eSJoseph Mingrone #define RING_NUMBER(trp, x)	((GET_BE_U_2((trp)->token_rseg[x]) & 0xfff0) >> 4)
78*ee67461eSJoseph Mingrone #define BRIDGE_NUMBER(trp, x)	(GET_BE_U_2((trp)->token_rseg[x]) & 0x000f)
793c602fabSXin LI #define SEGMENT_COUNT(trp)	((int)((RIF_LENGTH(trp) - 2) / 2))
803c602fabSXin LI 
813c602fabSXin LI struct token_header {
82*ee67461eSJoseph Mingrone 	nd_uint8_t   token_ac;
83*ee67461eSJoseph Mingrone 	nd_uint8_t   token_fc;
84*ee67461eSJoseph Mingrone 	nd_mac_addr  token_dhost;
85*ee67461eSJoseph Mingrone 	nd_mac_addr  token_shost;
86*ee67461eSJoseph Mingrone 	nd_uint16_t  token_rcf;
87*ee67461eSJoseph Mingrone 	nd_uint16_t  token_rseg[ROUTING_SEGMENT_MAX];
883c602fabSXin LI };
893c602fabSXin LI 
90722012ccSJulian Elischer 
91a1c2090eSBill Fenner /* Extract src, dst addresses */
92*ee67461eSJoseph Mingrone static void
extract_token_addrs(const struct token_header * trp,char * fsrc,char * fdst)93a1c2090eSBill Fenner extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst)
94722012ccSJulian Elischer {
95a1c2090eSBill Fenner 	memcpy(fdst, (const char *)trp->token_dhost, 6);
96a1c2090eSBill Fenner 	memcpy(fsrc, (const char *)trp->token_shost, 6);
9714fffcebSLarry Lile }
98722012ccSJulian Elischer 
99722012ccSJulian Elischer /*
100a1c2090eSBill Fenner  * Print the TR MAC header
101722012ccSJulian Elischer  */
102*ee67461eSJoseph Mingrone static void
token_hdr_print(netdissect_options * ndo,const struct token_header * trp,u_int length,const u_char * fsrc,const u_char * fdst)1033c602fabSXin LI token_hdr_print(netdissect_options *ndo,
104*ee67461eSJoseph Mingrone                 const struct token_header *trp, u_int length,
105*ee67461eSJoseph Mingrone                 const u_char *fsrc, const u_char *fdst)
106a1c2090eSBill Fenner {
107a1c2090eSBill Fenner 	const char *srcname, *dstname;
108722012ccSJulian Elischer 
1093c602fabSXin LI 	srcname = etheraddr_string(ndo, fsrc);
1103c602fabSXin LI 	dstname = etheraddr_string(ndo, fdst);
111a1c2090eSBill Fenner 
1123340d773SGleb Smirnoff 	if (!ndo->ndo_qflag)
113*ee67461eSJoseph Mingrone 		ND_PRINT("%02x %02x ",
114*ee67461eSJoseph Mingrone 		       GET_U_1(trp->token_ac),
115*ee67461eSJoseph Mingrone 		       GET_U_1(trp->token_fc));
116*ee67461eSJoseph Mingrone 	ND_PRINT("%s > %s, length %u: ",
117a1c2090eSBill Fenner 	       srcname, dstname,
118*ee67461eSJoseph Mingrone 	       length);
119722012ccSJulian Elischer }
120722012ccSJulian Elischer 
121a1c2090eSBill Fenner static const char *broadcast_indicator[] = {
122a1c2090eSBill Fenner 	"Non-Broadcast", "Non-Broadcast",
123a1c2090eSBill Fenner 	"Non-Broadcast", "Non-Broadcast",
124a1c2090eSBill Fenner 	"All-routes",    "All-routes",
125a1c2090eSBill Fenner 	"Single-route",  "Single-route"
126a1c2090eSBill Fenner };
127a1c2090eSBill Fenner 
128a1c2090eSBill Fenner static const char *direction[] = {
129a1c2090eSBill Fenner 	"Forward", "Backward"
130a1c2090eSBill Fenner };
131a1c2090eSBill Fenner 
132a1c2090eSBill Fenner static const char *largest_frame[] = {
133a1c2090eSBill Fenner 	"516",
134a1c2090eSBill Fenner 	"1500",
135a1c2090eSBill Fenner 	"2052",
136a1c2090eSBill Fenner 	"4472",
137a1c2090eSBill Fenner 	"8144",
138a1c2090eSBill Fenner 	"11407",
139a1c2090eSBill Fenner 	"17800",
140a1c2090eSBill Fenner 	"??"
141a1c2090eSBill Fenner };
142a1c2090eSBill Fenner 
143cc391cceSBruce M Simpson u_int
token_print(netdissect_options * ndo,const u_char * p,u_int length,u_int caplen)1443c602fabSXin LI token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
145722012ccSJulian Elischer {
146a1c2090eSBill Fenner 	const struct token_header *trp;
1473340d773SGleb Smirnoff 	int llc_hdrlen;
148*ee67461eSJoseph Mingrone 	nd_mac_addr srcmac, dstmac;
1493340d773SGleb Smirnoff 	struct lladdr_info src, dst;
150cc391cceSBruce M Simpson 	u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
151cc391cceSBruce M Simpson 	int seg;
152722012ccSJulian Elischer 
153*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "token-ring";
154a1c2090eSBill Fenner 	trp = (const struct token_header *)p;
155722012ccSJulian Elischer 
156a1c2090eSBill Fenner 	if (caplen < TOKEN_HDRLEN) {
157*ee67461eSJoseph Mingrone 		nd_print_trunc(ndo);
158cc391cceSBruce M Simpson 		return hdr_len;
159722012ccSJulian Elischer 	}
160cc391cceSBruce M Simpson 
161a1c2090eSBill Fenner 	/*
162a1c2090eSBill Fenner 	 * Get the TR addresses into a canonical form
163a1c2090eSBill Fenner 	 */
164*ee67461eSJoseph Mingrone 	extract_token_addrs(trp, (char*)srcmac, (char*)dstmac);
165722012ccSJulian Elischer 
166722012ccSJulian Elischer 	/* Adjust for source routing information in the MAC header */
167a1c2090eSBill Fenner 	if (IS_SOURCE_ROUTED(trp)) {
168a1c2090eSBill Fenner 		/* Clear source-routed bit */
169*ee67461eSJoseph Mingrone 		srcmac[0] &= 0x7f;
17014fffcebSLarry Lile 
1713c602fabSXin LI 		if (ndo->ndo_eflag)
172*ee67461eSJoseph Mingrone 			token_hdr_print(ndo, trp, length, srcmac, dstmac);
17314fffcebSLarry Lile 
17427df3f5dSRui Paulo 		if (caplen < TOKEN_HDRLEN + 2) {
175*ee67461eSJoseph Mingrone 			nd_print_trunc(ndo);
17627df3f5dSRui Paulo 			return hdr_len;
17727df3f5dSRui Paulo 		}
178a1c2090eSBill Fenner 		route_len = RIF_LENGTH(trp);
17927df3f5dSRui Paulo 		hdr_len += route_len;
18027df3f5dSRui Paulo 		if (caplen < hdr_len) {
181*ee67461eSJoseph Mingrone 			nd_print_trunc(ndo);
18227df3f5dSRui Paulo 			return hdr_len;
18327df3f5dSRui Paulo 		}
1843c602fabSXin LI 		if (ndo->ndo_vflag) {
185*ee67461eSJoseph Mingrone 			ND_PRINT("%s ", broadcast_indicator[BROADCAST(trp)]);
186*ee67461eSJoseph Mingrone 			ND_PRINT("%s", direction[DIRECTION(trp)]);
18714fffcebSLarry Lile 
188a1c2090eSBill Fenner 			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
189*ee67461eSJoseph Mingrone 				ND_PRINT(" [%u:%u]", RING_NUMBER(trp, seg),
190*ee67461eSJoseph Mingrone 				    BRIDGE_NUMBER(trp, seg));
19114fffcebSLarry Lile 		} else {
192*ee67461eSJoseph Mingrone 			ND_PRINT("rt = %x", GET_BE_U_2(trp->token_rcf));
19314fffcebSLarry Lile 
194a1c2090eSBill Fenner 			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
195*ee67461eSJoseph Mingrone 				ND_PRINT(":%x",
196*ee67461eSJoseph Mingrone 					 GET_BE_U_2(trp->token_rseg[seg]));
19714fffcebSLarry Lile 		}
198*ee67461eSJoseph Mingrone 		ND_PRINT(" (%s) ", largest_frame[LARGEST_FRAME(trp)]);
19914fffcebSLarry Lile 	} else {
2003c602fabSXin LI 		if (ndo->ndo_eflag)
201*ee67461eSJoseph Mingrone 			token_hdr_print(ndo, trp, length, srcmac, dstmac);
202722012ccSJulian Elischer 	}
203722012ccSJulian Elischer 
204*ee67461eSJoseph Mingrone 	src.addr = srcmac;
2053340d773SGleb Smirnoff 	src.addr_string = etheraddr_string;
206*ee67461eSJoseph Mingrone 	dst.addr = dstmac;
2073340d773SGleb Smirnoff 	dst.addr_string = etheraddr_string;
2083340d773SGleb Smirnoff 
209a1c2090eSBill Fenner 	/* Skip over token ring MAC header and routing information */
210cc391cceSBruce M Simpson 	length -= hdr_len;
211cc391cceSBruce M Simpson 	p += hdr_len;
212cc391cceSBruce M Simpson 	caplen -= hdr_len;
213722012ccSJulian Elischer 
214a1c2090eSBill Fenner 	/* Frame Control field determines interpretation of packet */
215a1c2090eSBill Fenner 	if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
216722012ccSJulian Elischer 		/* Try to print the LLC-layer header & higher layers */
2173340d773SGleb Smirnoff 		llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2183340d773SGleb Smirnoff 		if (llc_hdrlen < 0) {
2193340d773SGleb Smirnoff 			/* packet type not known, print raw packet */
2203c602fabSXin LI 			if (!ndo->ndo_suppress_default_print)
2213c602fabSXin LI 				ND_DEFAULTPRINT(p, caplen);
2223340d773SGleb Smirnoff 			llc_hdrlen = -llc_hdrlen;
223722012ccSJulian Elischer 		}
2243340d773SGleb Smirnoff 		hdr_len += llc_hdrlen;
225a1c2090eSBill Fenner 	} else {
226a1c2090eSBill Fenner 		/* Some kinds of TR packet we cannot handle intelligently */
227a1c2090eSBill Fenner 		/* XXX - dissect MAC packets if frame type is 0 */
2283c602fabSXin LI 		if (!ndo->ndo_eflag)
2293c602fabSXin LI 			token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len,
230*ee67461eSJoseph Mingrone 			    srcmac, dstmac);
2313c602fabSXin LI 		if (!ndo->ndo_suppress_default_print)
2323c602fabSXin LI 			ND_DEFAULTPRINT(p, caplen);
233a1c2090eSBill Fenner 	}
234cc391cceSBruce M Simpson 	return (hdr_len);
235cc391cceSBruce M Simpson }
236cc391cceSBruce M Simpson 
237cc391cceSBruce M Simpson /*
238cc391cceSBruce M Simpson  * This is the top level routine of the printer.  'p' points
239cc391cceSBruce M Simpson  * to the TR header of the packet, 'h->ts' is the timestamp,
240c1ad1296SSam Leffler  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
241cc391cceSBruce M Simpson  * is the number of bytes actually captured.
242cc391cceSBruce M Simpson  */
243*ee67461eSJoseph Mingrone void
token_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)2443c602fabSXin LI token_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
245cc391cceSBruce M Simpson {
246*ee67461eSJoseph Mingrone 	ndo->ndo_protocol = "token-ring";
247*ee67461eSJoseph Mingrone 	ndo->ndo_ll_hdr_len += token_print(ndo, p, h->len, h->caplen);
248722012ccSJulian Elischer }
249