1f838836ac8c355e2f4fb36258287bb3f4217232
[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.63 2001/04/03 05:42:11 guy 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-eth.h"
39 #include "packet-ieee8023.h"
40 #include "packet-ipx.h"
41 #include "packet-isl.h"
42 #include "packet-llc.h"
43
44 extern const value_string etype_vals[];
45
46 /* protocols and header fields */
47 static int proto_eth = -1;
48 static int hf_eth_dst = -1;
49 static int hf_eth_src = -1;
50 static int hf_eth_len = -1;
51 static int hf_eth_type = -1;
52 static int hf_eth_addr = -1;
53 static int hf_eth_trailer = -1;
54
55 static gint ett_ieee8023 = -1;
56 static gint ett_ether2 = -1;
57
58 static dissector_handle_t isl_handle;
59
60 #define ETH_HEADER_SIZE 14
61
62 /* These are the Netware-ish names for the different Ethernet frame types.
63         EthernetII: The ethernet with a Type field instead of a length field
64         Ethernet802.2: An 802.3 header followed by an 802.2 header
65         Ethernet802.3: A raw 802.3 packet. IPX/SPX can be the only payload.
66                         There's no 802.2 hdr in this.
67         EthernetSNAP: Basically 802.2, just with 802.2SNAP. For our purposes,
68                 there's no difference between 802.2 and 802.2SNAP, since we just
69                 pass it down to the LLC dissector. -- Gilbert
70 */
71 #define ETHERNET_II     0
72 #define ETHERNET_802_2  1
73 #define ETHERNET_802_3  2
74 #define ETHERNET_SNAP   3
75
76 void
77 capture_eth(const u_char *pd, int offset, packet_counts *ld)
78 {
79   guint16    etype, length;
80   int     ethhdr_type;  /* the type of ethernet frame */
81
82   if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
83     ld->other++;
84     return;
85   }
86   
87   etype = pntohs(&pd[offset+12]);
88
89         /* either ethernet802.3 or ethernet802.2 */
90   if (etype <= IEEE_802_3_MAX_LEN) {
91     length = etype;
92
93     /* Is there an 802.2 layer? I can tell by looking at the first 2
94        bytes after the 802.3 header. If they are 0xffff, then what
95        follows the 802.3 header is an IPX payload, meaning no 802.2.
96        (IPX/SPX is they only thing that can be contained inside a
97        straight 802.3 packet). A non-0xffff value means that there's an
98        802.2 layer inside the 802.3 layer */
99     if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) {
100       ethhdr_type = ETHERNET_802_3;
101     }
102     else {
103       ethhdr_type = ETHERNET_802_2;
104     }
105
106     /* Oh, yuck.  Cisco ISL frames require special interpretation of the
107        destination address field; fortunately, they can be recognized by
108        checking the first 5 octets of the destination address, which are
109        01-00-0C-00-00 for ISL frames. */
110     if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C
111         && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) {
112       capture_isl(pd, offset, ld);
113       return;
114     }
115
116     /* Convert the LLC length from the 802.3 header to a total
117        frame length, by adding in the size of any data that preceded
118        the Ethernet header, and adding in the Ethernet header size,
119        and set the payload and captured-payload lengths to the minima
120        of the total length and the frame lengths. */
121     length += offset + ETH_HEADER_SIZE;
122     if (pi.len > length)
123       pi.len = length;
124     if (pi.captured_len > length)
125       pi.captured_len = length;
126   } else {
127     ethhdr_type = ETHERNET_II;
128   }
129   offset += ETH_HEADER_SIZE;
130
131   switch (ethhdr_type) {
132     case ETHERNET_802_3:
133       capture_ipx(pd, offset, ld);
134       break;
135     case ETHERNET_802_2:
136       capture_llc(pd, offset, ld);
137       break;
138     case ETHERNET_II:
139       capture_ethertype(etype, offset, pd, ld);
140       break;
141   }
142 }
143
144 static void
145 dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
146 {
147   int                   orig_captured_len;
148   proto_item            *ti;
149   const guint8          *dst, *src;
150   const guint8          *pd;
151
152   guint16               etype;
153   volatile gboolean     is_802_2;
154   int                   eth_offset;
155   volatile guint16      length;
156   proto_tree            *volatile fh_tree = NULL;
157
158   tvb_compat(tvb, &pd, (int*)&eth_offset);
159
160   orig_captured_len = pinfo->captured_len;
161
162   if (check_col(pinfo->fd, COL_PROTOCOL))
163     col_set_str(pinfo->fd, COL_PROTOCOL, "Ethernet");
164
165   src = tvb_get_ptr(tvb, 6, 6);
166   dst = tvb_get_ptr(tvb, 0, 6);
167   SET_ADDRESS(&pinfo->dl_src,   AT_ETHER, 6, src);
168   SET_ADDRESS(&pinfo->src,      AT_ETHER, 6, src);
169   SET_ADDRESS(&pinfo->dl_dst,   AT_ETHER, 6, dst);
170   SET_ADDRESS(&pinfo->dst,      AT_ETHER, 6, dst);
171
172   etype = tvb_get_ntohs(tvb, 12);
173
174         /* either ethernet802.3 or ethernet802.2 */
175   if (etype <= IEEE_802_3_MAX_LEN) {
176     length = etype;
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 (        tvb_get_guint8(tvb, 0) == 0x01 &&
183                 tvb_get_guint8(tvb, 1) == 0x00 &&
184                 tvb_get_guint8(tvb, 2) == 0x0C &&
185                 tvb_get_guint8(tvb, 3) == 0x00 &&
186                 tvb_get_guint8(tvb, 4) == 0x00 ) {
187       call_dissector(isl_handle, tvb, pinfo, tree);
188       return;
189     }
190
191     /* Is there an 802.2 layer? I can tell by looking at the first 2
192        bytes after the 802.3 header. If they are 0xffff, then what
193        follows the 802.3 header is an IPX payload, meaning no 802.2.
194        (IPX/SPX is they only thing that can be contained inside a
195        straight 802.3 packet). A non-0xffff value means that there's an
196        802.2 layer inside the 802.3 layer */
197     is_802_2 = TRUE;
198     TRY {
199             if (tvb_get_ntohs(tvb, 14) == 0xffff) {
200               is_802_2 = FALSE;
201             }
202     }
203     CATCH2(BoundsError, ReportedBoundsError) {
204             ; /* do nothing */
205
206     }
207     ENDTRY;
208
209     if (check_col(pinfo->fd, COL_INFO)) {
210       col_add_fstr(pinfo->fd, COL_INFO, "IEEE 802.3 Ethernet %s",
211                 (is_802_2 ? "" : "Raw "));
212     }
213     if (tree) {
214       ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
215                 "IEEE 802.3 Ethernet %s", (is_802_2 ? "" : "Raw "));
216
217       fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
218
219       proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
220       proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
221
222 /* add items for eth.addr filter */
223       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
224       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
225     }
226
227     /* Convert the LLC length from the 802.3 header to a total
228        frame length, by adding in the size of any data that preceded
229        the Ethernet header, and adding in the Ethernet header size,
230        and set the payload and captured-payload lengths to the minima
231        of the total length and the frame lengths.
232
233        XXX - when all dissectors are tvbuffified we shouldn't have to
234        do this any more. */
235     length += eth_offset + ETH_HEADER_SIZE;
236     if (pinfo->len > length)
237       pinfo->len = length;
238     if (pinfo->captured_len > length)
239       pinfo->captured_len = length;
240
241     dissect_802_3(etype, is_802_2, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree,
242                   hf_eth_len, hf_eth_trailer);
243   } else {
244     if (check_col(pinfo->fd, COL_INFO))
245       col_set_str(pinfo->fd, COL_INFO, "Ethernet II");
246     if (tree) {
247       ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
248                 "Ethernet II");
249
250       fh_tree = proto_item_add_subtree(ti, ett_ether2);
251
252       proto_tree_add_ether(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
253       proto_tree_add_ether(fh_tree, hf_eth_src, tvb, 6, 6, src);
254 /* add items for eth.addr filter */
255       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
256       proto_tree_add_ether_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
257     }
258
259     ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type,
260           hf_eth_trailer);
261   }
262 }
263
264 void
265 proto_register_eth(void)
266 {
267         static hf_register_info hf[] = {
268
269                 { &hf_eth_dst,
270                 { "Destination",        "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
271                         "Destination Hardware Address" }},
272
273                 { &hf_eth_src,
274                 { "Source",             "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
275                         "Source Hardware Address" }},
276
277                 { &hf_eth_len,
278                 { "Length",             "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
279                         "" }},
280
281                 /* registered here but handled in ethertype.c */
282                 { &hf_eth_type,
283                 { "Type",               "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
284                         "" }},
285                 { &hf_eth_addr,
286                 { "Source or Destination Address", "eth.addr", FT_ETHER, BASE_NONE, NULL, 0x0,
287                         "Source or Destination Hardware Address" }},
288
289                 { &hf_eth_trailer,
290                 { "Trailer", "eth.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
291                         "Ethernet Trailer or Checksum" }},
292
293         };
294         static gint *ett[] = {
295                 &ett_ieee8023,
296                 &ett_ether2,
297         };
298
299         proto_eth = proto_register_protocol("Ethernet", "Ethernet", "eth");
300         proto_register_field_array(proto_eth, hf, array_length(hf));
301         proto_register_subtree_array(ett, array_length(ett));
302
303         register_dissector("eth", dissect_eth, proto_eth);
304 }
305
306 void
307 proto_reg_handoff_eth(void)
308 {
309         /*
310          * Get a handle for the ISL dissector.
311          */
312         isl_handle = find_dissector("isl");
313
314         dissector_add("wtap_encap", WTAP_ENCAP_ETHERNET, dissect_eth,
315             proto_eth);
316         dissector_add("ethertype", ETHERTYPE_ETHBRIDGE, dissect_eth,
317             proto_eth);
318         dissector_add("chdlctype", ETHERTYPE_ETHBRIDGE, dissect_eth,
319             proto_eth);
320         dissector_add("gre.proto", ETHERTYPE_ETHBRIDGE, dissect_eth,
321             proto_eth);
322 }