2 * Routines for calling the right protocol for the ethertype.
4 * $Id: packet-ethertype.c,v 1.36 2003/06/11 09:17:00 guy Exp $
6 * Gilbert Ramirez <gram@alumni.rice.edu>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/packet.h>
33 #include "packet-ip.h"
34 #include "packet-ipv6.h"
35 #include "packet-ipx.h"
36 #include "packet-vlan.h"
37 #include "packet-vines.h"
41 static dissector_table_t ethertype_dissector_table;
43 static dissector_handle_t data_handle;
45 const value_string etype_vals[] = {
46 {ETHERTYPE_IP, "IP" },
47 {ETHERTYPE_IPv6, "IPv6" },
48 {ETHERTYPE_X25L3, "X.25 Layer 3" },
49 {ETHERTYPE_ARP, "ARP" },
50 {ETHERTYPE_REVARP, "RARP" },
51 {ETHERTYPE_DEC_LB, "DEC LanBridge" },
52 {ETHERTYPE_ATALK, "Appletalk" },
53 {ETHERTYPE_SNA, "SNA-over-Ethernet" },
54 {ETHERTYPE_AARP, "AARP" },
55 {ETHERTYPE_IPX, "Netware IPX/SPX" },
56 {ETHERTYPE_VINES_IP, "Vines IP" },
57 {ETHERTYPE_VINES_ECHO, "Vines Echo" },
58 {ETHERTYPE_TRAIN, "Netmon Train" },
59 {ETHERTYPE_LOOP, "Loopback" }, /* Ethernet Loopback */
60 {ETHERTYPE_WCP, "Wellfleet Compression Protocol" },
61 {ETHERTYPE_PPPOED, "PPPoE Discovery" },
62 {ETHERTYPE_PPPOES, "PPPoE Session" },
63 {ETHERTYPE_INTEL_ANS, "Intel ANS probe" },
64 {ETHERTYPE_MS_NLB_HEARTBEAT, "MS NLB heartbeat" },
65 {ETHERTYPE_VLAN, "802.1Q Virtual LAN" },
66 {ETHERTYPE_EAPOL, "802.1X Authentication" },
67 {ETHERTYPE_MPLS, "MPLS label switched packet" },
68 {ETHERTYPE_MPLS_MULTI, "MPLS multicast label switched packet" },
69 {ETHERTYPE_3C_NBP_DGRAM, "3Com NBP Datagram" },
70 {ETHERTYPE_DEC, "DEC proto" },
71 {ETHERTYPE_DNA_DL, "DEC DNA Dump/Load" },
72 {ETHERTYPE_DNA_RC, "DEC DNA Remote Console" },
73 {ETHERTYPE_DNA_RT, "DEC DNA Routing" },
74 {ETHERTYPE_LAT, "DEC LAT" },
75 {ETHERTYPE_DEC_DIAG, "DEC Diagnostics" },
76 {ETHERTYPE_DEC_CUST, "DEC Customer use" },
77 {ETHERTYPE_DEC_SCA, "DEC LAVC/SCA" },
78 {ETHERTYPE_ETHBRIDGE, "Transparent Ethernet bridging" },
79 {ETHERTYPE_CGMP, "Cisco Group Management Protocol" },
80 {ETHERTYPE_SLOW_PROTOCOLS, "Slow Protocols" },
81 {ETHERTYPE_RTNET, "RTNET Protocol" },
84 * NDISWAN on Windows translates Ethernet frames from higher-level
85 * protocols into PPP frames to hand to the PPP driver, and translates
86 * PPP frames from the PPP driver to hand to the higher-level protocols.
88 * Apparently the PPP driver, on at least some versions of Windows,
89 * passes frames for internal-to-PPP protocols up through NDISWAN;
90 * the protocol type field appears to be passed through unchanged
91 * (unlike what's done with, for example, the protocol type field
92 * for IP, which is mapped from its PPP value to its Ethernet value).
94 * This means that we may see, on Ethernet captures, frames for
95 * protocols internal to PPP, so we list as "Ethernet" protocol
96 * types the PPP protocol types we've seen.
98 {PPP_IPCP, "PPP IP Control Protocol" },
99 {PPP_LCP, "PPP Link Control Protocol" },
100 {PPP_PAP, "PPP Password Authentication Protocol" },
101 {PPP_CCP, "PPP Compression Control Protocol" },
104 static void add_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
105 tvbuff_t *next_tvb, int offset_after_etype, guint length_before);
108 capture_ethertype(guint16 etype, const guchar *pd, int offset, int len,
116 capture_ip(pd, offset, len, ld);
119 capture_ipv6(pd, offset, len, ld);
125 capture_vlan(pd, offset, len, ld);
127 case ETHERTYPE_VINES_IP:
128 case ETHERTYPE_VINES_ECHO:
138 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
139 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
140 int etype_id, int trailer_id)
145 volatile gboolean dissector_found;
147 /* Add to proto_tree */
149 proto_tree_add_uint(fh_tree, etype_id, tvb,
150 offset_after_etype - 2, 2, etype);
153 /* Tvbuff for the payload after the Ethernet type. */
154 next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
156 pinfo->ethertype = etype;
158 /* Remember how much data there is in it. */
159 length_before = tvb_reported_length(next_tvb);
161 /* Look for sub-dissector, and call it if found.
162 Catch BoundsError and ReportedBoundsError, so that if the
163 reported length of "next_tvb" was reduced by some dissector
164 before an exception was thrown, we can still put in an item
167 dissector_found = dissector_try_port(ethertype_dissector_table,
168 etype, next_tvb, pinfo, tree);
170 CATCH2(BoundsError, ReportedBoundsError) {
171 /* Well, somebody threw an exception; that means that a
172 dissector was found, so we don't need to dissect
173 the payload as data or update the protocol or info
175 dissector_found = TRUE;
177 /* Add the trailer, if appropriate. */
178 add_trailer(fh_tree, trailer_id, tvb, next_tvb,
179 offset_after_etype, length_before);
181 /* Rrethrow the exception, so the "Short Frame" or "Mangled
182 Frame" indication can be put into the tree. */
185 /* XXX - RETHROW shouldn't return. */
186 g_assert_not_reached();
190 if (!dissector_found) {
191 /* No sub-dissector found.
192 Label rest of packet as "Data" */
193 call_dissector(data_handle,next_tvb, pinfo, tree);
199 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
200 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "LOOP");
205 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
206 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x",
211 if (check_col(pinfo->cinfo, COL_INFO)) {
212 description = match_strval(etype, etype_vals);
214 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
220 add_trailer(fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
225 add_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
226 tvbuff_t *next_tvb, int offset_after_etype, guint length_before)
229 tvbuff_t *volatile trailer_tvb;
232 return; /* we're not building a protocol tree */
234 if (trailer_id == -1)
235 return; /* our caller doesn't care about trailers */
237 /* OK, how much is there in that tvbuff now? */
238 length = tvb_reported_length(next_tvb);
240 /* If there's less than there was before, what's left is
242 if (length < length_before) {
244 * Create a tvbuff for the padding.
247 trailer_tvb = tvb_new_subset(tvb,
248 offset_after_etype + length, -1, -1);
250 CATCH2(BoundsError, ReportedBoundsError) {
251 /* The packet doesn't have "length" bytes worth of
252 captured data left in it. No trailer to display. */
257 trailer_tvb = NULL; /* no trailer */
259 /* If there's some bytes left over, and we were given an item ID
260 for a trailer, mark those bytes as a trailer. */
262 guint trailer_length;
264 trailer_length = tvb_length(trailer_tvb);
265 if (trailer_length != 0) {
266 proto_tree_add_item(fh_tree, trailer_id, trailer_tvb, 0,
267 trailer_length, FALSE);
274 proto_register_ethertype(void)
276 /* subdissector code */
277 ethertype_dissector_table = register_dissector_table("ethertype",
278 "Ethertype", FT_UINT16, BASE_HEX);
282 proto_reg_handoff_ethertype(void){
283 data_handle = find_dissector("data");