2 * Routines for calling the right protocol for the ethertype.
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-eth.h"
34 #include "packet-frame.h"
35 #include "packet-ip.h"
36 #include "packet-ipv6.h"
37 #include "packet-ipx.h"
38 #include "packet-vlan.h"
39 #include "packet-vines.h"
43 static dissector_table_t ethertype_dissector_table;
45 static dissector_handle_t data_handle;
47 const value_string etype_vals[] = {
48 {ETHERTYPE_IP, "IP" },
49 {ETHERTYPE_IPv6, "IPv6" },
50 {ETHERTYPE_X25L3, "X.25 Layer 3" },
51 {ETHERTYPE_ARP, "ARP" },
52 {ETHERTYPE_REVARP, "RARP" },
53 {ETHERTYPE_DEC_LB, "DEC LanBridge" },
54 {ETHERTYPE_ATALK, "Appletalk" },
55 {ETHERTYPE_SNA, "SNA-over-Ethernet" },
56 {ETHERTYPE_AARP, "AARP" },
57 {ETHERTYPE_IPX, "Netware IPX/SPX" },
58 {ETHERTYPE_VINES_IP, "Vines IP" },
59 {ETHERTYPE_VINES_ECHO, "Vines Echo" },
60 {ETHERTYPE_TRAIN, "Netmon Train" },
61 {ETHERTYPE_LOOP, "Loopback" }, /* Ethernet Loopback */
62 {ETHERTYPE_WCP, "Wellfleet Compression Protocol" },
63 {ETHERTYPE_ISMP, "Cabletron Interswitch Message Protocol" },
64 {ETHERTYPE_ISMP_TBFLOOD, "Cabletron SFVLAN 1.8 Tag-Based Flood" },
65 /* for ISMP, see RFC 2641, RFC 2642, RFC 2643 */
66 {ETHERTYPE_PPPOED, "PPPoE Discovery" },
67 {ETHERTYPE_PPPOES, "PPPoE Session" },
68 {ETHERTYPE_INTEL_ANS, "Intel ANS probe" },
69 {ETHERTYPE_MS_NLB_HEARTBEAT, "MS NLB heartbeat" },
70 {ETHERTYPE_VLAN, "802.1Q Virtual LAN" },
71 {ETHERTYPE_EAPOL, "802.1X Authentication" },
72 {ETHERTYPE_RSN_PREAUTH, "802.11i Pre-Authentication" },
73 {ETHERTYPE_MPLS, "MPLS label switched packet" },
74 {ETHERTYPE_MPLS_MULTI, "MPLS multicast label switched packet" },
75 {ETHERTYPE_3C_NBP_DGRAM, "3Com NBP Datagram" },
76 {ETHERTYPE_DEC, "DEC proto" },
77 {ETHERTYPE_DNA_DL, "DEC DNA Dump/Load" },
78 {ETHERTYPE_DNA_RC, "DEC DNA Remote Console" },
79 {ETHERTYPE_DNA_RT, "DEC DNA Routing" },
80 {ETHERTYPE_LAT, "DEC LAT" },
81 {ETHERTYPE_DEC_DIAG, "DEC Diagnostics" },
82 {ETHERTYPE_DEC_CUST, "DEC Customer use" },
83 {ETHERTYPE_DEC_SCA, "DEC LAVC/SCA" },
84 {ETHERTYPE_ETHBRIDGE, "Transparent Ethernet bridging" },
85 {ETHERTYPE_CGMP, "Cisco Group Management Protocol" },
86 {ETHERTYPE_SLOW_PROTOCOLS, "Slow Protocols" },
87 {ETHERTYPE_RTNET, "RTNET Protocol" },
88 {ETHERTYPE_RTCFG, "RTCFG Protocol" },
89 {ETHERTYPE_PROFINET, "PROFInet" },
92 * NDISWAN on Windows translates Ethernet frames from higher-level
93 * protocols into PPP frames to hand to the PPP driver, and translates
94 * PPP frames from the PPP driver to hand to the higher-level protocols.
96 * Apparently the PPP driver, on at least some versions of Windows,
97 * passes frames for internal-to-PPP protocols up through NDISWAN;
98 * the protocol type field appears to be passed through unchanged
99 * (unlike what's done with, for example, the protocol type field
100 * for IP, which is mapped from its PPP value to its Ethernet value).
102 * This means that we may see, on Ethernet captures, frames for
103 * protocols internal to PPP, so we list as "Ethernet" protocol
104 * types the PPP protocol types we've seen.
106 {PPP_IPCP, "PPP IP Control Protocol" },
107 {PPP_LCP, "PPP Link Control Protocol" },
108 {PPP_PAP, "PPP Password Authentication Protocol" },
109 {PPP_CCP, "PPP Compression Control Protocol" },
112 static void add_dix_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
113 tvbuff_t *next_tvb, int offset_after_etype, guint length_before,
117 capture_ethertype(guint16 etype, const guchar *pd, int offset, int len,
125 capture_ip(pd, offset, len, ld);
128 capture_ipv6(pd, offset, len, ld);
134 capture_vlan(pd, offset, len, ld);
136 case ETHERTYPE_VINES_IP:
137 case ETHERTYPE_VINES_ECHO:
147 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
148 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
149 int etype_id, int trailer_id, int fcs_len)
154 volatile gboolean dissector_found;
155 const char *saved_proto;
157 /* Add the Ethernet type to the protocol tree */
159 proto_tree_add_uint(fh_tree, etype_id, tvb,
160 offset_after_etype - 2, 2, etype);
163 /* Tvbuff for the payload after the Ethernet type. */
164 next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
166 pinfo->ethertype = etype;
168 /* Remember how much data there is in it. */
169 length_before = tvb_reported_length(next_tvb);
171 /* Look for sub-dissector, and call it if found.
172 Catch exceptions, so that if the reported length of "next_tvb"
173 was reduced by some dissector before an exception was thrown,
174 we can still put in an item for the trailer. */
175 saved_proto = pinfo->current_proto;
177 dissector_found = dissector_try_port(ethertype_dissector_table,
178 etype, next_tvb, pinfo, tree);
181 /* Somebody threw BoundsError, which means that:
183 1) a dissector was found, so we don't need to
184 dissect the payload as data or update the
185 protocol or info columns;
187 2) dissecting the payload found that the packet was
188 cut off by a snapshot length before the end of
189 the payload. The trailer comes after the payload,
190 so *all* of the trailer is cut off, and we'll
191 just get another BoundsError if we add the trailer.
193 Therefore, we just rethrow the exception so it gets
194 reported; we don't dissect the trailer or do anything
199 /* Somebody threw an exception other than BoundsError, which
200 means that a dissector was found, so we don't need to
201 dissect the payload as data or update the protocol or info
202 columns. We just show the exception and then drive on
203 to show the trailer, after noting that a dissector was
204 found and restoring the protocol value that was in effect
205 before we called the subdissector. */
206 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE);
207 dissector_found = TRUE;
208 pinfo->current_proto = saved_proto;
212 if (!dissector_found) {
213 /* No sub-dissector found.
214 Label rest of packet as "Data" */
215 call_dissector(data_handle,next_tvb, pinfo, tree);
221 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
222 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "LOOP");
227 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
228 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x",
233 if (check_col(pinfo->cinfo, COL_INFO)) {
234 description = match_strval(etype, etype_vals);
236 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
242 add_dix_trailer(fh_tree, trailer_id, tvb, next_tvb, offset_after_etype,
243 length_before, fcs_len);
247 add_dix_trailer(proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb,
248 tvbuff_t *next_tvb, int offset_after_etype, guint length_before,
252 tvbuff_t *volatile trailer_tvb;
255 return; /* we're not building a protocol tree */
257 if (trailer_id == -1)
258 return; /* our caller doesn't care about trailers */
260 /* OK, how much is there in that tvbuff now? */
261 length = tvb_reported_length(next_tvb);
263 /* If there's less than there was before, what's left is
265 if (length < length_before) {
267 * Is any of the padding present in the tvbuff?
269 if (tvb_offset_exists(tvb, offset_after_etype + length)) {
271 * Yes - create a tvbuff for the padding.
273 trailer_tvb = tvb_new_subset(tvb,
274 offset_after_etype + length, -1, -1);
277 * No - don't bother showing the trailer.
278 * XXX - show a Short Frame indication?
283 trailer_tvb = NULL; /* no trailer */
285 add_ethernet_trailer(fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
289 proto_register_ethertype(void)
291 /* subdissector code */
292 ethertype_dissector_table = register_dissector_table("ethertype",
293 "Ethertype", FT_UINT16, BASE_HEX);
297 proto_reg_handoff_ethertype(void)
299 data_handle = find_dissector("data");