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@stdio.com> 22 * 23 * Further tweaked to more closely resemble print-fddi.c 24 * Guy Harris <guy@alum.mit.edu> 25 * 26 * $FreeBSD$ 27 */ 28 #ifndef lint 29 static const char rcsid[] = 30 "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.13 2001/09/18 15:46:37 fenner Exp $"; 31 #endif 32 33 #ifdef HAVE_CONFIG_H 34 #include "config.h" 35 #endif 36 37 #include <sys/param.h> 38 #include <sys/time.h> 39 #include <sys/socket.h> 40 41 #include <netinet/in.h> 42 43 #include <pcap.h> 44 #include <stdio.h> 45 #include <string.h> 46 47 #include "interface.h" 48 #include "addrtoname.h" 49 #include "ethertype.h" 50 51 #include "ether.h" 52 #include "token.h" 53 54 /* Extract src, dst addresses */ 55 static inline void 56 extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) 57 { 58 memcpy(fdst, (const char *)trp->token_dhost, 6); 59 memcpy(fsrc, (const char *)trp->token_shost, 6); 60 } 61 62 /* 63 * Print the TR MAC header 64 */ 65 static inline void 66 token_print(register const struct token_header *trp, register u_int length, 67 register const u_char *fsrc, register const u_char *fdst) 68 { 69 const char *srcname, *dstname; 70 71 srcname = etheraddr_string(fsrc); 72 dstname = etheraddr_string(fdst); 73 74 if (vflag) 75 (void) printf("%02x %02x %s %s %d: ", 76 trp->token_ac, 77 trp->token_fc, 78 srcname, dstname, 79 length); 80 else 81 printf("%s %s %d: ", srcname, dstname, length); 82 } 83 84 static const char *broadcast_indicator[] = { 85 "Non-Broadcast", "Non-Broadcast", 86 "Non-Broadcast", "Non-Broadcast", 87 "All-routes", "All-routes", 88 "Single-route", "Single-route" 89 }; 90 91 static const char *direction[] = { 92 "Forward", "Backward" 93 }; 94 95 static const char *largest_frame[] = { 96 "516", 97 "1500", 98 "2052", 99 "4472", 100 "8144", 101 "11407", 102 "17800", 103 "??" 104 }; 105 106 /* 107 * This is the top level routine of the printer. 'p' is the points 108 * to the TR header of the packet, 'tvp' is the timestamp, 109 * 'length' is the length of the packet off the wire, and 'caplen' 110 * is the number of bytes actually captured. 111 */ 112 void 113 token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 114 { 115 u_int caplen = h->caplen; 116 u_int length = h->len; 117 const struct token_header *trp; 118 u_short extracted_ethertype; 119 struct ether_header ehdr; 120 u_int route_len = 0, seg; 121 122 trp = (const struct token_header *)p; 123 124 ++infodelay; 125 ts_print(&h->ts); 126 127 if (caplen < TOKEN_HDRLEN) { 128 printf("[|token-ring]"); 129 goto out; 130 } 131 /* 132 * Get the TR addresses into a canonical form 133 */ 134 extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); 135 /* 136 * Some printers want to get back at the ethernet addresses, 137 * and/or check that they're not walking off the end of the packet. 138 * Rather than pass them all the way down, we set these globals. 139 */ 140 snapend = p + caplen; 141 /* 142 * Actually, the only printers that use packetp are print-arp.c 143 * and print-bootp.c, and they assume that packetp points to an 144 * Ethernet header. The right thing to do is to fix them to know 145 * which link type is in use when they excavate. XXX 146 */ 147 packetp = (u_char *)&ehdr; 148 149 /* Adjust for source routing information in the MAC header */ 150 if (IS_SOURCE_ROUTED(trp)) { 151 /* Clear source-routed bit */ 152 *ESRC(&ehdr) &= 0x7f; 153 154 if (eflag) 155 token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 156 157 route_len = RIF_LENGTH(trp); 158 if (vflag) { 159 printf("%s ", broadcast_indicator[BROADCAST(trp)]); 160 printf("%s", direction[DIRECTION(trp)]); 161 162 for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 163 printf(" [%d:%d]", RING_NUMBER(trp, seg), 164 BRIDGE_NUMBER(trp, seg)); 165 } else { 166 printf("rt = %x", ntohs(trp->token_rcf)); 167 168 for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 169 printf(":%x", ntohs(trp->token_rseg[seg])); 170 } 171 printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); 172 } else { 173 if (eflag) 174 token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); 175 } 176 177 /* Skip over token ring MAC header and routing information */ 178 length -= TOKEN_HDRLEN + route_len; 179 p += TOKEN_HDRLEN + route_len; 180 caplen -= TOKEN_HDRLEN + route_len; 181 182 /* Frame Control field determines interpretation of packet */ 183 extracted_ethertype = 0; 184 if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { 185 /* Try to print the LLC-layer header & higher layers */ 186 if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), 187 &extracted_ethertype) == 0) { 188 /* ether_type not known, print raw packet */ 189 if (!eflag) 190 token_print(trp, 191 length + TOKEN_HDRLEN + route_len, 192 ESRC(&ehdr), EDST(&ehdr)); 193 if (extracted_ethertype) { 194 printf("(LLC %s) ", 195 etherproto_string(htons(extracted_ethertype))); 196 } 197 if (!xflag && !qflag) 198 default_print(p, caplen); 199 } 200 } else { 201 /* Some kinds of TR packet we cannot handle intelligently */ 202 /* XXX - dissect MAC packets if frame type is 0 */ 203 if (!eflag) 204 token_print(trp, length + TOKEN_HDRLEN + route_len, 205 ESRC(&ehdr), EDST(&ehdr)); 206 if (!xflag && !qflag) 207 default_print(p, caplen); 208 } 209 if (xflag) 210 default_print(p, caplen); 211 out: 212 putchar('\n'); 213 --infodelay; 214 if (infoprint) 215 info(0); 216 } 217