2 * Routines for ethernet packet disassembly
4 * $Id: packet-eth.c,v 1.29 2000/02/15 21:02:07 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;
51 static gint ett_ieee8023 = -1;
52 static gint ett_ether2 = -1;
54 #define ETH_HEADER_SIZE 14
56 /* These are the Netware-ish names for the different Ethernet frame types.
57 EthernetII: The ethernet with a Type field instead of a length field
58 Ethernet802.2: An 802.3 header followed by an 802.3 header
59 Ethernet802.3: A raw 802.3 packet. IPX/SPX can be the only payload.
60 There's not 802.2 hdr in this.
61 EthernetSNAP: Basically 802.2, just with 802.2SNAP. For our purposes,
62 there's no difference between 802.2 and 802.2SNAP, since we just
63 pass it down to dissect_llc(). -- Gilbert
66 #define ETHERNET_802_2 1
67 #define ETHERNET_802_3 2
68 #define ETHERNET_SNAP 3
71 capture_eth(const u_char *pd, int offset, packet_counts *ld)
73 guint16 etype, length;
74 int ethhdr_type; /* the type of ethernet frame */
76 if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
81 etype = pntohs(&pd[offset+12]);
83 /* either ethernet802.3 or ethernet802.2 */
84 if (etype <= IEEE_802_3_MAX_LEN) {
87 /* Is there an 802.2 layer? I can tell by looking at the first 2
88 bytes after the 802.3 header. If they are 0xffff, then what
89 follows the 802.3 header is an IPX payload, meaning no 802.2.
90 (IPX/SPX is they only thing that can be contained inside a
91 straight 802.3 packet). A non-0xffff value means that there's an
92 802.2 layer inside the 802.3 layer */
93 if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
94 ethhdr_type = ETHERNET_802_3;
97 ethhdr_type = ETHERNET_802_2;
100 /* Oh, yuck. Cisco ISL frames require special interpretation of the
101 destination address field; fortunately, they can be recognized by
102 checking the first 5 octets of the destination address, which are
103 01-00-0C-00-00 for ISL frames. */
104 if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
105 && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
106 capture_isl(pd, offset, ld);
110 /* Convert the LLC length from the 802.3 header to a total
111 frame length, by adding in the size of any data that preceded
112 the Ethernet header, and adding in the Ethernet header size,
113 and set the payload and captured-payload lengths to the minima
114 of the total length and the frame lengths. */
115 length += offset + ETH_HEADER_SIZE;
118 if (pi.captured_len > length)
119 pi.captured_len = length;
121 ethhdr_type = ETHERNET_II;
123 offset += ETH_HEADER_SIZE;
125 switch (ethhdr_type) {
127 capture_ipx(pd, offset, ld);
130 capture_llc(pd, offset, ld);
133 capture_ethertype(etype, offset, pd, ld);
139 dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
141 guint16 etype, length;
142 proto_tree *fh_tree = NULL;
144 int ethhdr_type; /* the type of ethernet frame */
146 if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
147 dissect_data(pd, offset, fd, tree);
151 SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &pd[offset+6]);
152 SET_ADDRESS(&pi.src, AT_ETHER, 6, &pd[offset+6]);
153 SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset+0]);
154 SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset+0]);
156 if (check_col(fd, COL_PROTOCOL))
157 col_add_str(fd, COL_PROTOCOL, "Ethernet");
159 etype = pntohs(&pd[offset+12]);
161 /* either ethernet802.3 or ethernet802.2 */
162 if (etype <= IEEE_802_3_MAX_LEN) {
165 /* Is there an 802.2 layer? I can tell by looking at the first 2
166 bytes after the 802.3 header. If they are 0xffff, then what
167 follows the 802.3 header is an IPX payload, meaning no 802.2.
168 (IPX/SPX is they only thing that can be contained inside a
169 straight 802.3 packet). A non-0xffff value means that there's an
170 802.2 layer inside the 802.3 layer */
171 if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
172 ethhdr_type = ETHERNET_802_3;
175 ethhdr_type = ETHERNET_802_2;
178 /* Oh, yuck. Cisco ISL frames require special interpretation of the
179 destination address field; fortunately, they can be recognized by
180 checking the first 5 octets of the destination address, which are
181 01-00-0C-00-00 for ISL frames. */
182 if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
183 && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
184 dissect_isl(pd, offset, fd, tree);
188 if (check_col(fd, COL_INFO)) {
189 col_add_fstr(fd, COL_INFO, "IEEE 802.3 %s",
190 (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
194 ti = proto_tree_add_item_format(tree, proto_eth, offset, ETH_HEADER_SIZE,
195 NULL, "IEEE 802.3 %s", (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
197 fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
199 proto_tree_add_item(fh_tree, hf_eth_dst, offset+0, 6, &pd[offset+0]);
200 proto_tree_add_item(fh_tree, hf_eth_src, offset+6, 6, &pd[offset+6]);
201 proto_tree_add_item(fh_tree, hf_eth_len, offset+12, 2, length);
204 /* Convert the LLC length from the 802.3 header to a total
205 frame length, by adding in the size of any data that preceded
206 the Ethernet header, and adding in the Ethernet header size,
207 and set the payload and captured-payload lengths to the minima
208 of the total length and the frame lengths. */
209 length += offset + ETH_HEADER_SIZE;
212 if (pi.captured_len > length)
213 pi.captured_len = length;
215 ethhdr_type = ETHERNET_II;
216 if (check_col(fd, COL_INFO))
217 col_add_str(fd, COL_INFO, "Ethernet II");
220 ti = proto_tree_add_item_format(tree, proto_eth, offset, ETH_HEADER_SIZE,
221 NULL, "Ethernet II");
223 fh_tree = proto_item_add_subtree(ti, ett_ether2);
225 proto_tree_add_item(fh_tree, hf_eth_dst, offset+0, 6, &pd[offset+0]);
226 proto_tree_add_item(fh_tree, hf_eth_src, offset+6, 6, &pd[offset+6]);
229 offset += ETH_HEADER_SIZE;
231 switch (ethhdr_type) {
233 dissect_ipx(pd, offset, fd, tree);
236 dissect_llc(pd, offset, fd, tree);
239 ethertype(etype, offset, pd, fd, tree, fh_tree, hf_eth_type);
245 proto_register_eth(void)
247 static hf_register_info hf[] = {
250 { "Destination", "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
251 "Destination Hardware Address" }},
254 { "Source", "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
255 "Source Hardware Address" }},
258 { "Length", "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
261 /* registered here but handled in ethertype.c */
263 { "Type", "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
266 static gint *ett[] = {
271 proto_eth = proto_register_protocol ("Ethernet", "eth" );
272 proto_register_field_array(proto_eth, hf, array_length(hf));
273 proto_register_subtree_array(ett, array_length(ett));