Removed trailing whitespaces from .h and .c files using the
[obnox/wireshark/wip.git] / packet-eth.c
1 /* packet-eth.c
2  * Routines for ethernet packet disassembly
3  *
4  * $Id: packet-eth.c,v 1.76 2002/08/26 19:08:59 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30 #include <epan/packet.h>
31 #include "prefs.h"
32 #include "etypes.h"
33 #include <epan/resolv.h>
34 #include "packet-eth.h"
35 #include "packet-ieee8023.h"
36 #include "packet-ipx.h"
37 #include "packet-isl.h"
38 #include "packet-llc.h"
39
40 /* Interpret capture file as FW1 monitor file */
41 static gboolean eth_interpret_as_fw1_monitor = FALSE;
42
43 /* protocols and header fields */
44 static int proto_eth = -1;
45 static int hf_eth_dst = -1;
46 static int hf_eth_src = -1;
47 static int hf_eth_len = -1;
48 static int hf_eth_type = -1;
49 static int hf_eth_addr = -1;
50 static int hf_eth_trailer = -1;
51
52 static gint ett_ieee8023 = -1;
53 static gint ett_ether2 = -1;
54
55 static dissector_handle_t isl_handle;
56 static dissector_handle_t fw1_handle;
57
58 #define ETH_HEADER_SIZE 14
59
60 /* These are the Netware-ish names for the different Ethernet frame types.
61         EthernetII: The ethernet with a Type field instead of a length field
62         Ethernet802.2: An 802.3 header followed by an 802.2 header
63         Ethernet802.3: A raw 802.3 packet. IPX/SPX can be the only payload.
64                         There's no 802.2 hdr in this.
65         EthernetSNAP: Basically 802.2, just with 802.2SNAP. For our purposes,
66                 there's no difference between 802.2 and 802.2SNAP, since we just
67                 pass it down to the LLC dissector. -- Gilbert
68 */
69 #define ETHERNET_II     0
70 #define ETHERNET_802_2  1
71 #define ETHERNET_802_3  2
72 #define ETHERNET_SNAP   3
73
74 void
75 capture_eth(const guchar *pd, int offset, int len, packet_counts *ld)
76 {
77   guint16    etype, length;
78   int     ethhdr_type;  /* the type of ethernet frame */
79
80   if (!BYTES_ARE_IN_FRAME(offset, len, ETH_HEADER_SIZE)) {
81     ld->other++;
82     return;
83   }
84   
85   etype = pntohs(&pd[offset+12]);
86
87         /* either ethernet802.3 or ethernet802.2 */
88   if (etype <= IEEE_802_3_MAX_LEN) {
89     length = etype;
90
91     /* Is there an 802.2 layer? I can tell by looking at the first 2
92        bytes after the 802.3 header. If they are 0xffff, then what
93        follows the 802.3 header is an IPX payload, meaning no 802.2.
94        (IPX/SPX is they only thing that can be contained inside a
95        straight 802.3 packet). A non-0xffff value means that there's an
96        802.2 layer inside the 802.3 layer */
97     if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
98       ethhdr_type = ETHERNET_802_3;
99     }
100     else {
101       ethhdr_type = ETHERNET_802_2;
102     }
103
104     /* Oh, yuck.  Cisco ISL frames require special interpretation of the
105        destination address field; fortunately, they can be recognized by
106        checking the first 5 octets of the destination address, which are
107        01-00-0C-00-00 for ISL frames. */
108     if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
109         && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
110       capture_isl(pd, offset, len, ld);
111       return;
112     }
113
114     /* Convert the LLC length from the 802.3 header to a total
115        frame length, by adding in the size of any data that preceded
116        the Ethernet header, and adding in the Ethernet header size,
117        and set the payload and captured-payload lengths to the minima
118        of the total length and the frame lengths. */
119     length += offset + ETH_HEADER_SIZE;
120     if (len > length)
121       len = length;
122   } else {
123     ethhdr_type = ETHERNET_II;
124   }
125   offset += ETH_HEADER_SIZE;
126
127   switch (ethhdr_type) {
128     case ETHERNET_802_3:
129       capture_ipx(ld);
130       break;
131     case ETHERNET_802_2:
132       capture_llc(pd, offset, len, ld);
133       break;
134     case ETHERNET_II:
135       capture_ethertype(etype, pd, offset, len, ld);
136       break;
137   }
138 }
139
140 static void
141 dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
142 {
143   proto_item            *ti;
144   const guint8          *dst, *src;
145
146   guint16               etype;
147   volatile gboolean     is_802_2;
148   proto_tree            *volatile fh_tree = NULL;
149
150   if (check_col(pinfo->cinfo, COL_PROTOCOL))
151     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Ethernet");
152
153   src = tvb_get_ptr(tvb, 6, 6);
154   dst = tvb_get_ptr(tvb, 0, 6);
155   SET_ADDRESS(&pinfo->dl_src,   AT_ETHER, 6, src);
156   SET_ADDRESS(&pinfo->src,      AT_ETHER, 6, src);
157   SET_ADDRESS(&pinfo->dl_dst,   AT_ETHER, 6, dst);
158   SET_ADDRESS(&pinfo->dst,      AT_ETHER, 6, dst);
159
160   etype = tvb_get_ntohs(tvb, 12);
161
162         /* either ethernet802.3 or ethernet802.2 */
163   if (etype <= IEEE_802_3_MAX_LEN) {
164     /* Oh, yuck.  Cisco ISL frames require special interpretation of the
165        destination address field; fortunately, they can be recognized by
166        checking the first 5 octets of the destination address, which are
167        01-00-0C-00-00 for ISL frames. */
168     if (        tvb_get_guint8(tvb, 0) == 0x01 &&
169                 tvb_get_guint8(tvb, 1) == 0x00 &&
170                 tvb_get_guint8(tvb, 2) == 0x0C &&
171                 tvb_get_guint8(tvb, 3) == 0x00 &&
172                 tvb_get_guint8(tvb, 4) == 0x00 ) {
173       call_dissector(isl_handle, tvb, pinfo, tree);
174       return;
175     }
176
177     /* Is there an 802.2 layer? I can tell by looking at the first 2
178        bytes after the 802.3 header. If they are 0xffff, then what
179        follows the 802.3 header is an IPX payload, meaning no 802.2.
180        (IPX/SPX is they only thing that can be contained inside a
181        straight 802.3 packet). A non-0xffff value means that there's an
182        802.2 layer inside the 802.3 layer */
183     is_802_2 = TRUE;
184     TRY {
185             if (tvb_get_ntohs(tvb, 14) == 0xffff) {
186               is_802_2 = FALSE;
187             }
188     }
189     CATCH2(BoundsError, ReportedBoundsError) {
190             ; /* do nothing */
191
192     }
193     ENDTRY;
194
195     if (check_col(pinfo->cinfo, COL_INFO)) {
196       col_add_fstr(pinfo->cinfo, COL_INFO, "IEEE 802.3 Ethernet %s",
197                 (is_802_2 ? "" : "Raw "));
198     }
199     if (tree) {
200       ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
201                 "IEEE 802.3 Ethernet %s", (is_802_2 ? "" : "Raw "));
202
203       fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
204
205       proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
206       proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
207
208 /* add items for eth.addr filter */
209       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
210       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
211     }
212
213     dissect_802_3(etype, is_802_2, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree,
214                   hf_eth_len, hf_eth_trailer);
215   } else {
216     if (eth_interpret_as_fw1_monitor) {
217       call_dissector(fw1_handle, tvb, pinfo, tree);
218       return;
219     }
220
221     if (check_col(pinfo->cinfo, COL_INFO))
222       col_set_str(pinfo->cinfo, COL_INFO, "Ethernet II");
223     if (tree) {
224       ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
225                 "Ethernet II, Src: %s, Dst: %s",
226                 ether_to_str(src), ether_to_str(dst));
227
228       fh_tree = proto_item_add_subtree(ti, ett_ether2);
229
230       proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
231       proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
232 /* add items for eth.addr filter */
233       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
234       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
235     }
236
237     ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type,
238           hf_eth_trailer);
239   }
240 }
241
242 void
243 proto_register_eth(void)
244 {
245         static hf_register_info hf[] = {
246
247                 { &hf_eth_dst,
248                 { "Destination",        "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
249                         "Destination Hardware Address", HFILL }},
250
251                 { &hf_eth_src,
252                 { "Source",             "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
253                         "Source Hardware Address", HFILL }},
254
255                 { &hf_eth_len,
256                 { "Length",             "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
257                         "", HFILL }},
258
259                 /* registered here but handled in ethertype.c */
260                 { &hf_eth_type,
261                 { "Type",               "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
262                         "", HFILL }},
263                 { &hf_eth_addr,
264                 { "Source or Destination Address", "eth.addr", FT_ETHER, BASE_NONE, NULL, 0x0,
265                         "Source or Destination Hardware Address", HFILL }},
266
267                 { &hf_eth_trailer,
268                 { "Trailer", "eth.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
269                         "Ethernet Trailer or Checksum", HFILL }},
270
271         };
272         static gint *ett[] = {
273                 &ett_ieee8023,
274                 &ett_ether2,
275         };
276         module_t *eth_module;
277
278         proto_eth = proto_register_protocol("Ethernet", "Ethernet", "eth");
279         proto_register_field_array(proto_eth, hf, array_length(hf));
280         proto_register_subtree_array(ett, array_length(ett));
281
282         /* Register configuration preferences */
283         eth_module = prefs_register_protocol(proto_eth, NULL);
284         prefs_register_bool_preference(eth_module, "interpret_as_fw1_monitor",
285             "Interpret as FireWall-1 monitor file",
286 "Whether the capture file should be interpreted as a CheckPoint FireWall-1 monitor file",
287             &eth_interpret_as_fw1_monitor);
288
289         register_dissector("eth", dissect_eth, proto_eth);
290 }
291
292 void
293 proto_reg_handoff_eth(void)
294 {
295         dissector_handle_t eth_handle;
296
297         /*
298          * Get a handle for the ISL dissector.
299          */
300         isl_handle = find_dissector("isl");
301         fw1_handle = find_dissector("fw1");
302
303         eth_handle = find_dissector("eth");
304         dissector_add("wtap_encap", WTAP_ENCAP_ETHERNET, eth_handle);
305         dissector_add("ethertype", ETHERTYPE_ETHBRIDGE, eth_handle);
306         dissector_add("chdlctype", ETHERTYPE_ETHBRIDGE, eth_handle);
307         dissector_add("gre.proto", ETHERTYPE_ETHBRIDGE, eth_handle);
308 }