12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Hacked version of print-ether.c  Larry Lile <lile@stdio.com>
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Further tweaked to more closely resemble print-fddi.c
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	Guy Harris <guy@alum.mit.edu>
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
2853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $";
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <pcap.h>
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
4253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "extract.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ethertype.h"
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ether.h"
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "token.h"
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Extract src, dst addresses */
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic inline void
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectextract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst)
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(fdst, (const char *)trp->token_dhost, 6);
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(fsrc, (const char *)trp->token_shost, 6);
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print the TR MAC header
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic inline void
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttoken_hdr_print(register const struct token_header *trp, register u_int length,
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	   register const u_char *fsrc, register const u_char *fdst)
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const char *srcname, *dstname;
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	srcname = etheraddr_string(fsrc);
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dstname = etheraddr_string(fdst);
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (vflag)
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		(void) printf("%02x %02x %s %s %d: ",
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       trp->token_ac,
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       trp->token_fc,
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       srcname, dstname,
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		       length);
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	else
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("%s %s %d: ", srcname, dstname, length);
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *broadcast_indicator[] = {
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"Non-Broadcast", "Non-Broadcast",
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"Non-Broadcast", "Non-Broadcast",
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"All-routes",    "All-routes",
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"Single-route",  "Single-route"
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *direction[] = {
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"Forward", "Backward"
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char *largest_frame[] = {
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"516",
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"1500",
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"2052",
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"4472",
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"8144",
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"11407",
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"17800",
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	"??"
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttoken_print(const u_char *p, u_int length, u_int caplen)
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct token_header *trp;
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_short extracted_ethertype;
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ether_header ehdr;
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int seg;
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	trp = (const struct token_header *)p;
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (caplen < TOKEN_HDRLEN) {
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[|token-ring]");
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return hdr_len;
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/*
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 * Get the TR addresses into a canonical form
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 */
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr));
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Adjust for source routing information in the MAC header */
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (IS_SOURCE_ROUTED(trp)) {
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Clear source-routed bit */
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		*ESRC(&ehdr) &= 0x7f;
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (eflag)
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
13053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (caplen < TOKEN_HDRLEN + 2) {
13153f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf("[|token-ring]");
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return hdr_len;
13353f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		route_len = RIF_LENGTH(trp);
13553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		hdr_len += route_len;
13653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (caplen < hdr_len) {
13753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf("[|token-ring]");
13853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			return hdr_len;
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (vflag) {
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%s ", broadcast_indicator[BROADCAST(trp)]);
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%s", direction[DIRECTION(trp)]);
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" [%d:%d]", RING_NUMBER(trp, seg),
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    BRIDGE_NUMBER(trp, seg));
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		} else {
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall			printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf));
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall				printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg]));
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]);
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else {
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (eflag)
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Skip over token ring MAC header and routing information */
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	length -= hdr_len;
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p += hdr_len;
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	caplen -= hdr_len;
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Frame Control field determines interpretation of packet */
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Try to print the LLC-layer header & higher layers */
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    &extracted_ethertype) == 0) {
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* ether_type not known, print raw packet */
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!eflag)
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				token_hdr_print(trp,
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    length + TOKEN_HDRLEN + route_len,
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				    ESRC(&ehdr), EDST(&ehdr));
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (extracted_ethertype) {
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf("(LLC %s) ",
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			etherproto_string(htons(extracted_ethertype)));
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			}
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (!suppress_default_print)
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				default_print(p, caplen);
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	} else {
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* Some kinds of TR packet we cannot handle intelligently */
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* XXX - dissect MAC packets if frame type is 0 */
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!eflag)
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			token_hdr_print(trp, length + TOKEN_HDRLEN + route_len,
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    ESRC(&ehdr), EDST(&ehdr));
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!suppress_default_print)
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default_print(p, caplen);
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (hdr_len);
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * This is the top level routine of the printer.  'p' points
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * to the TR header of the packet, 'h->ts' is the timestamp,
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * is the number of bytes actually captured.
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttoken_if_print(const struct pcap_pkthdr *h, const u_char *p)
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (token_print(p, h->len, h->caplen));
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
204