2 * Routines for FDDI packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
6 * $Id: packet-fddi.c,v 1.8 1998/11/17 04:28:53 gerald 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];
136 void dissect_fddi(const u_char *pd, frame_data *fd, GtkTree *tree)
139 GtkWidget *fh_tree, *ti;
140 u_char src[6], dst[6];
142 if (fd->cap_len < FDDI_HEADER_SIZE) {
143 dissect_data(pd, offset, fd, tree);
147 /* Extract the source and destination addresses, possibly bit-swapping
149 get_mac_addr(dst, (u_char *)&pd[FDDI_P_DHOST]);
150 get_mac_addr(src, (u_char *)&pd[FDDI_P_SHOST]);
152 fc = (int) pd[FDDI_P_FC];
154 if (check_col(fd, COL_RES_DL_SRC))
155 col_add_str(fd, COL_RES_DL_SRC, get_ether_name(src));
156 if (check_col(fd, COL_RES_DL_DST))
157 col_add_str(fd, COL_RES_DL_DST, get_ether_name(dst));
158 if (check_col(fd, COL_UNRES_DL_SRC))
159 col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str(src));
160 if (check_col(fd, COL_UNRES_DL_DST))
161 col_add_str(fd, COL_UNRES_DL_DST, ether_to_str(dst));
162 if (check_col(fd, COL_PROTOCOL))
163 col_add_str(fd, COL_PROTOCOL, "N/A");
164 if (check_col(fd, COL_INFO))
165 col_add_str(fd, COL_INFO, "FDDI");
168 ti = add_item_to_tree(GTK_WIDGET(tree), 0, offset,
170 (fc >= FDDI_FC_LLC_ASYNC_MIN && fc <= FDDI_FC_LLC_ASYNC_MAX) ?
171 "Async LLC" : "unsupported FC");
173 fh_tree = gtk_tree_new();
174 add_subtree(ti, fh_tree, ETT_FDDI);
175 add_item_to_tree(fh_tree, FDDI_P_FC, 1, "Frame Control: 0x%02x", fc);
176 add_item_to_tree(fh_tree, FDDI_P_DHOST, 6, "Destination: %s (%s)",
177 ether_to_str(dst), get_ether_name(dst));
178 add_item_to_tree(fh_tree, FDDI_P_SHOST, 6, "Source: %s (%s)",
179 ether_to_str(src), get_ether_name(src));
182 offset = FDDI_HEADER_SIZE;
186 /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
188 case FDDI_FC_LLC_ASYNC + 0 :
189 case FDDI_FC_LLC_ASYNC + 1 :
190 case FDDI_FC_LLC_ASYNC + 2 :
191 case FDDI_FC_LLC_ASYNC + 3 :
192 case FDDI_FC_LLC_ASYNC + 4 :
193 case FDDI_FC_LLC_ASYNC + 5 :
194 case FDDI_FC_LLC_ASYNC + 6 :
195 case FDDI_FC_LLC_ASYNC + 7 :
196 case FDDI_FC_LLC_ASYNC + 8 :
197 case FDDI_FC_LLC_ASYNC + 9 :
198 case FDDI_FC_LLC_ASYNC + 10 :
199 case FDDI_FC_LLC_ASYNC + 11 :
200 case FDDI_FC_LLC_ASYNC + 12 :
201 case FDDI_FC_LLC_ASYNC + 13 :
202 case FDDI_FC_LLC_ASYNC + 14 :
203 case FDDI_FC_LLC_ASYNC + 15 :
204 dissect_llc(pd, offset, fd, tree);
208 dissect_data(pd, offset, fd, tree);