2 * Routines for FDDI packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
6 * $Id: packet-fddi.c,v 1.9 1999/02/09 00:35:37 guy 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>
45 /* FDDI Frame Control values */
47 #define FDDI_FC_VOID 0x00 /* Void frame */
48 #define FDDI_FC_NRT 0x80 /* Nonrestricted token */
49 #define FDDI_FC_RT 0xc0 /* Restricted token */
50 #define FDDI_FC_MAC 0xc0 /* MAC frame */
51 #define FDDI_FC_SMT 0x40 /* SMT frame */
52 #define FDDI_FC_SMT_INFO 0x41 /* SMT Info */
53 #define FDDI_FC_SMT_NSA 0x4F /* SMT Next station adrs */
54 #define FDDI_FC_SMT_MIN FDDI_FC_SMT_INFO
55 #define FDDI_FC_SMT_MAX FDDI_FC_SMT_NSA
56 #define FDDI_FC_MAC_MIN 0xc1
57 #define FDDI_FC_MAC_BEACON 0xc2 /* MAC Beacon frame */
58 #define FDDI_FC_MAC_CLAIM 0xc3 /* MAC Claim frame */
59 #define FDDI_FC_MAC_MAX 0xcf
60 #define FDDI_FC_LLC_ASYNC 0x50 /* Async. LLC frame */
61 #define FDDI_FC_LLC_ASYNC_MIN FDDI_FC_LLC_ASYNC
62 #define FDDI_FC_LLC_ASYNC_DEF 0x54
63 #define FDDI_FC_LLC_ASYNC_MAX 0x5f
64 #define FDDI_FC_LLC_SYNC 0xd0 /* Sync. LLC frame */
65 #define FDDI_FC_LLC_SYNC_MIN FDDI_FC_LLC_SYNC
66 #define FDDI_FC_LLC_SYNC_MAX 0xd7
67 #define FDDI_FC_IMP_ASYNC 0x60 /* Implementor Async. */
68 #define FDDI_FC_IMP_ASYNC_MIN FDDI_FC_IMP_ASYNC
69 #define FDDI_FC_IMP_ASYNC_MAX 0x6f
70 #define FDDI_FC_IMP_SYNC 0xe0 /* Implementor Synch. */
72 #define FDDI_HEADER_SIZE 13
77 #define FDDI_P_DHOST 1
78 #define FDDI_P_SHOST 7
80 /* On some systems, the FDDI MAC addresses are bit-swapped. */
81 #if !defined(ultrix) && !defined(__alpha) && !defined(__bsdi)
82 #define BIT_SWAPPED_MAC_ADDRS
85 #ifdef BIT_SWAPPED_MAC_ADDRS
86 /* "swaptab[i]" is the value of "i" with the bits reversed. */
87 static u_char swaptab[256] = {
88 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
89 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
90 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
91 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
92 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
93 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
94 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
95 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
96 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
97 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
98 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
99 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
100 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
101 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
102 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
103 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
104 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
105 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
106 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
107 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
108 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
109 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
110 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
111 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
112 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
113 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
114 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
115 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
116 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
117 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
118 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
119 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
123 static void get_mac_addr(u_char *swapped_addr, const u_char *addr)
127 for (i = 0; i < 6; i++) {
128 #ifdef BIT_SWAPPED_MAC_ADDRS
129 swapped_addr[i] = swaptab[addr[i]];
131 swapped_addr[i] = addr[i];
137 capture_fddi(const u_char *pd, guint32 cap_len, packet_counts *ld) {
140 if (cap_len < FDDI_HEADER_SIZE) {
144 offset = FDDI_HEADER_SIZE;
146 fc = (int) pd[FDDI_P_FC];
150 /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
152 case FDDI_FC_LLC_ASYNC + 0 :
153 case FDDI_FC_LLC_ASYNC + 1 :
154 case FDDI_FC_LLC_ASYNC + 2 :
155 case FDDI_FC_LLC_ASYNC + 3 :
156 case FDDI_FC_LLC_ASYNC + 4 :
157 case FDDI_FC_LLC_ASYNC + 5 :
158 case FDDI_FC_LLC_ASYNC + 6 :
159 case FDDI_FC_LLC_ASYNC + 7 :
160 case FDDI_FC_LLC_ASYNC + 8 :
161 case FDDI_FC_LLC_ASYNC + 9 :
162 case FDDI_FC_LLC_ASYNC + 10 :
163 case FDDI_FC_LLC_ASYNC + 11 :
164 case FDDI_FC_LLC_ASYNC + 12 :
165 case FDDI_FC_LLC_ASYNC + 13 :
166 case FDDI_FC_LLC_ASYNC + 14 :
167 case FDDI_FC_LLC_ASYNC + 15 :
168 capture_llc(pd, offset, cap_len, ld);
179 void dissect_fddi(const u_char *pd, frame_data *fd, GtkTree *tree)
182 GtkWidget *fh_tree, *ti;
183 u_char src[6], dst[6];
185 if (fd->cap_len < FDDI_HEADER_SIZE) {
186 dissect_data(pd, offset, fd, tree);
190 /* Extract the source and destination addresses, possibly bit-swapping
192 get_mac_addr(dst, (u_char *)&pd[FDDI_P_DHOST]);
193 get_mac_addr(src, (u_char *)&pd[FDDI_P_SHOST]);
195 fc = (int) pd[FDDI_P_FC];
197 if (check_col(fd, COL_RES_DL_SRC))
198 col_add_str(fd, COL_RES_DL_SRC, get_ether_name(src));
199 if (check_col(fd, COL_RES_DL_DST))
200 col_add_str(fd, COL_RES_DL_DST, get_ether_name(dst));
201 if (check_col(fd, COL_UNRES_DL_SRC))
202 col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str(src));
203 if (check_col(fd, COL_UNRES_DL_DST))
204 col_add_str(fd, COL_UNRES_DL_DST, ether_to_str(dst));
205 if (check_col(fd, COL_PROTOCOL))
206 col_add_str(fd, COL_PROTOCOL, "N/A");
207 if (check_col(fd, COL_INFO))
208 col_add_str(fd, COL_INFO, "FDDI");
211 ti = add_item_to_tree(GTK_WIDGET(tree), 0, offset,
213 (fc >= FDDI_FC_LLC_ASYNC_MIN && fc <= FDDI_FC_LLC_ASYNC_MAX) ?
214 "Async LLC" : "unsupported FC");
216 fh_tree = gtk_tree_new();
217 add_subtree(ti, fh_tree, ETT_FDDI);
218 add_item_to_tree(fh_tree, FDDI_P_FC, 1, "Frame Control: 0x%02x", fc);
219 add_item_to_tree(fh_tree, FDDI_P_DHOST, 6, "Destination: %s (%s)",
220 ether_to_str(dst), get_ether_name(dst));
221 add_item_to_tree(fh_tree, FDDI_P_SHOST, 6, "Source: %s (%s)",
222 ether_to_str(src), get_ether_name(src));
225 offset = FDDI_HEADER_SIZE;
229 /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
231 case FDDI_FC_LLC_ASYNC + 0 :
232 case FDDI_FC_LLC_ASYNC + 1 :
233 case FDDI_FC_LLC_ASYNC + 2 :
234 case FDDI_FC_LLC_ASYNC + 3 :
235 case FDDI_FC_LLC_ASYNC + 4 :
236 case FDDI_FC_LLC_ASYNC + 5 :
237 case FDDI_FC_LLC_ASYNC + 6 :
238 case FDDI_FC_LLC_ASYNC + 7 :
239 case FDDI_FC_LLC_ASYNC + 8 :
240 case FDDI_FC_LLC_ASYNC + 9 :
241 case FDDI_FC_LLC_ASYNC + 10 :
242 case FDDI_FC_LLC_ASYNC + 11 :
243 case FDDI_FC_LLC_ASYNC + 12 :
244 case FDDI_FC_LLC_ASYNC + 13 :
245 case FDDI_FC_LLC_ASYNC + 14 :
246 case FDDI_FC_LLC_ASYNC + 15 :
247 dissect_llc(pd, offset, fd, tree);
251 dissect_data(pd, offset, fd, tree);