2 * Routines for FDDI packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
6 * $Id: packet-fddi.c,v 1.11 1999/03/23 03:14:37 gram Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
40 /* FDDI Frame Control values */
42 #define FDDI_FC_VOID 0x00 /* Void frame */
43 #define FDDI_FC_NRT 0x80 /* Nonrestricted token */
44 #define FDDI_FC_RT 0xc0 /* Restricted token */
45 #define FDDI_FC_MAC 0xc0 /* MAC frame */
46 #define FDDI_FC_SMT 0x40 /* SMT frame */
47 #define FDDI_FC_SMT_INFO 0x41 /* SMT Info */
48 #define FDDI_FC_SMT_NSA 0x4F /* SMT Next station adrs */
49 #define FDDI_FC_SMT_MIN FDDI_FC_SMT_INFO
50 #define FDDI_FC_SMT_MAX FDDI_FC_SMT_NSA
51 #define FDDI_FC_MAC_MIN 0xc1
52 #define FDDI_FC_MAC_BEACON 0xc2 /* MAC Beacon frame */
53 #define FDDI_FC_MAC_CLAIM 0xc3 /* MAC Claim frame */
54 #define FDDI_FC_MAC_MAX 0xcf
55 #define FDDI_FC_LLC_ASYNC 0x50 /* Async. LLC frame */
56 #define FDDI_FC_LLC_ASYNC_MIN FDDI_FC_LLC_ASYNC
57 #define FDDI_FC_LLC_ASYNC_DEF 0x54
58 #define FDDI_FC_LLC_ASYNC_MAX 0x5f
59 #define FDDI_FC_LLC_SYNC 0xd0 /* Sync. LLC frame */
60 #define FDDI_FC_LLC_SYNC_MIN FDDI_FC_LLC_SYNC
61 #define FDDI_FC_LLC_SYNC_MAX 0xd7
62 #define FDDI_FC_IMP_ASYNC 0x60 /* Implementor Async. */
63 #define FDDI_FC_IMP_ASYNC_MIN FDDI_FC_IMP_ASYNC
64 #define FDDI_FC_IMP_ASYNC_MAX 0x6f
65 #define FDDI_FC_IMP_SYNC 0xe0 /* Implementor Synch. */
67 #define FDDI_HEADER_SIZE 13
72 #define FDDI_P_DHOST 1
73 #define FDDI_P_SHOST 7
75 /* On some systems, the FDDI MAC addresses are bit-swapped. */
76 #if !defined(ultrix) && !defined(__alpha) && !defined(__bsdi)
77 #define BIT_SWAPPED_MAC_ADDRS
80 #ifdef BIT_SWAPPED_MAC_ADDRS
81 /* "swaptab[i]" is the value of "i" with the bits reversed. */
82 static u_char swaptab[256] = {
83 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
84 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
85 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
86 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
87 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
88 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
89 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
90 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
91 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
92 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
93 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
94 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
95 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
96 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
97 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
98 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
99 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
100 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
101 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
102 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
103 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
104 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
105 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
106 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
107 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
108 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
109 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
110 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
111 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
112 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
113 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
114 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
118 static void get_mac_addr(u_char *swapped_addr, const u_char *addr)
122 for (i = 0; i < 6; i++) {
123 #ifdef BIT_SWAPPED_MAC_ADDRS
124 swapped_addr[i] = swaptab[addr[i]];
126 swapped_addr[i] = addr[i];
132 capture_fddi(const u_char *pd, guint32 cap_len, packet_counts *ld) {
135 if (cap_len < FDDI_HEADER_SIZE) {
139 offset = FDDI_HEADER_SIZE;
141 fc = (int) pd[FDDI_P_FC];
145 /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
147 case FDDI_FC_LLC_ASYNC + 0 :
148 case FDDI_FC_LLC_ASYNC + 1 :
149 case FDDI_FC_LLC_ASYNC + 2 :
150 case FDDI_FC_LLC_ASYNC + 3 :
151 case FDDI_FC_LLC_ASYNC + 4 :
152 case FDDI_FC_LLC_ASYNC + 5 :
153 case FDDI_FC_LLC_ASYNC + 6 :
154 case FDDI_FC_LLC_ASYNC + 7 :
155 case FDDI_FC_LLC_ASYNC + 8 :
156 case FDDI_FC_LLC_ASYNC + 9 :
157 case FDDI_FC_LLC_ASYNC + 10 :
158 case FDDI_FC_LLC_ASYNC + 11 :
159 case FDDI_FC_LLC_ASYNC + 12 :
160 case FDDI_FC_LLC_ASYNC + 13 :
161 case FDDI_FC_LLC_ASYNC + 14 :
162 case FDDI_FC_LLC_ASYNC + 15 :
163 capture_llc(pd, offset, cap_len, ld);
174 void dissect_fddi(const u_char *pd, frame_data *fd, proto_tree *tree)
179 u_char src[6], dst[6];
181 if (fd->cap_len < FDDI_HEADER_SIZE) {
182 dissect_data(pd, offset, fd, tree);
186 /* Extract the source and destination addresses, possibly bit-swapping
188 get_mac_addr(dst, (u_char *)&pd[FDDI_P_DHOST]);
189 get_mac_addr(src, (u_char *)&pd[FDDI_P_SHOST]);
191 fc = (int) pd[FDDI_P_FC];
193 if (check_col(fd, COL_RES_DL_SRC))
194 col_add_str(fd, COL_RES_DL_SRC, get_ether_name(src));
195 if (check_col(fd, COL_RES_DL_DST))
196 col_add_str(fd, COL_RES_DL_DST, get_ether_name(dst));
197 if (check_col(fd, COL_UNRES_DL_SRC))
198 col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str(src));
199 if (check_col(fd, COL_UNRES_DL_DST))
200 col_add_str(fd, COL_UNRES_DL_DST, ether_to_str(dst));
201 if (check_col(fd, COL_PROTOCOL))
202 col_add_str(fd, COL_PROTOCOL, "N/A");
203 if (check_col(fd, COL_INFO))
204 col_add_str(fd, COL_INFO, "FDDI");
206 offset = FDDI_HEADER_SIZE;
209 ti = proto_tree_add_item(tree, 0, offset,
211 (fc >= FDDI_FC_LLC_ASYNC_MIN && fc <= FDDI_FC_LLC_ASYNC_MAX) ?
212 "Async LLC" : "unsupported FC");
214 fh_tree = proto_tree_new();
215 proto_item_add_subtree(ti, fh_tree, ETT_FDDI);
216 proto_tree_add_item(fh_tree, FDDI_P_FC, 1, "Frame Control: 0x%02x", fc);
217 proto_tree_add_item(fh_tree, FDDI_P_DHOST, 6, "Destination: %s (%s)",
218 ether_to_str(dst), get_ether_name(dst));
219 proto_tree_add_item(fh_tree, FDDI_P_SHOST, 6, "Source: %s (%s)",
220 ether_to_str(src), get_ether_name(src));
225 /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
227 case FDDI_FC_LLC_ASYNC + 0 :
228 case FDDI_FC_LLC_ASYNC + 1 :
229 case FDDI_FC_LLC_ASYNC + 2 :
230 case FDDI_FC_LLC_ASYNC + 3 :
231 case FDDI_FC_LLC_ASYNC + 4 :
232 case FDDI_FC_LLC_ASYNC + 5 :
233 case FDDI_FC_LLC_ASYNC + 6 :
234 case FDDI_FC_LLC_ASYNC + 7 :
235 case FDDI_FC_LLC_ASYNC + 8 :
236 case FDDI_FC_LLC_ASYNC + 9 :
237 case FDDI_FC_LLC_ASYNC + 10 :
238 case FDDI_FC_LLC_ASYNC + 11 :
239 case FDDI_FC_LLC_ASYNC + 12 :
240 case FDDI_FC_LLC_ASYNC + 13 :
241 case FDDI_FC_LLC_ASYNC + 14 :
242 case FDDI_FC_LLC_ASYNC + 15 :
243 dissect_llc(pd, offset, fd, tree);
247 dissect_data(pd, offset, fd, tree);