b131839a0f6e2ebe5f9b453ed7921fc16b8bb0b2
[obnox/wireshark/wip.git] / packet-fddi.c
1 /* packet-fddi.c
2  * Routines for FDDI packet disassembly
3  *
4  * Laurent Deniel <deniel@worldnet.fr>
5  *
6  * $Id: packet-fddi.c,v 1.8 1998/11/17 04:28:53 gerald Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * 
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.
17  * 
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.
22  * 
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.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #include <gtk/gtk.h>
37
38 #include <stdio.h>
39
40
41 #include "ethereal.h"
42 #include "packet.h"
43 #include "resolv.h"
44
45 /* FDDI Frame Control values */
46
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. */
71
72 #define FDDI_HEADER_SIZE        13
73
74 /* field positions */
75
76 #define FDDI_P_FC               0
77 #define FDDI_P_DHOST            1
78 #define FDDI_P_SHOST            7
79
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
83 #endif
84
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,
120 };
121 #endif
122
123 static void get_mac_addr(u_char *swapped_addr, const u_char *addr)
124 {
125   int i;
126
127   for (i = 0; i < 6; i++) {
128 #ifdef BIT_SWAPPED_MAC_ADDRS
129     swapped_addr[i] = swaptab[addr[i]];
130 #else
131     swapped_addr[i] = addr[i];
132 #endif
133   }
134 }
135
136 void dissect_fddi(const u_char *pd, frame_data *fd, GtkTree *tree) 
137 {
138   int        offset = 0, fc;
139   GtkWidget *fh_tree, *ti;
140   u_char     src[6], dst[6];
141
142   if (fd->cap_len < FDDI_HEADER_SIZE) {
143     dissect_data(pd, offset, fd, tree);
144     return;
145   }
146
147   /* Extract the source and destination addresses, possibly bit-swapping
148      them. */
149   get_mac_addr(dst, (u_char *)&pd[FDDI_P_DHOST]);
150   get_mac_addr(src, (u_char *)&pd[FDDI_P_SHOST]);
151
152   fc = (int) pd[FDDI_P_FC];
153
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");
166
167   if (tree) {
168     ti = add_item_to_tree(GTK_WIDGET(tree), 0, offset,
169                           "FDDI %s",
170                           (fc >= FDDI_FC_LLC_ASYNC_MIN && fc <= FDDI_FC_LLC_ASYNC_MAX) ?
171                           "Async LLC" : "unsupported FC");
172
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));
180     }
181
182   offset = FDDI_HEADER_SIZE;
183
184   switch (fc) {
185
186     /* From now, only 802.2 SNAP (Async. LCC frame) is supported */
187
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);
205       return;
206       
207     default :
208       dissect_data(pd, offset, fd, tree);
209       return;
210
211   } /* fc */
212
213 } /* dissect_fddi */
214