2 * Routines for ethernet packet disassembly
4 * $Id: packet-eth.c,v 1.68 2001/11/20 22:29:04 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
37 #include "packet-eth.h"
38 #include "packet-ieee8023.h"
39 #include "packet-ipx.h"
40 #include "packet-isl.h"
41 #include "packet-llc.h"
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;
52 static gint ett_ieee8023 = -1;
53 static gint ett_ether2 = -1;
55 static dissector_handle_t isl_handle;
57 #define ETH_HEADER_SIZE 14
59 /* These are the Netware-ish names for the different Ethernet frame types.
60 EthernetII: The ethernet with a Type field instead of a length field
61 Ethernet802.2: An 802.3 header followed by an 802.2 header
62 Ethernet802.3: A raw 802.3 packet. IPX/SPX can be the only payload.
63 There's no 802.2 hdr in this.
64 EthernetSNAP: Basically 802.2, just with 802.2SNAP. For our purposes,
65 there's no difference between 802.2 and 802.2SNAP, since we just
66 pass it down to the LLC dissector. -- Gilbert
69 #define ETHERNET_802_2 1
70 #define ETHERNET_802_3 2
71 #define ETHERNET_SNAP 3
74 capture_eth(const u_char *pd, int offset, int len, packet_counts *ld)
76 guint16 etype, length;
77 int ethhdr_type; /* the type of ethernet frame */
79 if (!BYTES_ARE_IN_FRAME(offset, len, ETH_HEADER_SIZE)) {
84 etype = pntohs(&pd[offset+12]);
86 /* either ethernet802.3 or ethernet802.2 */
87 if (etype <= IEEE_802_3_MAX_LEN) {
90 /* Is there an 802.2 layer? I can tell by looking at the first 2
91 bytes after the 802.3 header. If they are 0xffff, then what
92 follows the 802.3 header is an IPX payload, meaning no 802.2.
93 (IPX/SPX is they only thing that can be contained inside a
94 straight 802.3 packet). A non-0xffff value means that there's an
95 802.2 layer inside the 802.3 layer */
96 if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
97 ethhdr_type = ETHERNET_802_3;
100 ethhdr_type = ETHERNET_802_2;
103 /* Oh, yuck. Cisco ISL frames require special interpretation of the
104 destination address field; fortunately, they can be recognized by
105 checking the first 5 octets of the destination address, which are
106 01-00-0C-00-00 for ISL frames. */
107 if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
108 && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
109 capture_isl(pd, offset, len, ld);
113 /* Convert the LLC length from the 802.3 header to a total
114 frame length, by adding in the size of any data that preceded
115 the Ethernet header, and adding in the Ethernet header size,
116 and set the payload and captured-payload lengths to the minima
117 of the total length and the frame lengths. */
118 length += offset + ETH_HEADER_SIZE;
122 ethhdr_type = ETHERNET_II;
124 offset += ETH_HEADER_SIZE;
126 switch (ethhdr_type) {
128 capture_ipx(pd, offset, len, ld);
131 capture_llc(pd, offset, len, ld);
134 capture_ethertype(etype, pd, offset, len, ld);
140 dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
143 const guint8 *dst, *src;
147 volatile gboolean is_802_2;
149 proto_tree *volatile fh_tree = NULL;
151 tvb_compat(tvb, &pd, (int*)ð_offset);
153 if (check_col(pinfo->fd, COL_PROTOCOL))
154 col_set_str(pinfo->fd, COL_PROTOCOL, "Ethernet");
156 src = tvb_get_ptr(tvb, 6, 6);
157 dst = tvb_get_ptr(tvb, 0, 6);
158 SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src);
159 SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src);
160 SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst);
161 SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst);
163 etype = tvb_get_ntohs(tvb, 12);
165 /* either ethernet802.3 or ethernet802.2 */
166 if (etype <= IEEE_802_3_MAX_LEN) {
167 /* Oh, yuck. Cisco ISL frames require special interpretation of the
168 destination address field; fortunately, they can be recognized by
169 checking the first 5 octets of the destination address, which are
170 01-00-0C-00-00 for ISL frames. */
171 if ( tvb_get_guint8(tvb, 0) == 0x01 &&
172 tvb_get_guint8(tvb, 1) == 0x00 &&
173 tvb_get_guint8(tvb, 2) == 0x0C &&
174 tvb_get_guint8(tvb, 3) == 0x00 &&
175 tvb_get_guint8(tvb, 4) == 0x00 ) {
176 call_dissector(isl_handle, tvb, pinfo, tree);
180 /* Is there an 802.2 layer? I can tell by looking at the first 2
181 bytes after the 802.3 header. If they are 0xffff, then what
182 follows the 802.3 header is an IPX payload, meaning no 802.2.
183 (IPX/SPX is they only thing that can be contained inside a
184 straight 802.3 packet). A non-0xffff value means that there's an
185 802.2 layer inside the 802.3 layer */
188 if (tvb_get_ntohs(tvb, 14) == 0xffff) {
192 CATCH2(BoundsError, ReportedBoundsError) {
198 if (check_col(pinfo->fd, COL_INFO)) {
199 col_add_fstr(pinfo->fd, COL_INFO, "IEEE 802.3 Ethernet %s",
200 (is_802_2 ? "" : "Raw "));
203 ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
204 "IEEE 802.3 Ethernet %s", (is_802_2 ? "" : "Raw "));
206 fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
208 proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
209 proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
211 /* add items for eth.addr filter */
212 proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
213 proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
216 dissect_802_3(etype, is_802_2, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree,
217 hf_eth_len, hf_eth_trailer);
219 if (check_col(pinfo->fd, COL_INFO))
220 col_set_str(pinfo->fd, COL_INFO, "Ethernet II");
222 ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
225 fh_tree = proto_item_add_subtree(ti, ett_ether2);
227 proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
228 proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
229 /* add items for eth.addr filter */
230 proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
231 proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
234 ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type,
240 proto_register_eth(void)
242 static hf_register_info hf[] = {
245 { "Destination", "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
246 "Destination Hardware Address", HFILL }},
249 { "Source", "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
250 "Source Hardware Address", HFILL }},
253 { "Length", "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
256 /* registered here but handled in ethertype.c */
258 { "Type", "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
261 { "Source or Destination Address", "eth.addr", FT_ETHER, BASE_NONE, NULL, 0x0,
262 "Source or Destination Hardware Address", HFILL }},
265 { "Trailer", "eth.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
266 "Ethernet Trailer or Checksum", HFILL }},
269 static gint *ett[] = {
274 proto_eth = proto_register_protocol("Ethernet", "Ethernet", "eth");
275 proto_register_field_array(proto_eth, hf, array_length(hf));
276 proto_register_subtree_array(ett, array_length(ett));
278 register_dissector("eth", dissect_eth, proto_eth);
282 proto_reg_handoff_eth(void)
285 * Get a handle for the ISL dissector.
287 isl_handle = find_dissector("isl");
289 dissector_add("wtap_encap", WTAP_ENCAP_ETHERNET, dissect_eth,
291 dissector_add("ethertype", ETHERTYPE_ETHBRIDGE, dissect_eth,
293 dissector_add("chdlctype", ETHERTYPE_ETHBRIDGE, dissect_eth,
295 dissector_add("gre.proto", ETHERTYPE_ETHBRIDGE, dissect_eth,