Add comments about nettl support.
[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.29 2000/02/15 21:02:07 gram Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
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.
15  * 
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.
20  * 
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.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #include <glib.h>
35 #include "packet.h"
36 #include "etypes.h"
37 #include "resolv.h"
38 #include "packet-ipx.h"
39 #include "packet-isl.h"
40 #include "packet-llc.h"
41
42 extern const value_string etype_vals[];
43
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
51 static gint ett_ieee8023 = -1;
52 static gint ett_ether2 = -1;
53
54 #define ETH_HEADER_SIZE 14
55
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
64 */
65 #define ETHERNET_II     0
66 #define ETHERNET_802_2  1
67 #define ETHERNET_802_3  2
68 #define ETHERNET_SNAP   3
69
70 void
71 capture_eth(const u_char *pd, int offset, packet_counts *ld)
72 {
73   guint16    etype, length;
74   int     ethhdr_type;  /* the type of ethernet frame */
75
76   if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
77     ld->other++;
78     return;
79   }
80   
81   etype = pntohs(&pd[offset+12]);
82
83         /* either ethernet802.3 or ethernet802.2 */
84   if (etype <= IEEE_802_3_MAX_LEN) {
85     length = etype;
86
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;
95     }
96     else {
97       ethhdr_type = ETHERNET_802_2;
98     }
99
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);
107       return;
108     }
109
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;
116     if (pi.len > length)
117       pi.len = length;
118     if (pi.captured_len > length)
119       pi.captured_len = length;
120   } else {
121     ethhdr_type = ETHERNET_II;
122   }
123   offset += ETH_HEADER_SIZE;
124
125   switch (ethhdr_type) {
126     case ETHERNET_802_3:
127       capture_ipx(pd, offset, ld);
128       break;
129     case ETHERNET_802_2:
130       capture_llc(pd, offset, ld);
131       break;
132     case ETHERNET_II:
133       capture_ethertype(etype, offset, pd, ld);
134       break;
135   }
136 }
137
138 void
139 dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
140 {
141   guint16    etype, length;
142   proto_tree *fh_tree = NULL;
143   proto_item *ti;
144   int        ethhdr_type;       /* the type of ethernet frame */
145
146   if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
147     dissect_data(pd, offset, fd, tree);
148     return;
149   }
150
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]);
155
156   if (check_col(fd, COL_PROTOCOL))
157     col_add_str(fd, COL_PROTOCOL, "Ethernet");
158
159   etype = pntohs(&pd[offset+12]);
160
161         /* either ethernet802.3 or ethernet802.2 */
162   if (etype <= IEEE_802_3_MAX_LEN) {
163     length = etype;
164
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;
173     }
174     else {
175       ethhdr_type = ETHERNET_802_2;
176     }
177
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);
185       return;
186     }
187
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 " : ""));
191     }
192     if (tree) {
193
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 " : ""));
196
197         fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
198
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);
202     }
203
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;
210     if (pi.len > length)
211       pi.len = length;
212     if (pi.captured_len > length)
213       pi.captured_len = length;
214   } else {
215     ethhdr_type = ETHERNET_II;
216     if (check_col(fd, COL_INFO))
217       col_add_str(fd, COL_INFO, "Ethernet II");
218     if (tree) {
219
220         ti = proto_tree_add_item_format(tree, proto_eth, offset, ETH_HEADER_SIZE,
221                 NULL, "Ethernet II");
222
223         fh_tree = proto_item_add_subtree(ti, ett_ether2);
224
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]);
227     }
228   }
229   offset += ETH_HEADER_SIZE;
230
231   switch (ethhdr_type) {
232     case ETHERNET_802_3:
233       dissect_ipx(pd, offset, fd, tree);
234       break;
235     case ETHERNET_802_2:
236       dissect_llc(pd, offset, fd, tree);
237       break;
238     case ETHERNET_II:
239       ethertype(etype, offset, pd, fd, tree, fh_tree, hf_eth_type);
240       break;
241   }
242 }
243
244 void
245 proto_register_eth(void)
246 {
247         static hf_register_info hf[] = {
248
249                 { &hf_eth_dst,
250                 { "Destination",        "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
251                         "Destination Hardware Address" }},
252
253                 { &hf_eth_src,
254                 { "Source",             "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
255                         "Source Hardware Address" }},
256
257                 { &hf_eth_len,
258                 { "Length",             "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
259                         "" }},
260
261                 /* registered here but handled in ethertype.c */
262                 { &hf_eth_type,
263                 { "Type",               "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
264                         "" }}
265         };
266         static gint *ett[] = {
267                 &ett_ieee8023,
268                 &ett_ether2,
269         };
270
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));
274 }