2 * Routines for ethernet packet disassembly
4 * $Id: packet-eth.c,v 1.33 2000/05/11 08:15:08 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
38 #include "packet-ipx.h"
39 #include "packet-isl.h"
40 #include "packet-llc.h"
42 extern const value_string etype_vals[];
44 /* protocols and header fields */
45 static int proto_eth = -1;
46 static int hf_eth_dst = -1;
47 static int hf_eth_src = -1;
48 static int hf_eth_len = -1;
49 static int hf_eth_type = -1;
50 static int hf_eth_addr = -1;
52 static gint ett_ieee8023 = -1;
53 static gint ett_ether2 = -1;
55 #define ETH_HEADER_SIZE 14
57 /* These are the Netware-ish names for the different Ethernet frame types.
58 EthernetII: The ethernet with a Type field instead of a length field
59 Ethernet802.2: An 802.3 header followed by an 802.3 header
60 Ethernet802.3: A raw 802.3 packet. IPX/SPX can be the only payload.
61 There's not 802.2 hdr in this.
62 EthernetSNAP: Basically 802.2, just with 802.2SNAP. For our purposes,
63 there's no difference between 802.2 and 802.2SNAP, since we just
64 pass it down to dissect_llc(). -- Gilbert
67 #define ETHERNET_802_2 1
68 #define ETHERNET_802_3 2
69 #define ETHERNET_SNAP 3
72 capture_eth(const u_char *pd, int offset, packet_counts *ld)
74 guint16 etype, length;
75 int ethhdr_type; /* the type of ethernet frame */
77 if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
82 etype = pntohs(&pd[offset+12]);
84 /* either ethernet802.3 or ethernet802.2 */
85 if (etype <= IEEE_802_3_MAX_LEN) {
88 /* Is there an 802.2 layer? I can tell by looking at the first 2
89 bytes after the 802.3 header. If they are 0xffff, then what
90 follows the 802.3 header is an IPX payload, meaning no 802.2.
91 (IPX/SPX is they only thing that can be contained inside a
92 straight 802.3 packet). A non-0xffff value means that there's an
93 802.2 layer inside the 802.3 layer */
94 if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
95 ethhdr_type = ETHERNET_802_3;
98 ethhdr_type = ETHERNET_802_2;
101 /* Oh, yuck. Cisco ISL frames require special interpretation of the
102 destination address field; fortunately, they can be recognized by
103 checking the first 5 octets of the destination address, which are
104 01-00-0C-00-00 for ISL frames. */
105 if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
106 && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
107 capture_isl(pd, offset, ld);
111 /* Convert the LLC length from the 802.3 header to a total
112 frame length, by adding in the size of any data that preceded
113 the Ethernet header, and adding in the Ethernet header size,
114 and set the payload and captured-payload lengths to the minima
115 of the total length and the frame lengths. */
116 length += offset + ETH_HEADER_SIZE;
119 if (pi.captured_len > length)
120 pi.captured_len = length;
122 ethhdr_type = ETHERNET_II;
124 offset += ETH_HEADER_SIZE;
126 switch (ethhdr_type) {
128 capture_ipx(pd, offset, ld);
131 capture_llc(pd, offset, ld);
134 capture_ethertype(etype, offset, pd, ld);
140 dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
142 int orig_captured_len;
143 guint16 etype, length;
144 proto_tree *fh_tree = NULL;
146 int ethhdr_type; /* the type of ethernet frame */
148 if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
149 dissect_data(pd, offset, fd, tree);
153 orig_captured_len = pi.captured_len;
155 SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &pd[offset+6]);
156 SET_ADDRESS(&pi.src, AT_ETHER, 6, &pd[offset+6]);
157 SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset+0]);
158 SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset+0]);
160 if (check_col(fd, COL_PROTOCOL))
161 col_add_str(fd, COL_PROTOCOL, "Ethernet");
163 etype = pntohs(&pd[offset+12]);
165 /* either ethernet802.3 or ethernet802.2 */
166 if (etype <= IEEE_802_3_MAX_LEN) {
169 /* Is there an 802.2 layer? I can tell by looking at the first 2
170 bytes after the 802.3 header. If they are 0xffff, then what
171 follows the 802.3 header is an IPX payload, meaning no 802.2.
172 (IPX/SPX is they only thing that can be contained inside a
173 straight 802.3 packet). A non-0xffff value means that there's an
174 802.2 layer inside the 802.3 layer */
175 if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
176 ethhdr_type = ETHERNET_802_3;
179 ethhdr_type = ETHERNET_802_2;
182 /* Oh, yuck. Cisco ISL frames require special interpretation of the
183 destination address field; fortunately, they can be recognized by
184 checking the first 5 octets of the destination address, which are
185 01-00-0C-00-00 for ISL frames. */
186 if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
187 && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
188 dissect_isl(pd, offset, fd, tree);
192 if (check_col(fd, COL_INFO)) {
193 col_add_fstr(fd, COL_INFO, "IEEE 802.3 %s",
194 (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
198 ti = proto_tree_add_protocol_format(tree, proto_eth, NullTVB, offset, ETH_HEADER_SIZE,
199 "IEEE 802.3 %s", (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
201 fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
203 proto_tree_add_item(fh_tree, hf_eth_dst, NullTVB, offset+0, 6, &pd[offset+0]);
204 proto_tree_add_item(fh_tree, hf_eth_src, NullTVB, offset+6, 6, &pd[offset+6]);
206 /* add items for eth.addr filter */
207 proto_tree_add_item_hidden(fh_tree, hf_eth_addr, NullTVB, offset + 0, 6, &pd[offset+0]);
208 proto_tree_add_item_hidden(fh_tree, hf_eth_addr, NullTVB, offset + 6, 6, &pd[offset+6]);
210 proto_tree_add_item(fh_tree, hf_eth_len, NullTVB, offset+12, 2, length);
213 /* Convert the LLC length from the 802.3 header to a total
214 frame length, by adding in the size of any data that preceded
215 the Ethernet header, and adding in the Ethernet header size,
216 and set the payload and captured-payload lengths to the minima
217 of the total length and the frame lengths. */
218 length += offset + ETH_HEADER_SIZE;
221 if (pi.captured_len > length)
222 pi.captured_len = length;
224 ethhdr_type = ETHERNET_II;
225 if (check_col(fd, COL_INFO))
226 col_add_str(fd, COL_INFO, "Ethernet II");
229 ti = proto_tree_add_protocol_format(tree, proto_eth, NullTVB, offset, ETH_HEADER_SIZE,
232 fh_tree = proto_item_add_subtree(ti, ett_ether2);
234 proto_tree_add_item(fh_tree, hf_eth_dst, NullTVB, offset+0, 6, &pd[offset+0]);
235 proto_tree_add_item(fh_tree, hf_eth_src, NullTVB, offset+6, 6, &pd[offset+6]);
236 /* add items for eth.addr filter */
237 proto_tree_add_item_hidden(fh_tree, hf_eth_addr, NullTVB, offset + 0, 6, &pd[offset+0]);
238 proto_tree_add_item_hidden(fh_tree, hf_eth_addr, NullTVB, offset + 6, 6, &pd[offset+6]);
241 offset += ETH_HEADER_SIZE;
243 switch (ethhdr_type) {
245 dissect_ipx(pd, offset, fd, tree);
248 dissect_llc(pd, offset, fd, tree);
251 ethertype(etype, offset, pd, fd, tree, fh_tree, hf_eth_type);
257 proto_register_eth(void)
259 static hf_register_info hf[] = {
262 { "Destination", "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
263 "Destination Hardware Address" }},
266 { "Source", "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
267 "Source Hardware Address" }},
270 { "Length", "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
273 /* registered here but handled in ethertype.c */
275 { "Type", "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
278 { "Source or Destination Address", "eth.addr", FT_ETHER, BASE_NONE, NULL, 0x0,
279 "Source or Destination Hardware Address" }}
282 static gint *ett[] = {
287 proto_eth = proto_register_protocol ("Ethernet", "eth" );
288 proto_register_field_array(proto_eth, hf, array_length(hf));
289 proto_register_subtree_array(ett, array_length(ett));