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 29a1c2090eSBill Fenner #ifdef HAVE_CONFIG_H 30*ee67461eSJoseph Mingrone #include <config.h> 31722012ccSJulian Elischer #endif 32722012ccSJulian Elischer 33*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 34722012ccSJulian Elischer 35a1c2090eSBill Fenner #include <string.h> 36722012ccSJulian Elischer 373340d773SGleb Smirnoff #include "netdissect.h" 3827df3f5dSRui Paulo #include "extract.h" 39722012ccSJulian Elischer #include "addrtoname.h" 403c602fabSXin LI 413c602fabSXin LI /* 423c602fabSXin LI * Copyright (c) 1998, Larry Lile 433c602fabSXin LI * All rights reserved. 443c602fabSXin LI * 453c602fabSXin LI * Redistribution and use in source and binary forms, with or without 463c602fabSXin LI * modification, are permitted provided that the following conditions 473c602fabSXin LI * are met: 483c602fabSXin LI * 1. Redistributions of source code must retain the above copyright 493c602fabSXin LI * notice unmodified, this list of conditions, and the following 503c602fabSXin LI * disclaimer. 513c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright 523c602fabSXin LI * notice, this list of conditions and the following disclaimer in the 533c602fabSXin LI * documentation and/or other materials provided with the distribution. 543c602fabSXin LI * 553c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 563c602fabSXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 573c602fabSXin LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 583c602fabSXin LI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 593c602fabSXin LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 603c602fabSXin LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 613c602fabSXin LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 623c602fabSXin LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 633c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 643c602fabSXin LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 653c602fabSXin LI * SUCH DAMAGE. 663c602fabSXin LI * 673c602fabSXin LI */ 683c602fabSXin LI 693c602fabSXin LI #define TOKEN_HDRLEN 14 703c602fabSXin LI #define ROUTING_SEGMENT_MAX 16 713c602fabSXin LI #define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80) 72*ee67461eSJoseph Mingrone #define FRAME_TYPE(trp) ((GET_U_1((trp)->token_fc) & 0xC0) >> 6) 733c602fabSXin LI #define TOKEN_FC_LLC 1 743c602fabSXin LI 75*ee67461eSJoseph Mingrone #define BROADCAST(trp) ((GET_BE_U_2((trp)->token_rcf) & 0xE000) >> 13) 76*ee67461eSJoseph Mingrone #define RIF_LENGTH(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x1f00) >> 8) 77*ee67461eSJoseph Mingrone #define DIRECTION(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x0080) >> 7) 78*ee67461eSJoseph Mingrone #define LARGEST_FRAME(trp) ((GET_BE_U_2((trp)->token_rcf) & 0x0070) >> 4) 79*ee67461eSJoseph Mingrone #define RING_NUMBER(trp, x) ((GET_BE_U_2((trp)->token_rseg[x]) & 0xfff0) >> 4) 80*ee67461eSJoseph Mingrone #define BRIDGE_NUMBER(trp, x) (GET_BE_U_2((trp)->token_rseg[x]) & 0x000f) 813c602fabSXin LI #define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) 823c602fabSXin LI 833c602fabSXin LI struct token_header { 84*ee67461eSJoseph Mingrone nd_uint8_t token_ac; 85*ee67461eSJoseph Mingrone nd_uint8_t token_fc; 86*ee67461eSJoseph Mingrone nd_mac_addr token_dhost; 87*ee67461eSJoseph Mingrone nd_mac_addr token_shost; 88*ee67461eSJoseph Mingrone nd_uint16_t token_rcf; 89*ee67461eSJoseph Mingrone nd_uint16_t token_rseg[ROUTING_SEGMENT_MAX]; 903c602fabSXin LI }; 913c602fabSXin LI 92722012ccSJulian Elischer 93a1c2090eSBill Fenner /* Extract src, dst addresses */ 94*ee67461eSJoseph Mingrone static void 95a1c2090eSBill Fenner extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) 96722012ccSJulian Elischer { 97a1c2090eSBill Fenner memcpy(fdst, (const char *)trp->token_dhost, 6); 98a1c2090eSBill Fenner memcpy(fsrc, (const char *)trp->token_shost, 6); 9914fffcebSLarry Lile } 100722012ccSJulian Elischer 101722012ccSJulian Elischer /* 102a1c2090eSBill Fenner * Print the TR MAC header 103722012ccSJulian Elischer */ 104*ee67461eSJoseph Mingrone static void 1053c602fabSXin LI token_hdr_print(netdissect_options *ndo, 106*ee67461eSJoseph Mingrone const struct token_header *trp, u_int length, 107*ee67461eSJoseph Mingrone const u_char *fsrc, const u_char *fdst) 108a1c2090eSBill Fenner { 109a1c2090eSBill Fenner const char *srcname, *dstname; 110722012ccSJulian Elischer 1113c602fabSXin LI srcname = etheraddr_string(ndo, fsrc); 1123c602fabSXin LI dstname = etheraddr_string(ndo, fdst); 113a1c2090eSBill Fenner 1143340d773SGleb Smirnoff if (!ndo->ndo_qflag) 115*ee67461eSJoseph Mingrone ND_PRINT("%02x %02x ", 116*ee67461eSJoseph Mingrone GET_U_1(trp->token_ac), 117*ee67461eSJoseph Mingrone GET_U_1(trp->token_fc)); 118*ee67461eSJoseph Mingrone ND_PRINT("%s > %s, length %u: ", 119a1c2090eSBill Fenner srcname, dstname, 120*ee67461eSJoseph Mingrone length); 121722012ccSJulian Elischer } 122722012ccSJulian Elischer 123a1c2090eSBill Fenner static const char *broadcast_indicator[] = { 124a1c2090eSBill Fenner "Non-Broadcast", "Non-Broadcast", 125a1c2090eSBill Fenner "Non-Broadcast", "Non-Broadcast", 126a1c2090eSBill Fenner "All-routes", "All-routes", 127a1c2090eSBill Fenner "Single-route", "Single-route" 128a1c2090eSBill Fenner }; 129a1c2090eSBill Fenner 130a1c2090eSBill Fenner static const char *direction[] = { 131a1c2090eSBill Fenner "Forward", "Backward" 132a1c2090eSBill Fenner }; 133a1c2090eSBill Fenner 134a1c2090eSBill Fenner static const char *largest_frame[] = { 135a1c2090eSBill Fenner "516", 136a1c2090eSBill Fenner "1500", 137a1c2090eSBill Fenner "2052", 138a1c2090eSBill Fenner "4472", 139a1c2090eSBill Fenner "8144", 140a1c2090eSBill Fenner "11407", 141a1c2090eSBill Fenner "17800", 142a1c2090eSBill Fenner "??" 143a1c2090eSBill Fenner }; 144a1c2090eSBill Fenner 145cc391cceSBruce M Simpson u_int 1463c602fabSXin LI token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) 147722012ccSJulian Elischer { 148a1c2090eSBill Fenner const struct token_header *trp; 1493340d773SGleb Smirnoff int llc_hdrlen; 150*ee67461eSJoseph Mingrone nd_mac_addr srcmac, dstmac; 1513340d773SGleb Smirnoff struct lladdr_info src, dst; 152cc391cceSBruce M Simpson u_int route_len = 0, hdr_len = TOKEN_HDRLEN; 153cc391cceSBruce M Simpson int seg; 154722012ccSJulian Elischer 155*ee67461eSJoseph Mingrone ndo->ndo_protocol = "token-ring"; 156a1c2090eSBill Fenner trp = (const struct token_header *)p; 157722012ccSJulian Elischer 158a1c2090eSBill Fenner if (caplen < TOKEN_HDRLEN) { 159*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 160cc391cceSBruce M Simpson return hdr_len; 161722012ccSJulian Elischer } 162cc391cceSBruce M Simpson 163a1c2090eSBill Fenner /* 164a1c2090eSBill Fenner * Get the TR addresses into a canonical form 165a1c2090eSBill Fenner */ 166*ee67461eSJoseph Mingrone extract_token_addrs(trp, (char*)srcmac, (char*)dstmac); 167722012ccSJulian Elischer 168722012ccSJulian Elischer /* Adjust for source routing information in the MAC header */ 169a1c2090eSBill Fenner if (IS_SOURCE_ROUTED(trp)) { 170a1c2090eSBill Fenner /* Clear source-routed bit */ 171*ee67461eSJoseph Mingrone srcmac[0] &= 0x7f; 17214fffcebSLarry Lile 1733c602fabSXin LI if (ndo->ndo_eflag) 174*ee67461eSJoseph Mingrone token_hdr_print(ndo, trp, length, srcmac, dstmac); 17514fffcebSLarry Lile 17627df3f5dSRui Paulo if (caplen < TOKEN_HDRLEN + 2) { 177*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 17827df3f5dSRui Paulo return hdr_len; 17927df3f5dSRui Paulo } 180a1c2090eSBill Fenner route_len = RIF_LENGTH(trp); 18127df3f5dSRui Paulo hdr_len += route_len; 18227df3f5dSRui Paulo if (caplen < hdr_len) { 183*ee67461eSJoseph Mingrone nd_print_trunc(ndo); 18427df3f5dSRui Paulo return hdr_len; 18527df3f5dSRui Paulo } 1863c602fabSXin LI if (ndo->ndo_vflag) { 187*ee67461eSJoseph Mingrone ND_PRINT("%s ", broadcast_indicator[BROADCAST(trp)]); 188*ee67461eSJoseph Mingrone ND_PRINT("%s", direction[DIRECTION(trp)]); 18914fffcebSLarry Lile 190a1c2090eSBill Fenner for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 191*ee67461eSJoseph Mingrone ND_PRINT(" [%u:%u]", RING_NUMBER(trp, seg), 192*ee67461eSJoseph Mingrone BRIDGE_NUMBER(trp, seg)); 19314fffcebSLarry Lile } else { 194*ee67461eSJoseph Mingrone ND_PRINT("rt = %x", GET_BE_U_2(trp->token_rcf)); 19514fffcebSLarry Lile 196a1c2090eSBill Fenner for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) 197*ee67461eSJoseph Mingrone ND_PRINT(":%x", 198*ee67461eSJoseph Mingrone GET_BE_U_2(trp->token_rseg[seg])); 19914fffcebSLarry Lile } 200*ee67461eSJoseph Mingrone ND_PRINT(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); 20114fffcebSLarry Lile } else { 2023c602fabSXin LI if (ndo->ndo_eflag) 203*ee67461eSJoseph Mingrone token_hdr_print(ndo, trp, length, srcmac, dstmac); 204722012ccSJulian Elischer } 205722012ccSJulian Elischer 206*ee67461eSJoseph Mingrone src.addr = srcmac; 2073340d773SGleb Smirnoff src.addr_string = etheraddr_string; 208*ee67461eSJoseph Mingrone dst.addr = dstmac; 2093340d773SGleb Smirnoff dst.addr_string = etheraddr_string; 2103340d773SGleb Smirnoff 211a1c2090eSBill Fenner /* Skip over token ring MAC header and routing information */ 212cc391cceSBruce M Simpson length -= hdr_len; 213cc391cceSBruce M Simpson p += hdr_len; 214cc391cceSBruce M Simpson caplen -= hdr_len; 215722012ccSJulian Elischer 216a1c2090eSBill Fenner /* Frame Control field determines interpretation of packet */ 217a1c2090eSBill Fenner if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { 218722012ccSJulian Elischer /* Try to print the LLC-layer header & higher layers */ 2193340d773SGleb Smirnoff llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 2203340d773SGleb Smirnoff if (llc_hdrlen < 0) { 2213340d773SGleb Smirnoff /* packet type not known, print raw packet */ 2223c602fabSXin LI if (!ndo->ndo_suppress_default_print) 2233c602fabSXin LI ND_DEFAULTPRINT(p, caplen); 2243340d773SGleb Smirnoff llc_hdrlen = -llc_hdrlen; 225722012ccSJulian Elischer } 2263340d773SGleb Smirnoff hdr_len += llc_hdrlen; 227a1c2090eSBill Fenner } else { 228a1c2090eSBill Fenner /* Some kinds of TR packet we cannot handle intelligently */ 229a1c2090eSBill Fenner /* XXX - dissect MAC packets if frame type is 0 */ 2303c602fabSXin LI if (!ndo->ndo_eflag) 2313c602fabSXin LI token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len, 232*ee67461eSJoseph Mingrone srcmac, dstmac); 2333c602fabSXin LI if (!ndo->ndo_suppress_default_print) 2343c602fabSXin LI ND_DEFAULTPRINT(p, caplen); 235a1c2090eSBill Fenner } 236cc391cceSBruce M Simpson return (hdr_len); 237cc391cceSBruce M Simpson } 238cc391cceSBruce M Simpson 239cc391cceSBruce M Simpson /* 240cc391cceSBruce M Simpson * This is the top level routine of the printer. 'p' points 241cc391cceSBruce M Simpson * to the TR header of the packet, 'h->ts' is the timestamp, 242c1ad1296SSam Leffler * 'h->len' is the length of the packet off the wire, and 'h->caplen' 243cc391cceSBruce M Simpson * is the number of bytes actually captured. 244cc391cceSBruce M Simpson */ 245*ee67461eSJoseph Mingrone void 2463c602fabSXin LI token_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) 247cc391cceSBruce M Simpson { 248*ee67461eSJoseph Mingrone ndo->ndo_protocol = "token-ring"; 249*ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len += token_print(ndo, p, h->len, h->caplen); 250722012ccSJulian Elischer } 251