1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Hacked version of print-ether.c Larry Lile <lile (at) stdio.com> 22 * 23 * Further tweaked to more closely resemble print-fddi.c 24 * Guy Harris <guy (at) alum.mit.edu> 25 */ 26 #ifndef lint 27 static const char rcsid[] _U_ = 28 "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $"; 29 #endif 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 35 #include <tcpdump-stdinc.h> 36 37 #include <pcap.h> 38 #include <stdio.h> 39 #include <string.h> 40 41 #include "interface.h" 42 #include "extract.h" 43 #include "addrtoname.h" 44 #include "ethertype.h" 45 46 #include "ether.h" 47 #include "token.h" 48 49 /* Extract src, dst addresses */ 50 static inline void 51 extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) 52 { 53 memcpy(fdst, (const char *)trp->token_dhost, 6); 54 memcpy(fsrc, (const char *)trp->token_shost, 6); 55 } 56 57 /* 58 * Print the TR MAC header 59 */ 60 static inline void 61 token_hdr_print(register const struct token_header *trp, register u_int length, 62 register const u_char *fsrc, register const u_char *fdst) 63 { 64 const char *srcname, *dstname; 65 66 srcname = etheraddr_string(fsrc); 67 dstname = etheraddr_string(fdst); 68 69 if (vflag) 70 (void) printf("%02x %02x %s %s %d: ", 71 trp->token_ac, 72 trp->token_fc, 73 srcname, dstname, 74 length); 75 else 76 printf("%s %s %d: ", srcname, dstname, length); 77 } 78 79 static const char *broadcast_indicator[] = { 80 "Non-Broadcast", "Non-Broadcast", 81 "Non-Broadcast", "Non-Broadcast", 82 "All-routes", "All-routes", 83 "Single-route", "Single-route" 84 }; 85 86 static const char *direction[] = { 87 "Forward", "Backward" 88 }; 89 90 static const char *largest_frame[] = { 91 "516", 92 "1500", 93 "2052", 94 "4472", 95 "8144", 96 "11407", 97 "17800", 98 "??" 99 }; 100 101 u_int 102 token_print(const u_char *p, u_int length, u_int caplen) 103 { 104 const struct token_header *trp; 105 u_short extracted_ethertype; 106 struct ether_header ehdr; 107 u_int route_len = 0, hdr_len = TOKEN_HDRLEN; 108 int seg; 109 110 trp = (const struct token_header *)p; 111 112 if (caplen < TOKEN_HDRLEN) { 113 printf("[|token-ring]"); 114 return hdr_len; 115 } 116 117 /* 118 * Get the TR addresses into a canonical form 119 */ 120 extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); 121 122 /* Adjust for source routing information in the MAC header */ 123 if (IS_SOURCE_ROUTED(trp)) { 124 /* Clear source-routed bit */ 125 *ESRC(&ehdr) &= 0x7f; 126 127 if (eflag) 128 token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 129 130 if (caplen < TOKEN_HDRLEN + 2) { 131 printf("[|token-ring]"); 132 return hdr_len; 133 } 134 route_len = RIF_LENGTH(trp); 135 hdr_len += route_len; 136 if (caplen < hdr_len) { 137 printf("[|token-ring]"); 138 return hdr_len; 139 } 140 if (vflag) { 141 printf("%s ", broadcast_indicator[BROADCAST(trp)]); 142 printf("%s", direction[DIRECTION(trp)]); 143 144 for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 145 printf(" [%d:%d]", RING_NUMBER(trp, seg), 146 BRIDGE_NUMBER(trp, seg)); 147 } else { 148 printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf)); 149 150 for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 151 printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg])); 152 } 153 printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); 154 } else { 155 if (eflag) 156 token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 157 } 158 159 /* Skip over token ring MAC header and routing information */ 160 length -= hdr_len; 161 p += hdr_len; 162 caplen -= hdr_len; 163 164 /* Frame Control field determines interpretation of packet */ 165 if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { 166 /* Try to print the LLC-layer header & higher layers */ 167 if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), 168 &extracted_ethertype) == 0) { 169 /* ether_type not known, print raw packet */ 170 if (!eflag) 171 token_hdr_print(trp, 172 length + TOKEN_HDRLEN + route_len, 173 ESRC(&ehdr), EDST(&ehdr)); 174 if (extracted_ethertype) { 175 printf("(LLC %s) ", 176 etherproto_string(htons(extracted_ethertype))); 177 } 178 if (!suppress_default_print) 179 default_print(p, caplen); 180 } 181 } else { 182 /* Some kinds of TR packet we cannot handle intelligently */ 183 /* XXX - dissect MAC packets if frame type is 0 */ 184 if (!eflag) 185 token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, 186 ESRC(&ehdr), EDST(&ehdr)); 187 if (!suppress_default_print) 188 default_print(p, caplen); 189 } 190 return (hdr_len); 191 } 192 193 /* 194 * This is the top level routine of the printer. 'p' points 195 * to the TR header of the packet, 'h->ts' is the timestamp, 196 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 197 * is the number of bytes actually captured. 198 */ 199 u_int 200 token_if_print(const struct pcap_pkthdr *h, const u_char *p) 201 { 202 return (token_print(p, h->len, h->caplen)); 203 } 204