Make "packet-clip.c", "packet-raw.c", "packet-ppp.c", "packet-tr.c",
[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.41 2000/05/19 05:29:44 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-ipx.h"
40 #include "packet-isl.h"
41 #include "packet-llc.h"
42
43 extern const value_string etype_vals[];
44
45 /* protocols and header fields */
46 static int proto_eth = -1;
47 static int hf_eth_dst = -1;
48 static int hf_eth_src = -1;
49 static int hf_eth_len = -1;
50 static int hf_eth_type = -1;
51 static int hf_eth_addr = -1;
52 static int hf_eth_trailer = -1;
53
54 static gint ett_ieee8023 = -1;
55 static gint ett_ether2 = -1;
56
57 #define ETH_HEADER_SIZE 14
58
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 not 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 dissect_llc(). -- Gilbert
67 */
68 #define ETHERNET_II     0
69 #define ETHERNET_802_2  1
70 #define ETHERNET_802_3  2
71 #define ETHERNET_SNAP   3
72
73 void
74 capture_eth(const u_char *pd, int offset, packet_counts *ld)
75 {
76   guint16    etype, length;
77   int     ethhdr_type;  /* the type of ethernet frame */
78
79   if (!BYTES_ARE_IN_FRAME(offset, ETH_HEADER_SIZE)) {
80     ld->other++;
81     return;
82   }
83   
84   etype = pntohs(&pd[offset+12]);
85
86         /* either ethernet802.3 or ethernet802.2 */
87   if (etype <= IEEE_802_3_MAX_LEN) {
88     length = etype;
89
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;
98     }
99     else {
100       ethhdr_type = ETHERNET_802_2;
101     }
102
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, ld);
110       return;
111     }
112
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;
119     if (pi.len > length)
120       pi.len = length;
121     if (pi.captured_len > length)
122       pi.captured_len = length;
123   } else {
124     ethhdr_type = ETHERNET_II;
125   }
126   offset += ETH_HEADER_SIZE;
127
128   switch (ethhdr_type) {
129     case ETHERNET_802_3:
130       capture_ipx(pd, offset, ld);
131       break;
132     case ETHERNET_802_2:
133       capture_llc(pd, offset, ld);
134       break;
135     case ETHERNET_II:
136       capture_ethertype(etype, offset, pd, ld);
137       break;
138   }
139 }
140
141 void
142 dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
143 {
144   int                   orig_captured_len;
145   proto_item            *ti;
146   guint8                *dst, *src;
147   const guint8          *pd;
148
149   volatile guint16      etype;
150   volatile int          ethhdr_type;    /* the type of ethernet frame */
151   volatile int          eth_offset;
152   volatile guint16      length;
153
154   /* These are static because gcc says that they might get clobbered
155    * otherwise. */
156   static tvbuff_t       *next_tvb = NULL;
157   static tvbuff_t       *trailer_tvb;
158   static proto_tree     *fh_tree;
159
160   tvb_compat(tvb, &pd, (int*)&eth_offset);
161
162   /* Reset this static variable to NULL since I test it's value later */
163   trailer_tvb = NULL;
164
165   pinfo->current_proto = "Ethernet";
166   orig_captured_len = pinfo->captured_len;
167
168   if (check_col(pinfo->fd, COL_PROTOCOL))
169     col_add_str(pinfo->fd, COL_PROTOCOL, "Ethernet");
170
171   src = tvb_get_ptr(tvb, 6, 6);
172   dst = tvb_get_ptr(tvb, 0, 6);
173   SET_ADDRESS(&pi.dl_src,       AT_ETHER, 6, src);
174   SET_ADDRESS(&pi.src,          AT_ETHER, 6, src);
175   SET_ADDRESS(&pi.dl_dst,       AT_ETHER, 6, dst);
176   SET_ADDRESS(&pi.dst,          AT_ETHER, 6, dst);
177
178   etype = tvb_get_ntohs(tvb, 12);
179
180         /* either ethernet802.3 or ethernet802.2 */
181   if (etype <= IEEE_802_3_MAX_LEN) {
182     length = etype;
183
184     /* Is there an 802.2 layer? I can tell by looking at the first 2
185        bytes after the 802.3 header. If they are 0xffff, then what
186        follows the 802.3 header is an IPX payload, meaning no 802.2.
187        (IPX/SPX is they only thing that can be contained inside a
188        straight 802.3 packet). A non-0xffff value means that there's an
189        802.2 layer inside the 802.3 layer */
190     ethhdr_type = ETHERNET_802_2;
191     TRY {
192             if (tvb_get_ntohs(tvb, 14) == 0xffff) {
193               ethhdr_type = ETHERNET_802_3;
194             }
195     }
196     CATCH2(BoundsError, ReportedBoundsError) {
197             ; /* do nothing */
198
199     }
200     ENDTRY;
201
202     /* Oh, yuck.  Cisco ISL frames require special interpretation of the
203        destination address field; fortunately, they can be recognized by
204        checking the first 5 octets of the destination address, which are
205        01-00-0C-00-00 for ISL frames. */
206     if (        tvb_get_guint8(tvb, 0) == 0x01 &&
207                 tvb_get_guint8(tvb, 1) == 0x00 &&
208                 tvb_get_guint8(tvb, 2) == 0x0C &&
209                 tvb_get_guint8(tvb, 3) == 0x00 &&
210                 tvb_get_guint8(tvb, 4) == 0x00 ) {
211       dissect_isl(pd, eth_offset, pinfo->fd, tree);
212       return;
213     }
214
215     if (check_col(pinfo->fd, COL_INFO)) {
216       col_add_fstr(pinfo->fd, COL_INFO, "IEEE 802.3 %s",
217                 (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
218     }
219     if (tree) {
220
221         ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
222                 "IEEE 802.3 %s", (ethhdr_type == ETHERNET_802_3 ? "Raw " : ""));
223
224         fh_tree = proto_item_add_subtree(ti, ett_ieee8023);
225
226         proto_tree_add_item(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
227         proto_tree_add_item(fh_tree, hf_eth_src, tvb, 6, 6, src);
228
229 /* add items for eth.addr filter */
230         proto_tree_add_item_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
231         proto_tree_add_item_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
232
233         proto_tree_add_item(fh_tree, hf_eth_len, tvb, 12, 2, length);
234     }
235
236     /* Convert the LLC length from the 802.3 header to a total
237        frame length, by adding in the size of any data that preceded
238        the Ethernet header, and adding in the Ethernet header size,
239        and set the payload and captured-payload lengths to the minima
240        of the total length and the frame lengths. */
241     length += eth_offset + ETH_HEADER_SIZE;
242     if (pi.len > length)
243       pi.len = length;
244     if (pi.captured_len > length)
245       pi.captured_len = length;
246   } else {
247     ethhdr_type = ETHERNET_II;
248     if (check_col(pinfo->fd, COL_INFO))
249       col_add_str(pinfo->fd, COL_INFO, "Ethernet II");
250     if (tree) {
251
252         ti = proto_tree_add_protocol_format(tree, proto_eth, tvb, 0, ETH_HEADER_SIZE,
253                 "Ethernet II");
254
255         fh_tree = proto_item_add_subtree(ti, ett_ether2);
256
257         proto_tree_add_item(fh_tree, hf_eth_dst, tvb, 0, 6, dst);
258         proto_tree_add_item(fh_tree, hf_eth_src, tvb, 6, 6, src);
259 /* add items for eth.addr filter */
260         proto_tree_add_item_hidden(fh_tree, hf_eth_addr, tvb, 0, 6, dst);
261         proto_tree_add_item_hidden(fh_tree, hf_eth_addr, tvb, 6, 6, src);
262     }
263   }
264   eth_offset += ETH_HEADER_SIZE;
265
266   /* Give the next dissector only 'length' number of bytes */
267   if (etype <= IEEE_802_3_MAX_LEN) {
268           TRY {
269              next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, etype, etype);
270              trailer_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE + etype, -1, -1);
271           }
272           CATCH2(BoundsError, ReportedBoundsError) {
273              next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, etype);
274           }
275           ENDTRY;
276   }
277   else {
278      next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, -1);
279   }
280
281   switch (ethhdr_type) {
282     case ETHERNET_802_3:
283       dissect_ipx(pd, eth_offset, pinfo->fd, tree);
284       break;
285     case ETHERNET_802_2:
286       dissect_llc(next_tvb, &pi, tree);
287       break;
288     case ETHERNET_II:
289       ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type);
290       break;
291   }
292
293   /* If there's some bytes left over, mark them. */
294   if (trailer_tvb && tree) {
295           int             trailer_length;
296           const guint8    *ptr;
297
298           trailer_length = tvb_length(trailer_tvb);
299           if (trailer_length > 0) {
300                   ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length);
301                   proto_tree_add_item(fh_tree, hf_eth_trailer, tvb, ETH_HEADER_SIZE + etype,
302                           trailer_length, ptr);
303           }
304   }
305
306 }
307
308 void
309 proto_register_eth(void)
310 {
311         static hf_register_info hf[] = {
312
313                 { &hf_eth_dst,
314                 { "Destination",        "eth.dst", FT_ETHER, BASE_NONE, NULL, 0x0,
315                         "Destination Hardware Address" }},
316
317                 { &hf_eth_src,
318                 { "Source",             "eth.src", FT_ETHER, BASE_NONE, NULL, 0x0,
319                         "Source Hardware Address" }},
320
321                 { &hf_eth_len,
322                 { "Length",             "eth.len", FT_UINT16, BASE_DEC, NULL, 0x0,
323                         "" }},
324
325                 /* registered here but handled in ethertype.c */
326                 { &hf_eth_type,
327                 { "Type",               "eth.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
328                         "" }},
329                 { &hf_eth_addr,
330                 { "Source or Destination Address", "eth.addr", FT_ETHER, BASE_NONE, NULL, 0x0,
331                         "Source or Destination Hardware Address" }},
332
333                 { &hf_eth_trailer,
334                 { "Trailer", "eth.trailer", FT_BYTES, BASE_NONE, NULL, 0x0,
335                         "Ethernet Trailer or Checksum" }},
336
337         };
338         static gint *ett[] = {
339                 &ett_ieee8023,
340                 &ett_ether2,
341         };
342
343         proto_eth = proto_register_protocol ("Ethernet", "eth" );
344         proto_register_field_array(proto_eth, hf, array_length(hf));
345         proto_register_subtree_array(ett, array_length(ett));
346 }