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