1 /* packet-ethertype.c
2 * Routines for processing Ethernet payloads and payloads like Ethernet
3 * payloads (i.e., payloads when there could be an Ethernet trailer and
4 * possibly an FCS).
5 *
6 * Gilbert Ramirez <gram@alumni.rice.edu>
7 *
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15 #include "config.h"
16
17 #include <epan/packet.h>
18 #include <epan/exceptions.h>
19 #include <epan/etypes.h>
20 #include <epan/ppptypes.h>
21 #include <epan/show_exception.h>
22 #include <epan/decode_as.h>
23 #include <epan/capture_dissectors.h>
24 #include <epan/proto_data.h>
25 #include "packet-eth.h"
26
27 void proto_register_ethertype(void);
28
29 static dissector_table_t ethertype_dissector_table;
30
31 static int proto_ethertype = -1;
32
33 const value_string etype_vals[] = {
34 { ETHERTYPE_IP, "IPv4" },
35 { ETHERTYPE_IPv6, "IPv6" },
36 { ETHERTYPE_VLAN, "802.1Q Virtual LAN" },
37 { ETHERTYPE_SLPP, "Simple Loop Protection Protocol" },
38 { ETHERTYPE_VLACP, "Virtual LACP" }, /* Nortel/Avaya/Extremenetworks */
39 { ETHERTYPE_OLDSLPP, "Simple Loop Protection Protocol (old)" },
40 { ETHERTYPE_ARP, "ARP" },
41 { ETHERTYPE_WLCCP, "Cisco Wireless Lan Context Control Protocol" },
42 { ETHERTYPE_MINT, "Motorola Media Independent Network Transport" },
43 { ETHERTYPE_CENTRINO_PROMISC, "IEEE 802.11 (Centrino promiscuous)" },
44 { ETHERTYPE_XNS_IDP, "XNS Internet Datagram Protocol" },
45 { ETHERTYPE_X25L3, "X.25 Layer 3" },
46 { ETHERTYPE_WOL, "Wake on LAN" },
47 { ETHERTYPE_WMX_M2M, "WiMax Mac-to-Mac" },
48 { ETHERTYPE_EPL_V1, "EPL_V1" },
49 { ETHERTYPE_REVARP, "RARP" },
50 { ETHERTYPE_DEC_LB, "DEC LanBridge" },
51 { ETHERTYPE_ATALK, "AppleTalk LLAP bridging" },
52 { ETHERTYPE_SNA, "SNA-over-Ethernet" },
53 { ETHERTYPE_DLR, "EtherNet/IP Device Level Ring" },
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 /* Ethernet Loopback */
60 { ETHERTYPE_LOOP, "Loopback" },
61 { ETHERTYPE_FOUNDRY, "Foundry proprietary" },
62 { ETHERTYPE_WCP, "Wellfleet Compression Protocol" },
63 { ETHERTYPE_STP, "Spanning Tree Protocol" },
64 /* for ISMP, see RFC 2641, RFC 2642, RFC 2643 */
65 { ETHERTYPE_ISMP, "Cabletron Interswitch Message Protocol" },
66 { ETHERTYPE_ISMP_TBFLOOD, "Cabletron SFVLAN 1.8 Tag-Based Flood" },
67 /* In www.iana.org/assignments/ethernet-numbers, 8203-8205 description is
68 * Quantum Software. Now the company is called QNX Software Systems. */
69 { ETHERTYPE_QNX_QNET6, "QNX 6 QNET protocol" },
70 { ETHERTYPE_PPPOED, "PPPoE Discovery" },
71 { ETHERTYPE_PPPOES, "PPPoE Session" },
72 { ETHERTYPE_LINK_CTL, "HomePNA, wlan link local tunnel" },
73 { ETHERTYPE_INTEL_ANS, "Intel ANS probe" },
74 { ETHERTYPE_MS_NLB_HEARTBEAT, "MS NLB heartbeat" },
75 { ETHERTYPE_JUMBO_LLC, "Jumbo LLC" },
76 { ETHERTYPE_BRCM_TYPE, "Broadcom tag" },
77 { ETHERTYPE_HOMEPLUG, "Homeplug" },
78 { ETHERTYPE_HOMEPLUG_AV, "Homeplug AV" },
79 { ETHERTYPE_MRP, "MRP" },
80 { ETHERTYPE_IEEE_802_1AD, "802.1ad Provider Bridge (Q-in-Q)" },
81 { ETHERTYPE_MACSEC, "802.1AE (MACsec)" },
82 { ETHERTYPE_IEEE_1905, "1905.1a Convergent Digital Home Network for Heterogenous Technologies" },
83 { ETHERTYPE_IEEE_802_1AH, "802.1ah Provider Backbone Bridge (mac-in-mac)" },
84 { ETHERTYPE_IEEE_802_1BR, "802.1br Bridge Port Extension E-Tag" },
85 { ETHERTYPE_EAPOL, "802.1X Authentication" },
86 { ETHERTYPE_RSN_PREAUTH, "802.11i Pre-Authentication" },
87 { ETHERTYPE_MPLS, "MPLS label switched packet" },
88 { ETHERTYPE_MPLS_MULTI, "MPLS multicast label switched packet" },
89 { ETHERTYPE_3C_NBP_DGRAM, "3Com NBP Datagram" },
90 { ETHERTYPE_DEC, "DEC proto" },
91 { ETHERTYPE_DNA_DL, "DEC DNA Dump/Load" },
92 { ETHERTYPE_DNA_RC, "DEC DNA Remote Console" },
93 { ETHERTYPE_DNA_RT, "DEC DNA Routing" },
94 { ETHERTYPE_LAT, "DEC LAT" },
95 { ETHERTYPE_DEC_DIAG, "DEC Diagnostics" },
96 { ETHERTYPE_DEC_CUST, "DEC Customer use" },
97 { ETHERTYPE_DEC_SCA, "DEC LAVC/SCA" },
98 { ETHERTYPE_DEC_LAST, "DEC LAST" },
99 { ETHERTYPE_ETHBRIDGE, "Transparent Ethernet bridging" },
100 { ETHERTYPE_CGMP, "Cisco Group Management Protocol" },
101 { ETHERTYPE_GIGAMON, "Gigamon Header" },
102 { ETHERTYPE_MSRP, "802.1Qat Multiple Stream Reservation Protocol" },
103 { ETHERTYPE_MMRP, "802.1ak Multiple Mac Registration Protocol" },
104 { ETHERTYPE_NSH, "Network Service Header" },
105 { ETHERTYPE_PA_HBBACKUP, "PA HB Backup" },
106 { ETHERTYPE_AVTP, "IEEE 1722 Audio Video Transport Protocol" },
107 { ETHERTYPE_ROHC, "Robust Header Compression(RoHC)" },
108 { ETHERTYPE_TRILL, "Transparent Interconnection of Lots of Links" },
109 { ETHERTYPE_L2ISIS, "Intermediate System to Intermediate System" },
110 { ETHERTYPE_MAC_CONTROL, "MAC Control" },
111 { ETHERTYPE_SLOW_PROTOCOLS, "Slow Protocols" },
112 { ETHERTYPE_RTMAC, "Real-Time Media Access Control" },
113 { ETHERTYPE_RTCFG, "Real-Time Configuration Protocol" },
114 { ETHERTYPE_CDMA2000_A10_UBS, "CDMA2000 A10 Unstructured byte stream" },
115 { ETHERTYPE_ATMOE, "ATM over Ethernet" },
116 { ETHERTYPE_PROFINET, "PROFINET" },
117 { ETHERTYPE_REALTEK, "Realtek Layer 2 Protocols" },
118 { ETHERTYPE_AOE, "ATA over Ethernet" },
119 { ETHERTYPE_ECATF, "EtherCAT frame" },
120 { ETHERTYPE_TELKONET, "Telkonet powerline" },
121 { ETHERTYPE_EPL_V2, "ETHERNET Powerlink v2" },
122 { ETHERTYPE_XIMETA, "XiMeta Technology" },
123 { ETHERTYPE_CSM_ENCAPS, "CSM_ENCAPS Protocol" },
124 { ETHERTYPE_EXPERIMENTAL_ETH1, "Local Experimental Ethertype 1" },
125 { ETHERTYPE_EXPERIMENTAL_ETH2, "Local Experimental Ethertype 2" },
126 { ETHERTYPE_IEEE802_OUI_EXTENDED, "IEEE 802a OUI Extended Ethertype" },
127 { ETHERTYPE_IEC61850_GOOSE, "IEC 61850/GOOSE" },
128 { ETHERTYPE_IEC61850_GSE, "IEC 61850/GSE management services" },
129 { ETHERTYPE_IEC61850_SV, "IEC 61850/SV (Sampled Value Transmission" },
130 { ETHERTYPE_TIPC, "Transparent Inter Process Communication" },
131 { ETHERTYPE_LLDP, "802.1 Link Layer Discovery Protocol (LLDP)" },
132 { ETHERTYPE_3GPP2, "CDMA2000 A10 3GPP2 Packet" },
133 { ETHERTYPE_TTE_PCF, "TTEthernet Protocol Control Frame" },
134 { ETHERTYPE_CESOETH, "Circuit Emulation Services over Ethernet (MEF8)" },
135 { ETHERTYPE_LLTD, "Link Layer Topology Discovery (LLTD)" },
136 { ETHERTYPE_WSMP, "(WAVE) Short Message Protocol (WSM)" },
137 { ETHERTYPE_VMLAB, "VMware Lab Manager" },
138 { ETHERTYPE_COBRANET, "Cirrus Cobranet Packet" },
139 { ETHERTYPE_NSRP, "Juniper Netscreen Redundant Protocol" },
140 { ETHERTYPE_EERO, "EERO Broadcast Packet" },
141 /*
142 * NDISWAN on Windows translates Ethernet frames from higher-level
143 * protocols into PPP frames to hand to the PPP driver, and translates
144 * PPP frames from the PPP driver to hand to the higher-level protocols.
145 *
146 * Apparently the PPP driver, on at least some versions of Windows,
147 * passes frames for internal-to-PPP protocols up through NDISWAN;
148 * the protocol type field appears to be passed through unchanged
149 * (unlike what's done with, for example, the protocol type field
150 * for IP, which is mapped from its PPP value to its Ethernet value).
151 *
152 * This means that we may see, on Ethernet captures, frames for
153 * protocols internal to PPP, so we list as "Ethernet" protocol
154 * types the PPP protocol types we've seen.
155 */
156 { PPP_IPCP, "PPP IP Control Protocol" },
157 { PPP_LCP, "PPP Link Control Protocol" },
158 { PPP_PAP, "PPP Password Authentication Protocol" },
159 { PPP_CCP, "PPP Compression Control Protocol" },
160 { ETHERTYPE_LLT, "Veritas Low Latency Transport (not officially registered)" },
161 { ETHERTYPE_CFM, "IEEE 802.1ag Connectivity Fault Management (CFM) protocol" },
162 { ETHERTYPE_DCE, "Data Center Ethernet (DCE) protocol(Cisco)" },
163 { ETHERTYPE_FCOE, "Fibre Channel over Ethernet" },
164 { ETHERTYPE_IEEE80211_DATA_ENCAP, "IEEE 802.11 data encapsulation" },
165 { ETHERTYPE_LINX, "LINX IPC Protocol" },
166 { ETHERTYPE_FIP, "FCoE Initialization Protocol" },
167 { ETHERTYPE_MIH, "Media Independent Handover Protocol" },
168 { ETHERTYPE_ELMI, "Ethernet Local Management Interface (MEF16)" },
169 { ETHERTYPE_PTP, "PTPv2 over Ethernet (IEEE1588)" },
170 { ETHERTYPE_NCSI, "Network Controller Sideband Interface" },
171 { ETHERTYPE_PRP, "Parallel Redundancy Protocol (PRP) and HSR Supervision (IEC62439 Part 3)" },
172 { ETHERTYPE_FLIP, "Flow Layer Internal Protocol" },
173 { ETHERTYPE_ROCE, "RDMA over Converged Ethernet" },
174 { ETHERTYPE_TDMOE, "Digium TDM over Ethernet Protocol" },
175 { ETHERTYPE_WAI, "WAI Authentication Protocol" },
176 { ETHERTYPE_VNTAG, "VN-Tag" },
177 { ETHERTYPE_SEL_L2, "Schweitzer Engineering Labs Layer 2 Protocol" },
178 { ETHERTYPE_HSR, "High-availability Seamless Redundancy (IEC62439 Part 3)" },
179 { ETHERTYPE_BPQ, "AX.25" },
180 { ETHERTYPE_CMD, "CiscoMetaData" },
181 { ETHERTYPE_GEONETWORKING, "GeoNetworking" },
182 { ETHERTYPE_XIP, "eXpressive Internet Protocol" },
183 { ETHERTYPE_NWP, "Neighborhood Watch Protocol" },
184 { ETHERTYPE_BLUECOM, "bluecom Protocol" },
185 { ETHERTYPE_QINQ_OLD, "QinQ: old non-standard 802.1ad" },
186 { ETHERTYPE_TECMP, "Technically Enhanced Capture Module Protocol (TECMP)" },
187 { ETHERTYPE_6LOWPAN, "6LoWPAN" },
188 { ETHERTYPE_AVSP, "Arista Timestamp" },
189 { ETHERTYPE_ECPRI, "eCPRI" },
190 { ETHERTYPE_CABLELABS, "CableLabs Layer-3 Protocol" },
191 { ETHERTYPE_EXEH, "EXos internal Extra Header" },
192 { ETHERTYPE_ACIGLEAN, "Cisco ACI ARP gleaning" },
193 { ETHERTYPE_IEEE_802_1CB, "802.1CB Frame Replication and Elimination for Reliability" },
194 { 0, NULL }
195 };
196
eth_prompt(packet_info * pinfo,gchar * result)197 static void eth_prompt(packet_info *pinfo, gchar* result)
198 {
199 g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Ethertype 0x%04x as",
200 GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num)));
201 }
202
eth_value(packet_info * pinfo)203 static gpointer eth_value(packet_info *pinfo)
204 {
205 return p_get_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num);
206 }
207
208 static void add_dix_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
209 int trailer_id, tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
210 guint length_before, gint fcs_len);
211
212 /*
213 void
214 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
215 packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree,
216 int etype_id, int trailer_id, int fcs_len)
217 */
218 static int
dissect_ethertype(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)219 dissect_ethertype(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
220 {
221 const char *description;
222 tvbuff_t *volatile next_tvb;
223 guint length_before;
224 gint captured_length, reported_length;
225 volatile int dissector_found = 0;
226 const char *volatile saved_proto;
227 ethertype_data_t *ethertype_data;
228
229 /* Reject the packet if data is NULL */
230 if (data == NULL)
231 return 0;
232 ethertype_data = (ethertype_data_t*)data;
233
234 /* Get the captured length and reported length of the data
235 after the Ethernet type. */
236 captured_length = tvb_captured_length_remaining(tvb, ethertype_data->payload_offset);
237 reported_length = tvb_reported_length_remaining(tvb,
238 ethertype_data->payload_offset);
239
240 /* With Cisco ACI gleaning, the rest of the packet is dissected for informational purposes only */
241 if (ethertype_data->etype == ETHERTYPE_ACIGLEAN) {
242
243 guint gleantype, payload_etype;
244
245 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype);
246 col_set_writable(pinfo->cinfo, COL_PROTOCOL, FALSE);
247
248 description = try_val_to_str(ethertype_data->etype, etype_vals);
249 col_add_str(pinfo->cinfo, COL_INFO, description);
250 col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
251 if (reported_length >= 1) {
252 gleantype = (tvb_get_guint8(tvb, ethertype_data->payload_offset) & 0xF0) >> 4;
253 switch (gleantype) {
254 case 4: /* IPv4 */
255 payload_etype = 0x0800;
256 break;
257 case 6: /* IPv6 */
258 payload_etype = 0x86BB;
259 break;
260 default: /* ARP */
261 payload_etype = 0x0806;
262 }
263 ethertype_data->etype = payload_etype;
264 // FIXME: Add glean to protocol-stack in frame-header
265 }
266 }
267
268 /* Remember how much data there is after the Ethernet type,
269 including any trailer and FCS. */
270 length_before = reported_length;
271
272 /* Construct a tvbuff for the payload after the Ethernet type.
273 If the FCS length is positive, remove the FCS.
274 (If it's zero, there's no FCS; if it's negative,
275 we don't know whether there's an FCS, so we'll
276 guess based on the length of the trailer.) */
277 if (ethertype_data->fcs_len > 0) {
278 if (captured_length >= 0 && reported_length >= 0) {
279 if (reported_length >= ethertype_data->fcs_len)
280 reported_length -= ethertype_data->fcs_len;
281 if (captured_length > reported_length)
282 captured_length = reported_length;
283 }
284 }
285 next_tvb = tvb_new_subset_length_caplen(tvb, ethertype_data->payload_offset, captured_length,
286 reported_length);
287
288 p_add_proto_data(pinfo->pool, pinfo, proto_ethertype, pinfo->curr_layer_num, GUINT_TO_POINTER((guint)ethertype_data->etype));
289
290 /* Look for sub-dissector, and call it if found.
291 Catch exceptions, so that if the reported length of "next_tvb"
292 was reduced by some dissector before an exception was thrown,
293 we can still put in an item for the trailer. */
294 saved_proto = pinfo->current_proto;
295 TRY {
296 dissector_found = dissector_try_uint(ethertype_dissector_table,
297 ethertype_data->etype, next_tvb, pinfo, tree);
298 }
299 CATCH_NONFATAL_ERRORS {
300 /* Somebody threw an exception that means that there
301 was a problem dissecting the payload; that means
302 that a dissector was found, so we don't need to
303 dissect the payload as data or update the protocol
304 or info columns.
305
306 Just show the exception and then drive on to show
307 the trailer, after noting that a dissector was found
308 and restoring the protocol value that was in effect
309 before we called the subdissector. */
310 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
311
312 dissector_found = 1;
313 pinfo->current_proto = saved_proto;
314 }
315 ENDTRY;
316
317 if (!dissector_found) {
318 /* No sub-dissector found.
319 Label rest of packet as "Data" */
320 call_data_dissector(next_tvb, pinfo, tree);
321
322 /* Label protocol */
323 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ethertype_data->etype);
324
325 description = try_val_to_str(ethertype_data->etype, etype_vals);
326 if (description) {
327 col_add_str(pinfo->cinfo, COL_INFO, description);
328 }
329 }
330
331 add_dix_trailer(pinfo, tree, ethertype_data->fh_tree, ethertype_data->trailer_id, tvb, next_tvb, ethertype_data->payload_offset,
332 length_before, ethertype_data->fcs_len);
333
334 return tvb_captured_length(tvb);
335 }
336
337 static void
add_dix_trailer(packet_info * pinfo,proto_tree * tree,proto_tree * fh_tree,int trailer_id,tvbuff_t * tvb,tvbuff_t * next_tvb,int offset_after_etype,guint length_before,gint fcs_len)338 add_dix_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int trailer_id,
339 tvbuff_t *tvb, tvbuff_t *next_tvb, int offset_after_etype,
340 guint length_before, gint fcs_len)
341 {
342 guint length;
343 tvbuff_t *trailer_tvb;
344
345 /* OK, how much is there in that tvbuff now? */
346 length = tvb_reported_length(next_tvb);
347
348 /* If there's less than there was before, what's left is
349 a trailer. */
350 if (length < length_before) {
351 /*
352 * Is any of the padding present in the tvbuff?
353 */
354 if (tvb_offset_exists(tvb, offset_after_etype + length)) {
355 /*
356 * Yes - create a tvbuff for the padding.
357 */
358 trailer_tvb = tvb_new_subset_remaining(tvb,
359 offset_after_etype + length);
360 } else {
361 /*
362 * No - don't bother showing the trailer.
363 * XXX - show a Short Frame indication?
364 */
365 trailer_tvb = NULL;
366 }
367 } else
368 trailer_tvb = NULL; /* no trailer */
369
370 add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
371 }
372
373 void
proto_register_ethertype(void)374 proto_register_ethertype(void)
375 {
376 /* Decode As handling */
377 static build_valid_func eth_da_build_value[1] = {eth_value};
378 static decode_as_value_t eth_da_values = {eth_prompt, 1, eth_da_build_value};
379 static decode_as_t ethertype_da = {"ethertype", "ethertype", 1, 0, ð_da_values, NULL, NULL,
380 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
381
382
383 proto_ethertype = proto_register_protocol("Ethertype", "Ethertype", "ethertype");
384 /* This isn't a real protocol, so you can't disable its dissection. */
385 proto_set_cant_toggle(proto_ethertype);
386
387 register_dissector("ethertype", dissect_ethertype, proto_ethertype);
388
389 /* subdissector code */
390 ethertype_dissector_table = register_dissector_table("ethertype",
391 "Ethertype", proto_ethertype, FT_UINT16, BASE_HEX);
392 register_capture_dissector_table("ethertype", "Ethertype");
393
394 register_decode_as(ðertype_da);
395 }
396
397 /*
398 * Editor modelines - https://www.wireshark.org/tools/modelines.html
399 *
400 * Local variables:
401 * c-basic-offset: 8
402 * tab-width: 8
403 * indent-tabs-mode: t
404 * End:
405 *
406 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
407 * :indentSize=8:tabSize=8:noTabs=false:
408 */
409