144165Sjulian/* 244165Sjulian * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 344165Sjulian * The Regents of the University of California. All rights reserved. 444165Sjulian * 544165Sjulian * Redistribution and use in source and binary forms, with or without 644165Sjulian * modification, are permitted provided that: (1) source code distributions 744165Sjulian * retain the above copyright notice and this paragraph in its entirety, (2) 844165Sjulian * distributions including binary code include the above copyright notice and 944165Sjulian * this paragraph in its entirety in the documentation or other materials 1044165Sjulian * provided with the distribution, and (3) all advertising materials mentioning 1144165Sjulian * features or use of this software display the following acknowledgement: 1244165Sjulian * ``This product includes software developed by the University of California, 1344165Sjulian * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1444165Sjulian * the University nor the names of its contributors may be used to endorse 1544165Sjulian * or promote products derived from this software without specific prior 1644165Sjulian * written permission. 1744165Sjulian * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1844165Sjulian * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1944165Sjulian * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2044165Sjulian * 2144165Sjulian * Hacked version of print-ether.c Larry Lile <lile@stdio.com> 2256896Sfenner * 2398527Sfenner * Further tweaked to more closely resemble print-fddi.c 2498527Sfenner * Guy Harris <guy@alum.mit.edu> 2598527Sfenner * 2656896Sfenner * $FreeBSD$ 2744165Sjulian */ 2844165Sjulian#ifndef lint 29127675Sbmsstatic const char rcsid[] _U_ = 30190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $"; 3144165Sjulian#endif 3244165Sjulian 3398527Sfenner#ifdef HAVE_CONFIG_H 3498527Sfenner#include "config.h" 3598527Sfenner#endif 3698527Sfenner 37127675Sbms#include <tcpdump-stdinc.h> 3844165Sjulian 3998527Sfenner#include <pcap.h> 4044165Sjulian#include <stdio.h> 4198527Sfenner#include <string.h> 4244165Sjulian 4344165Sjulian#include "interface.h" 44214478Srpaulo#include "extract.h" 4544165Sjulian#include "addrtoname.h" 4644165Sjulian#include "ethertype.h" 4744165Sjulian 4898527Sfenner#include "ether.h" 4998527Sfenner#include "token.h" 5044165Sjulian 5198527Sfenner/* Extract src, dst addresses */ 5244165Sjulianstatic inline void 5398527Sfennerextract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) 5444165Sjulian{ 5598527Sfenner memcpy(fdst, (const char *)trp->token_dhost, 6); 5698527Sfenner memcpy(fsrc, (const char *)trp->token_shost, 6); 5798527Sfenner} 5844165Sjulian 5998527Sfenner/* 6098527Sfenner * Print the TR MAC header 6198527Sfenner */ 6298527Sfennerstatic inline void 63127675Sbmstoken_hdr_print(register const struct token_header *trp, register u_int length, 6498527Sfenner register const u_char *fsrc, register const u_char *fdst) 6598527Sfenner{ 6698527Sfenner const char *srcname, *dstname; 6750514Slile 6898527Sfenner srcname = etheraddr_string(fsrc); 6998527Sfenner dstname = etheraddr_string(fdst); 7044165Sjulian 7198527Sfenner if (vflag) 7298527Sfenner (void) printf("%02x %02x %s %s %d: ", 7398527Sfenner trp->token_ac, 7498527Sfenner trp->token_fc, 7598527Sfenner srcname, dstname, 7698527Sfenner length); 7744165Sjulian else 7898527Sfenner printf("%s %s %d: ", srcname, dstname, length); 7944165Sjulian} 8044165Sjulian 8198527Sfennerstatic const char *broadcast_indicator[] = { 8298527Sfenner "Non-Broadcast", "Non-Broadcast", 8398527Sfenner "Non-Broadcast", "Non-Broadcast", 8498527Sfenner "All-routes", "All-routes", 8598527Sfenner "Single-route", "Single-route" 8698527Sfenner}; 8798527Sfenner 8898527Sfennerstatic const char *direction[] = { 8998527Sfenner "Forward", "Backward" 9098527Sfenner}; 9198527Sfenner 9298527Sfennerstatic const char *largest_frame[] = { 9398527Sfenner "516", 9498527Sfenner "1500", 9598527Sfenner "2052", 9698527Sfenner "4472", 9798527Sfenner "8144", 9898527Sfenner "11407", 9998527Sfenner "17800", 10098527Sfenner "??" 10198527Sfenner}; 10298527Sfenner 103127675Sbmsu_int 104127675Sbmstoken_print(const u_char *p, u_int length, u_int caplen) 10544165Sjulian{ 10698527Sfenner const struct token_header *trp; 10756896Sfenner u_short extracted_ethertype; 10898527Sfenner struct ether_header ehdr; 109127675Sbms u_int route_len = 0, hdr_len = TOKEN_HDRLEN; 110127675Sbms int seg; 11144165Sjulian 11298527Sfenner trp = (const struct token_header *)p; 11344165Sjulian 11498527Sfenner if (caplen < TOKEN_HDRLEN) { 11544165Sjulian printf("[|token-ring]"); 116127675Sbms return hdr_len; 11744165Sjulian } 118127675Sbms 11944165Sjulian /* 12098527Sfenner * Get the TR addresses into a canonical form 12198527Sfenner */ 12298527Sfenner extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); 12344165Sjulian 12498527Sfenner /* Adjust for source routing information in the MAC header */ 12598527Sfenner if (IS_SOURCE_ROUTED(trp)) { 12698527Sfenner /* Clear source-routed bit */ 12798527Sfenner *ESRC(&ehdr) &= 0x7f; 12850514Slile 12998527Sfenner if (eflag) 130127675Sbms token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 13150514Slile 132214478Srpaulo if (caplen < TOKEN_HDRLEN + 2) { 133214478Srpaulo printf("[|token-ring]"); 134214478Srpaulo return hdr_len; 135214478Srpaulo } 13698527Sfenner route_len = RIF_LENGTH(trp); 137214478Srpaulo hdr_len += route_len; 138214478Srpaulo if (caplen < hdr_len) { 139214478Srpaulo printf("[|token-ring]"); 140214478Srpaulo return hdr_len; 141214478Srpaulo } 14298527Sfenner if (vflag) { 14398527Sfenner printf("%s ", broadcast_indicator[BROADCAST(trp)]); 14498527Sfenner printf("%s", direction[DIRECTION(trp)]); 145127675Sbms 14698527Sfenner for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 14798527Sfenner printf(" [%d:%d]", RING_NUMBER(trp, seg), 14898527Sfenner BRIDGE_NUMBER(trp, seg)); 14998527Sfenner } else { 150214478Srpaulo printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf)); 151127675Sbms 15298527Sfenner for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 153214478Srpaulo printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg])); 15498527Sfenner } 15598527Sfenner printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); 15698527Sfenner } else { 15798527Sfenner if (eflag) 158127675Sbms token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 15998527Sfenner } 16044165Sjulian 16198527Sfenner /* Skip over token ring MAC header and routing information */ 162127675Sbms length -= hdr_len; 163127675Sbms p += hdr_len; 164127675Sbms caplen -= hdr_len; 16544165Sjulian 16698527Sfenner /* Frame Control field determines interpretation of packet */ 16798527Sfenner if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { 16898527Sfenner /* Try to print the LLC-layer header & higher layers */ 16998527Sfenner if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), 17098527Sfenner &extracted_ethertype) == 0) { 17198527Sfenner /* ether_type not known, print raw packet */ 17298527Sfenner if (!eflag) 173127675Sbms token_hdr_print(trp, 17498527Sfenner length + TOKEN_HDRLEN + route_len, 17598527Sfenner ESRC(&ehdr), EDST(&ehdr)); 17698527Sfenner if (extracted_ethertype) { 17798527Sfenner printf("(LLC %s) ", 17898527Sfenner etherproto_string(htons(extracted_ethertype))); 17998527Sfenner } 180162021Ssam if (!suppress_default_print) 18198527Sfenner default_print(p, caplen); 18298527Sfenner } 18398527Sfenner } else { 18498527Sfenner /* Some kinds of TR packet we cannot handle intelligently */ 18598527Sfenner /* XXX - dissect MAC packets if frame type is 0 */ 18644165Sjulian if (!eflag) 187127675Sbms token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, 18898527Sfenner ESRC(&ehdr), EDST(&ehdr)); 189162021Ssam if (!suppress_default_print) 19044165Sjulian default_print(p, caplen); 19144165Sjulian } 192127675Sbms return (hdr_len); 19344165Sjulian} 194127675Sbms 195127675Sbms/* 196127675Sbms * This is the top level routine of the printer. 'p' points 197127675Sbms * to the TR header of the packet, 'h->ts' is the timestamp, 198146778Ssam * 'h->len' is the length of the packet off the wire, and 'h->caplen' 199127675Sbms * is the number of bytes actually captured. 200127675Sbms */ 201127675Sbmsu_int 202127675Sbmstoken_if_print(const struct pcap_pkthdr *h, const u_char *p) 203127675Sbms{ 204127675Sbms return (token_print(p, h->len, h->caplen)); 205127675Sbms} 206